DropDownOpened事件上设置的WPF组合框绑定列表
本文关键字:组合 绑定 列表 WPF 事件 设置 DropDownOpened | 更新日期: 2023-09-27 18:26:43
我的问题是ComboBox
没有显示存储在其绑定列表中的值。
以下是我正在做的:
WPF:
<ComboBox ItemsSource="{Binding Devices}"
DropDownOpened="deviceSelector_DropDownOpened"/>
注意,我的Window
的DataContext
是{Binding RelativeSource={RelativeSource Self}}
。
C#代码背后:
public List<String> Devices { get; set; }
private void deviceSelector_DropDownOpened(object sender, EventArgs e)
{
// the actual population of the list is occuring in another method
// as a result of a database query. I've confirmed that this query is
// working properly and Devices is being populated.
var dev = new List<String>();
dev.Add("Device 1");
dev.Add("Device 2");
Devices = dev;
}
我尝试过用ObservableCollection
而不是List
来实现这一点,我也尝试过使用PropertyChangedEventHandler
。这两种方法对我都不起作用
知道为什么当我点击下拉列表时我的项目没有显示吗?
既然您是在代码隐藏中完成这项工作的,为什么不直接设置ComboBox.ItemsSource
呢。
现在,我不会说这是应该在WPF中的方式(我更希望视图的数据加载在ViewModel中),但它会解决您的问题。
这不起作用的原因是您的属性在更改时不会通知绑定系统。我知道你说过你用PropertyChangedEventHandler
试过了,但除非你的View
看起来像这样,否则这是行不通的:
public class MyView : UserControl, INotifyPropertyChanged
{
private List<String> devices;
public event PropertyChangedEventHandler PropertyChanged;
public List<String> Devices
{
get { return devices; }
set
{
devices = value;
// add appropriate event raising pattern
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("Devices"));
}
}
...
}
同样,使用ObservableCollection
只能像这样工作:
private readonly ObservableCollection<string> devices = new ObservableCollection<string>();
public IEnumerable<string> Devices { get { return devices; } }
private void deviceSelector_DropDownOpened(object sender, EventArgs e)
{
devices.Clear();
devices.Add("Device 1");
devices.Add("Device 2");
}
任何一种方法都应该填充ComboBox
,在我刚刚运行的一个快速测试中,它起了作用。
编辑以添加DependencyProperty
方法
最后一种方法是使用DependencyProperty
(因为您的View
是DependencyObject
:
public class MyView : UserControl
{
public static readonly DependencyProperty DevicesProperty = DependencyProperty.Register(
"Devices",
typeof(List<string>),
typeof(MainWindow),
new FrameworkPropertyMetadata(null));
public List<string> Devices
{
get { return (List<string>)GetValue(DevicesProperty); }
set { SetValue(DevicesProperty, value); }
}
...
}
下面的更改(由Abe Heidebrecht建议)解决了这个问题,但我不知道为什么。有人愿意解释一下吗?
WPF:
<ComboBox DropDownOpened="deviceSelector_DropDownOpened"
Name="deviceSelector"/>
C#代码背后:
private void deviceSelector_DropDownOpened(object sender, EventArgs e)
{
var dev = new List<String>();
dev.Add("Device 1");
dev.Add("Device 2");
deviceSelector.ItemsSource = dev;
}
除非我在这里遗漏了什么:
当更新设备属性的设备时,尝试激发OnPropertyChanged,这应该可以解决此问题。我偶尔也不得不设置模式:
ItemsSource="{Binding Devices, Mode=TwoWay}"
在某些控件上。
直接在控件上设置项源告诉控件直接使用新项,而不使用xaml中连接的绑定。更新datacontext上的Devices属性不会告诉组合框Devices属性已更改,因此不会更新。通知组合框更改的方法是在设备属性更改时为其激发OnPropertyChanged。