选择项目时无法清除列表框
Can't clear ListBox while item is selected
你好,今天我在用 WPF 做实验,我发现当一个 ListBox 有一个选中的项目时,它不允许修改它并挂起应用程序
private void Button_Click_7(object sender, RoutedEventArgs e)
{
ScriptBox.Items.Clear();
Functions.PopulateListBox(ScriptBox, "./Scripts", "*.txt");
Functions.PopulateListBox(ScriptBox, "./Scripts", "*.lua");
}
我是 WPF 的新手,所以找出发生这种情况的原因会有很大帮助。
编辑:可能是 Mscorelib.dll(不是)
编辑:使用 Peregrine 改进的 Try Catch
您尝试过使用 ScriptBox.UnselectAll()
或 ScriptBox.SelectedIndex = -1
吗?
假设 ScriptBox 是您的列表框。
即使您不打算采用完整的 MVVM 路线,将应用程序的数据与 UI 控件分开仍然是个好主意。
1] 在 Window 的构造函数中,创建一个 ObservableCollection<string>
并将其设置为 ScriptBox
控件的 ItemsSource
。
private ObservableCollection<string> _scriptBoxCollection;
public MyView()
{
_scriptBoxCollection = new ObservableCollection<string>();
ScriptBox.ItemsSource = _scriptBoxCollection ;
}
2] 将您的 PopulateListBox()
方法更改为 return 文件名集合。按照Single Responsibility Principle,这样的方法不应该关心它们生成的数据是如何被使用的。
public ReadOnlyCollection<string> GetMatchingFiles(string folder, string fileSpec) { ... }
return的值是ReadOnlyCollection<T>
符合Microsoft guidelines。
3] 更改按钮单击处理程序,以便它更新可观察集合。
private void Button_Click_7(object sender, RoutedEventArgs e)
{
_scriptBoxCollectionClear();
foreach(var item in Functions.GetMatchingFiles("./Scripts", "*.txt")
_scriptBoxCollection.Add(item);
Functions.GetMatchingFiles("./Scripts", "*.lua")
_scriptBoxCollection.Add(item);
}
ForEach
构造是必需的,因为标准 ObservableCollection
不支持 AddRange()
。
将此添加到 Functions.cs(并描述 PopulateListBox() 和任何其他将数据直接写入 UI 控件的类似方法)
public static ReadOnlyCollection<string> GetMatchingFiles(string folder, string fileType)
{
var result = new List<string>();
var dinfo = new DirectoryInfo(folder);
var files = dinfo.GetFiles(fileType);
foreach (var file in files)
{
result.Add(file.Name);
}
return result.AsReadOnly();
}
你好,今天我在用 WPF 做实验,我发现当一个 ListBox 有一个选中的项目时,它不允许修改它并挂起应用程序
private void Button_Click_7(object sender, RoutedEventArgs e)
{
ScriptBox.Items.Clear();
Functions.PopulateListBox(ScriptBox, "./Scripts", "*.txt");
Functions.PopulateListBox(ScriptBox, "./Scripts", "*.lua");
}
我是 WPF 的新手,所以找出发生这种情况的原因会有很大帮助。
编辑:可能是 Mscorelib.dll(不是)
编辑:使用 Peregrine 改进的 Try Catch
您尝试过使用 ScriptBox.UnselectAll()
或 ScriptBox.SelectedIndex = -1
吗?
假设 ScriptBox 是您的列表框。
即使您不打算采用完整的 MVVM 路线,将应用程序的数据与 UI 控件分开仍然是个好主意。
1] 在 Window 的构造函数中,创建一个 ObservableCollection<string>
并将其设置为 ScriptBox
控件的 ItemsSource
。
private ObservableCollection<string> _scriptBoxCollection;
public MyView()
{
_scriptBoxCollection = new ObservableCollection<string>();
ScriptBox.ItemsSource = _scriptBoxCollection ;
}
2] 将您的 PopulateListBox()
方法更改为 return 文件名集合。按照Single Responsibility Principle,这样的方法不应该关心它们生成的数据是如何被使用的。
public ReadOnlyCollection<string> GetMatchingFiles(string folder, string fileSpec) { ... }
return的值是ReadOnlyCollection<T>
符合Microsoft guidelines。
3] 更改按钮单击处理程序,以便它更新可观察集合。
private void Button_Click_7(object sender, RoutedEventArgs e)
{
_scriptBoxCollectionClear();
foreach(var item in Functions.GetMatchingFiles("./Scripts", "*.txt")
_scriptBoxCollection.Add(item);
Functions.GetMatchingFiles("./Scripts", "*.lua")
_scriptBoxCollection.Add(item);
}
ForEach
构造是必需的,因为标准 ObservableCollection
不支持 AddRange()
。
将此添加到 Functions.cs(并描述 PopulateListBox() 和任何其他将数据直接写入 UI 控件的类似方法)
public static ReadOnlyCollection<string> GetMatchingFiles(string folder, string fileType)
{
var result = new List<string>();
var dinfo = new DirectoryInfo(folder);
var files = dinfo.GetFiles(fileType);
foreach (var file in files)
{
result.Add(file.Name);
}
return result.AsReadOnly();
}