2013-10-24 64 views
6

我是WPF的新手。WPF Combobox在更改集合時沒有更新

我想將字符串的集合綁定到組合框。

public ObservableCollection<string> ListString {get; set;} 

綁定和DataContext的是如下

<Window 
     x:Class="Assignment2.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:validators="clr-namespace:Assignment2" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525" 
     DataContext="{Binding RelativeSource={RelativeSource Self}, Path=.}"> 
    <Grid> 
     <ComboBox Height="23" HorizontalAlignment="Left" Margin="109,103,0,0" Name="StringComboBox" VerticalAlignment="Top" Width="120" SelectionChanged="StringComboBox_SelectionChanged"> 
      <ComboBox.ItemsSource> 
       <Binding Path="ListString" BindsDirectlyToSource="True" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged"></Binding> 
      </ComboBox.ItemsSource> 
     </ComboBox> 

我才知道,這是發生,因爲集合更新設置。如果我寫

public MainWindow() 
     { 

      InputString = ""; 
      ListString = new ObservableCollection<string>(); 
      ListString.Add("AAA"); 
      ListString.Add("BBB"); 
      ListString.Add("CCC"); 
      InitializeComponent(); 

     } 

它的工作,但如果我在上面第一行移動InitializeComponent()如下,這是行不通的。

public MainWindow() 
      { 
       InitializeComponent(); 
       InputString = ""; 
       ListString = new ObservableCollection<string>(); 
       ListString.Add("AAA"); 
       ListString.Add("BBB"); 
       ListString.Add("CCC");     
      } 

我應該怎麼辦?

+1

一個工作,另一個不工作。我會選擇適用的選項。 – Paparazzi

+1

@Blam我想推廣這個問題來解決我的其他問題,其中列表來自WCF服務。你仍然建議去選擇適用的選項? –

回答

9

解決了這個問題。實施INotifyPropertyChanged的如下

public partial class MainWindow : Window, INotifyPropertyChanged 

修改的存取如下

private ObservableCollection<string> listString; 
    public ObservableCollection<string> ListString 
    { 
     get 
     { 
      return listString; 
     } 
     set 
     { 
      listString = value; 
      NotifyPropertyChanged("ListString"); // method implemented below 
     } 
    } 

和增加了以下事件和方法,以提高該事件

public event PropertyChangedEventHandler PropertyChanged; 
public void NotifyPropertyChanged(string name) 
{ 
    if (PropertyChanged != null) 
    { 
     PropertyChanged(this,new PropertyChangedEventArgs(name)); 
    } 
} 

和它的工作原理B)

0

如果你改變你的代碼

<Window 
    x:Class="Assignment2.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:validators="clr-namespace:Assignment2" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Height="350" Width="525"> 
<Grid> 
    <ComboBox Height="23" HorizontalAlignment="Left" Margin="109,103,0,0" Name="StringComboBox" VerticalAlignment="Top" Width="120" SelectionChanged="StringComboBox_SelectionChanged" 
       ItemsSource="{Binding ListString, Mode=OneWay}"/> 

CS會發生什麼。

public MainWindow() 
     { 
      InitializeComponent(); 
      InputString = ""; 
      ListString = new ObservableCollection<string>(); 
      ListString.Add("AAA"); 
      ListString.Add("BBB"); 
      ListString.Add("CCC"); 

      this.DataContext=this;  
     }   

btw:使用mode = twoway設置ItemsSource對我來說沒有任何意義。你的組合框永遠不會爲你的視圖模型「創建一個新的itemssource」。

編輯: 我認爲你的第一個解決方案,因爲在XAML設置DataContext的作品。我假設DataContext =「{Binding RelativeSource = {RelativeSource Self},Path =。}」在調用InitializeComponent()時執行。因爲你的ListString屬性只是一個自動屬性,而不是實現INotifyPropertyChanged - 你的mainwindowview不會得到你的ctor創建一個新的ListString屬性的通知。

public ObservableCollection<string> ListString {get{return _list;}; set{_list=value; OnPropertyChanged("ListString");}} 

應與你的方法是可行的,但你必須執行INotifyPropertyChanged你MainWindow類。

+0

我開始知道這是因爲InitializeComponent被調用時,它將該控件綁定到該特定對象引用,並且當引用自身發生變化時,它不起作用。 –

+0

如果您希望設置liststring = new OberservableCollection 多於一次,則必須爲您的類實現INotifyPropertyChanged。 InitializeComponent()的問題;分別this.DataContext = this;看到我的編輯 – blindmeis

+0

這解決了我的問題,它的工作..非常感謝 –

0

您可以在代碼後面設置組合框的項目源,或者在列表填充後再次設置datacontext,或者您可以使用inotifychanged來提高屬性更改。

public MainWindow() 
     { 
      InitializeComponent(); 
      InputString = ""; 
      ListString = new ObservableCollection<string>(); 
      ListString.Add("AAA"); 
      ListString.Add("BBB"); 
      ListString.Add("CCC"); 
      StringComboBox.ItemsSource = ListString; 

     } 
+0

與您的建議也不起作用:( –

+0

您確定您在代碼中添加了StringComboBox.ItemsSource = ListString;它應該工作。在我的結尾和它的工作 – Jason

+1

抱歉它正在工作,但你不認爲我應該通過XAML進行綁定 –

0

對我來說,問題在於「新興」ListString。使它成爲一個屬性(所選的答案)是一種解決方法。或者內嵌瞬時,或者把它放在InitializeComponent之前我相信會沒事的。

如果預計經常會出現新問題,將ObservableCollection封裝在管理器類中可能會有所幫助。在排除我自己的問題後,我發現了這個問題。我通過執行INotifyCollectionChanged並轉發事件來得到它的工作,如

/// <summary> 
/// Maintains an observable (i.e. good for binding) collection of resources that can be indexed by name or alias 
/// </summary> 
/// <typeparam name="RT">Resource Type: the type of resource associated with this collection</typeparam> 
public class ResourceCollection<RT> : IEnumerable, INotifyCollectionChanged 
    where RT : class, IResource, new() 
{ 
    public event NotifyCollectionChangedEventHandler CollectionChanged 
    { 
     add { Ports.CollectionChanged += value; } 
     remove { Ports.CollectionChanged -= value; } 
    } 

    public IEnumerator GetEnumerator() { return Ports.GetEnumerator(); } 

    private ObservableCollection<RT> Ports { get; set; } 
    private Dictionary<string, RT> ByAlias { get; set; } 
    private Dictionary<string, RT> ByName { get; set; } 
} 
相關問題