2

我的问题是ComboBox没有显示存储在其绑定列表中的值。

这是我正在做的事情:

WPF:

<ComboBox ItemsSource="{Binding Devices}" 
  DropDownOpened="deviceSelector_DropDownOpened"/>

请注意,我WindowDataContext{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;
} 

我尝试过使用 aObservableCollection而不是 a 来执行此List操作,并且我也尝试过使用 a PropertyChangedEventHandler。这些方法都不适合我。

知道为什么单击下拉列表时我的项目没有显示吗?

4

3 回答 3

4

既然您无论如何都是在代码后面执行此操作,为什么不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"));
        }
    }

    ...
}

同样,使用 anObservableCollection只会像这样工作:

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方法

你可以做到这一点的最后一种方法是使用 a DependencyProperty(因为你View是 a 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); }
    }

    ...
}
于 2013-08-07T19:40:55.053 回答
1

以下更改(由 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;
} 
于 2013-08-07T19:32:36.620 回答
0

除非我在这里遗漏了什么:

当设备为设备属性更新时尝试触发 OnPropertyChanged,这应该可以解决这个问题。我偶尔也不得不设置模式:

ItemsSource="{Binding Devices, Mode=TwoWay}"

在某些控件上。

在控件上设置 itemssource 直接告诉控件直接使用新项目,而不使用 xaml 中挂钩的绑定。更新 datacontext 上的 Devices 属性不会告诉组合框 Devices 属性已更改,因此不会更新。通知组合框更改的方法是在设备属性发生更改时为其触发 OnPropertyChanged。

于 2013-08-07T19:34:12.937 回答