2011-10-11 48 views
3

我有一個組合框在我MainWindow.xaml文件,像這樣的工作:INotifyPropertyChanged的不使用WPF數據綁定

<ComboBox Name="material1ComboBox" 
      HorizontalAlignment="Center" 
      MinWidth="100" 
      ItemsSource="{Binding ViewProperties.MaterialDropDownValues}" 
      SelectedValue="{Binding ViewProperties.Material1SelectedValue}" 
      SelectionChanged="Material1ComboBoxSelectionChanged"> 
</ComboBox> 

我分配使用this.datacontext = this在代碼隱藏在DataContext。

我創建了作爲MainWindow屬性進行訪問,並且是實現INotifyPropertyChanged幷包含MaterialDropDownValues作爲屬性類ViewProperties

我甚至將MaterialDropDownValues更改爲ObservableCollection

問題是數據綁定工作在初始化但是如果MaterialDropDownValues屬性更改組合框值不更新。

我在ViewProperties類以下內容:

public ObservableCollection<string> MaterialDropDownValues 
    { 
     get { return this.materialDropDownValues; } 
     set 
     { 
      this.materialDropDownValues = value; 

      OnPropertyChanged("MaterialDropDownValues"); 
     } 
    } 

    protected void OnPropertyChanged(string name) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(name)); 
     } 
    } 

任何想法,爲什麼這是不工作?我可以找到的所有其他答案建議實施INotifyPropertyChanged並使該屬性成爲可觀察集合。

+2

請注意,如果您只是從列表中添加/刪除數據,則不應重新綁定整個集合。你應該這樣做:'materialDropDownValues.Remove(value);'。 –

+0

在過去,當我遇到這個問題時,它有時是由其他(代碼隱藏)代碼直接編程設置ItemsSource(從而終止綁定)導致的。 – bigtlb

+0

注意:整個列表可以立即更改,不僅僅是需要添加或刪除的單個項目。 – Seth

回答

0

當我遇到這樣的事情時,我所做的第一件事就是玩弄綁定模式。例如:

ItemsSource="{Binding Path=ViewProperties.MaterialDropDownValues, Mode=TwoWay}" 

有時候會讓你失望。另一件事我會確定的是,如果您在初始加載後實例化新的ViewProperties對象,則通知您發生更改。如果不這樣做,那麼XAML將引用該對象的過時版本,而您的代碼隱藏/視圖模型在另一個版本上運行。

+0

我懷疑這與綁定的方向有什麼關係 - 「ItemsSource」將默認爲「OneWay」,這至少意味着將顯示項目。作爲一個方面說明,如果您在運行時查看Visual Studio中的調試窗口,它通常會向您顯示(良性)錯誤消息,如果出於某種原因無法解析「綁定」,那麼這是一個相當不錯的第一診斷步驟 –

0

編輯迴應評論

無的下方解決了這個問題,但留下作爲參考。


原來的答案

的問題是,你有沒有指定的DataContext對你的看法,這是在WPF查找Binding值默認。

只要你ViewProperties財產上MainWindow是公開的,你可以簡單地改變你的綁定:

ItemsSource="{Binding ViewProperties.MaterialDropDownValues, 
    RelativeSource={RelativeSource FindAncestor, AncestorType=Window}" 

這將導致WPF找上Window首次出現的屬性值,它找到的組合框上面視覺樹。

或者,你可以在Window.DataContext屬性正好被設置爲你的ViewProperties實例,並更改綁定到以下幾點:

ItemsSource="{Binding MaterialDropDownValues}" 

任何一項都將工作,但我會建議使用後者,因爲它更接近到WPF/XAML應用程序中通常首選的MVVM模式。

+0

我確實指定了datacontext作爲代碼中的MainWindow(按照答案)。但是,您說我沒有爲該綁定指定正確的數據上下文? – Seth

+0

啊,是的,你確實提到過。我從來沒有見過過設置'this.DataContext = this'的例子,所以我不能說它是否應該有效。無論如何,我描述的任何一種方法都應該解決這個問題。 –

+0

剛剛做了一個快速測試,'this.DataContext = this'似乎對我來說很好...... –

0

,如果你改變你的XAML來

<ComboBox Name="material1ComboBox" 
     HorizontalAlignment="Center" 
     MinWidth="100" 
     DataContext="{Binding ViewProperties}" 
     ItemsSource="{Binding MaterialDropDownValues}" 
     SelectedValue="{Binding Material1SelectedValue}" 
     SelectionChanged="Material1ComboBoxSelectionChanged"> 
</ComboBox> 

不過你應該只是實例化您的收藏一次,並只使用刪除,增加和明確的,當你使用OberservableCollection會發生什麼。

1

解決方案1:

不要重新this.materialDropDownValues試圖爲所有新項目做

this.materialDropDownValues.Clear(); 
foreach(var mystring in myStrings) 
     this.materialDropDownValues.Add(mystring); 

。如果這不工作然後嘗試解決2 ...

解決方案2:

按我的經驗,我認爲基本類型的ObservableCollectionintstringbooldouble等的房產不刷新如果未指定ItemsControl.ItemTemplate,則更改通知。

<ComboBox Name="material1ComboBox" 
      HorizontalAlignment="Center" 
      MinWidth="100" 
      ItemsSource="{Binding ViewProperties.MaterialDropDownValues}" 
      SelectedValue="{Binding ViewProperties.Material1SelectedValue}" 
      SelectionChanged="Material1ComboBoxSelectionChanged"> 
     <ComboBox.ItemTemplate> 
      <DataTemplate DataType="{x:Type System:String}"> 
       <TextBlock Text="{Binding}" /> 
      </DataTemplate> 
     </ComboBox.ItemTemplate> 
    </ComboBox> 

這是因爲ItemsControl中的物品的容器通過簡單地複製item.ToString創造了它不可觀察的項目容器的原始數據()。在上面的代碼中,{Binding}應更新整個項目源更改時的數據更改。

讓我知道這是否工作。

+0

剛去度假,但當我回來時,我會在這兩個解決方案中去。 – Seth