我的问题是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
。这些方法都没有对我有用。
当我点击下拉列表时,知道为什么我的项目没有显示?
答案 0 :(得分:3)
由于您无论如何都要在代码中执行此操作,为什么不直接设置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); }
}
...
}
答案 1 :(得分:0)
以下变化(由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;
}
答案 2 :(得分:0)
除非我在这里遗漏了什么:
尝试在设备更新设备属性时触发OnPropertyChanged,这应解决此问题。我偶尔也必须设置模式:
ItemsSource="{Binding Devices, Mode=TwoWay}"
在一些控件上。
直接在控件上设置itemssource会告诉控件直接使用新项,而不使用连接在xaml中的绑定。更新datacontext上的Devices属性不会告诉组合框,Devices属性已更改,因此不会更新。通知组合框更改的方法是在设备属性发生变化时触发OnPropertyChanged。