2013-08-07 76 views
1

我的問題是ComboBox未顯示存儲在其綁定列表中的值。在DropDownOpened事件上設置的WPF組合框綁定列表

下面是我在做什麼:

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; 
} 

我曾嘗試與ObservableCollection代替List這樣做,我已經使用PropertyChangedEventHandler也試過。這些方法都不適用於我。

任何想法爲什麼我的項目沒有被顯示,當我點擊下拉菜單?

+2

既然你這樣做是在後面的代碼呢,爲什麼不直接設置'ComboBox.ItemsSource'? –

+0

@AbeHeidebrecht試過了,它解決了我的問題!不知道爲什麼在WPF中設置ItemsSource不起作用,但請注意解釋嗎? –

+0

我添加了一個答案TR Ÿ幫助解釋這一點。 –

回答

2

由於您在代碼背後執行此操作,爲什麼不直接設置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(如您的ViewDependencyObject

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); } 
    } 

    ... 
} 
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; 
} 
0

除非我失去了一些東西在這裏:當設備被用於該設備的屬性更新

嘗試發射OnPropertyChanged,這應該解決這個問題我偶爾也不得不設置模式:

​​

在一些控件上。

在控件上設置itemssource直接告訴控件直接使用新項目,而不使用xaml中的鉤子。更新datacontext上的Devices屬性不會告訴組合框屬性已更改,因此它不會更新。通知組合框更改的方法是在設備屬性發生更改時觸發OnPropertyChanged。