我正在尝试在这里做一些非常基本的事情,我没想到会给我带来这么多问题。我的主窗口类上有一个名为 ItemList 的公共(public)属性,类型为 List<string>
.我在程序的整个生命周期中都添加到这个列表中,并且希望当我将新项目添加到 ItemList 属性时,表单上的 ListBox 控件能够自动更新。
到目前为止,我有以下 XAML:
<Window x:Class="ElserBackupGUI.Main"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Backup Profile Editor [New Profile]" Height="480" Width="640">
<DockPanel>
<Menu DockPanel.Dock="Top">
<MenuItem Header="File">
<MenuItem Header="Open"/>
</MenuItem>
</Menu>
<StackPanel Orientation="Vertical" DockPanel.Dock="Top" Margin="10 10 10 3">
<TextBlock>Items to backup:</TextBlock>
</StackPanel>
<DockPanel DockPanel.Dock="Bottom" Margin="10 0 10 10">
<StackPanel Orientation="Horizontal">
<Button Name="AddDirectoryButton" Height="22.725" Width="120" Margin="0 0 6 0" Click="AddDirectoryButton_Click">Add Directory...</Button>
<Button Name="AddFileButton" Height="22.725" Width="90" Margin="0 0 6 0" Click="AddFileButton_Click">Add File...</Button>
<Button Name="RemoveDirectoriesButton" Height="22.725" Width="75.447" Margin="0 0 6 0">Remove</Button>
</StackPanel>
</DockPanel>
<ListBox Name="SelectedItems" Margin="10 0 10 10" ItemsSource="{Binding Path=ItemList}"/>
</DockPanel>
</Window>
相关的代码隐藏代码如下:
public partial class Main : Window
{
private string _lastFolder = string.Empty;
private ObservableCollection<string> _itemList = new ObservableCollection<string>();
public ObservableCollection<string> ItemList {
get { return _itemList ?? (_itemList = new ObservableCollection<string>()); }
set { _itemList = value; }
}
public Main()
{
InitializeComponent();
ItemList.Add("test item");
DataContext = this;
}
private void AddDirectoryButton_Click(object sender, RoutedEventArgs e)
{
FolderBrowserDialog dialog = new FolderBrowserDialog();
if (!string.IsNullOrEmpty(_lastFolder))
dialog.SelectedPath = _lastFolder;
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
_lastFolder = dialog.SelectedPath;
ItemList.Add(dialog.SelectedPath);
}
}
private void AddFileButton_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog dialog = new OpenFileDialog();
if (!string.IsNullOrEmpty(_lastFolder))
dialog.InitialDirectory = _lastFolder;
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
_lastFolder = System.IO.Path.GetDirectoryName(dialog.FileName);
SelectedItems.ItemsSource = null;
ItemList.Add(dialog.FileName);
}
}
}
我是 WPF 的新手,对于这样一个简单的问题,大多数教程似乎都过于复杂。我似乎无法到达任何地方 - 我错过了什么?
最佳答案
你应该使用 BindingList<T>
或 ObservableCollection<T>
而不是 List<T>
.
问题是,为了按照你想要的方式绑定(bind),它需要实现 INotifyCollectionChanged
或 IBindingList
. List<T>
不支持这个。
编辑:
检查您的更改后,仍然存在一个问题。
在 AddFileButton_Click 事件处理程序中,删除以下行:
SelectedItems.ItemsSource = null;
它明确地删除了您的绑定(bind),并导致列表框被清除。如果您删除它,您的代码应该按原样工作。
但是,我确实建议将您的集合定义和构造函数更改为更类似的内容:
// No need for the null checking every time, or public setter. They just cause issues
public ObservableCollection<string> ItemList
{
get;
private set;
}
// Add construction here, now that we're using an auto-prop
public Main()
{
this.ItemList = new ObservableCollection<string>();
InitializeComponent();
ItemList.Add("test item");
DataContext = this;
}
关于.net - WPF - 将列表框绑定(bind)到列表 <string> - 我做错了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1488840/