![](/img/trans.png)
[英]WPF - data binding - no updates even with INotifyPropertyChanged
[英]INotifyPropertyChanged not working with WPF data binding
我的MainWindow.xaml文件中有一個組合框,如下所示:
<ComboBox Name="material1ComboBox"
HorizontalAlignment="Center"
MinWidth="100"
ItemsSource="{Binding ViewProperties.MaterialDropDownValues}"
SelectedValue="{Binding ViewProperties.Material1SelectedValue}"
SelectionChanged="Material1ComboBoxSelectionChanged">
</ComboBox>
我使用this.datacontext = this
在codebehind中分配了datacontext。
我創建了一個ViewProperties
,它作為MainWindow
的屬性進行訪問,是一個實現INotifyPropertyChanged並包含MaterialDropDownValues
作為屬性的類。
我甚至將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並使該屬性成為一個observablecollection。
解決方案1:
不要重新創建this.materialDropDownValues
嘗試做
this.materialDropDownValues.Clear();
foreach(var mystring in myStrings)
this.materialDropDownValues.Add(mystring);
對於所有新項目。 如果這不起作用,那么嘗試解決方案2 ......
解決方案2:
根據我的經驗,我認為如果未指定ItemsControl.ItemTemplate
則不會在Property Change通知上刷新像int
, string
, bool
, double
等原始類型的ObservableCollection
。
<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的items容器只需復制item.ToString()就可以在其中為原始數據創建不可觀察的項容器。 在上面的代碼中, {Binding}
應該在更改整個項目源時更新數據更改。
讓我知道這個是否奏效。
當我碰到這樣的事情時,我做的第一件事就是玩弄綁定模式。 就像是:
ItemsSource="{Binding Path=ViewProperties.MaterialDropDownValues, Mode=TwoWay}"
這有時會讓你失望。 我要確定的另一件事是,如果您在初始加載后實例化新的ViewProperties對象,則通知更改。 如果不這樣做,XAML將引用該對象的過時版本,而您的代碼隱藏/視圖模型在另一個版本上運行。
編輯以回應評論
以下都沒有解決問題,但留作參考。
原始答案
問題是您沒有為視圖指定DataContext
,這是WPF默認查找Binding
值的地方。
如果MainWindow
上的ViewProperties
屬性是公共的,您只需將綁定更改為:
ItemsSource="{Binding ViewProperties.MaterialDropDownValues,
RelativeSource={RelativeSource FindAncestor, AncestorType=Window}"
這會導致WPF在可視樹中的組合框上方找到的Window
的第一個出現時查找屬性值。
或者,您可以將Window.DataContext
屬性設置為Window.DataContext
實例, ViewProperties
綁定更改為以下內容:
ItemsSource="{Binding MaterialDropDownValues}"
這些中的任何一個都可以工作,但我建議使用后者,因為它更接近MVF模式,這在WPF / XAML應用程序中通常是首選的。
如果你改變你的xaml會發生什么
<ComboBox Name="material1ComboBox"
HorizontalAlignment="Center"
MinWidth="100"
DataContext="{Binding ViewProperties}"
ItemsSource="{Binding MaterialDropDownValues}"
SelectedValue="{Binding Material1SelectedValue}"
SelectionChanged="Material1ComboBoxSelectionChanged">
</ComboBox>
盡管如此,您只需要實例化您的集合一次,並在使用OberservableCollection時使用remove,add和clear。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.