我们有一个Item Details窗口,它使用ViewModel的一个实例作为DataContext。我们在ViewModel上有一个名为StatusMessage的简单字符串属性,用于向用户提供反馈。我们在此视图模型上实现了INotifyPropertyChanged,并且StatusMessage属性配置为引发事件。 ViewModel有三个其他成员,它们是类(或集合),在所有这些工作中,绑定的工作方式应该如此。
问题是,当以编程方式更改时,StatusMessage不会在GUI中更新。我们已经调试并发现该属性确实在发生变化,而我们订阅了属性更改事件后面的Window代码,并且可以看到该事件确实正在触发。
绑定到StatusMessage的任何控件都将显示构造函数上设置的内容,但在此之后它永远不会更新。
我使用了两个不同的控件,一个是带有twoway绑定的文本框,另一个是标签,两者都绑定到StatusMessage。当我使用TextBox更改值时,我的标签也会更改。但是,ViewModel内部所做的任何更改都不会传播到GUI。
没有绑定错误。我们甚至检查了PropertyChanged事件处理程序上的HasBindingErrors属性,它显示为false并显示我们的控件仍然绑定到StatusMessage。
此问题仅影响基本/根ViewModel类。所有成员都是类并拥有自己的成员并实现INotifyPropertyChanged而没有任何问题。我们有完全双向绑定,他们都工作。
我已经尝试过清理和重建项目,但没有任何区别。
什么可能导致绑定失败而不产生任何错误消息?
这是实际的代码,虽然我不得不削减很多,以使其在这里很好地适应:
XAML:
<Window x:Class="PZESpecsApp.SpecDetails"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
xmlns:local="clr-namespace:SpecsApp"
Title="Spec Details" Height="600" Width="1000">
<Grid>
<TextBlock Text="{Binding spec.MakeAndModelNo}" FontSize="24" FontWeight="Bold" Margin="16,10,0,0" />
<TextBox Name="txtStatusMessage" Text="{Binding StatusMessage, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" FontSize="24" FontWeight="Bold" Foreground="Black" />
<Label Grid.Column="0" Content="{Binding Path=StatusMessage}" Foreground="White" />
</Grid>
</Window>
窗口代码:
public partial class SpecDetails : Window
{
private SpecDetailsViewModel model;
public SpecDetails(int id)
{
InitializeComponent();
model = new SpecDetailsViewModel(id);
model.PropertyChanged += ViewModel_PropertyChanged;
DataContext = model;
}
private void ViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
//this shows that the property actually changes as expected
Debug.Print("PropertyChanged=" + e.PropertyName);
}
}
ViewModel代码:
public class SpecDetailsViewModel
{
public event PropertyChangedEventHandler PropertyChanged;
private Spec _spec;
public Spec spec
{
get { return _spec; }
set { _spec = value; PropertyChanged.Notify(() => this.spec); }
}
private string _statusMessage;
public string StatusMessage
{
get { return _statusMessage; }
set { _statusMessage = value; PropertyChanged.Notify(() => this.StatusMessage); }
}
public SpecDetailsViewModel(int id)
{
spec = AppData.SpecsList.FirstOrDefault(s => s.id == id);
StatusMessage = "Monkey See, Monkey Do!"; //this stays on the GUI
}
public void SaveSpec() {
//this doesn't have any affect on the GUI
this.StatusMessage = "Changes Saved";
}
}
答案 0 :(得分:2)
好的,我发现了问题。我猜你可以说我们隐含地实现了INotifyPropertyChanged,显然这还不够好。修复程序位于ViewModel类中:
public class SpecDetailsViewModel : INotifyPropertyChanged