C# PropertyChanged在ViewModelBase中始终为空
为了更好地理解MVVM模式,我做了一个简单的示例。 以下是示例解决方案的链接,因为很难解释整个问题: 有C# PropertyChanged在ViewModelBase中始终为空,c#,wpf,xaml,mvvm,binding,C#,Wpf,Xaml,Mvvm,Binding,为了更好地理解MVVM模式,我做了一个简单的示例。 以下是示例解决方案的链接,因为很难解释整个问题: 有Employee模型(带有Age属性)和EmployeeViewModel,其中包含Employee对象,并在以下代码中更改其Age属性: public int Age { get { return _employee.Age; } set { if (value == _employee.Age) return;
Employee
模型(带有Age
属性)和EmployeeViewModel
,其中包含Employee
对象,并在以下代码中更改其Age
属性:
public int Age
{
get { return _employee.Age; }
set
{
if (value == _employee.Age)
return;
_employee.Age = value;
NotifyPropertyChanged("Age");
}
}
EmployeeViewModel
继承自具有标准InotifyProperty更改代码的ViewModelBase
类:
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(p));
}
我正在尝试使用ICommand更改员工的年龄:
public void Increase()
{
this.SelectedEmployee.Age++;
NotifyPropertyChanged("Age");
}
属性已更改,但绑定的TextBLock不会更改其值。
我检查并看到调用了NotifyPropertyChanged
,但是PropertyChanged
是null
。
我还确保我的应用程序中只有一个PeopleViewModel
。
那么,为什么属性被更改
为null
编辑:
以下是ViewModelBase
的完整代码:
public class ViewModelBase
{
public String DisplayName { get; set; }
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(string p)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(p));
}
}
#endregion
}
有PeopleViewModel
包含observableCollectio
n和EmployeeViewModels
,并设置为DataContext
。
属性的值会更改,但如果不重新加载对象,则不会显示更改
以下是PeopleViewer.xaml,其中显示了绑定:
<UserControl x:Class="MVVMTestMyCopy.View.PeopleViewer"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:vm="clr-namespace:MVVMTestMyCopy.ViewModel"
mc:Ignorable="d"
d:DesignHeight="316" d:DesignWidth="410">
<UserControl.Resources>
<vm:PeopleViewModel x:Key="viewModel"/>
</UserControl.Resources>
<Grid DataContext="{Binding Source={StaticResource viewModel}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ListBox ItemsSource="{Binding People}"
Grid.Column="0"
Margin="5,5,4,5"
SelectedItem="{Binding SelectedEmployee, Mode=TwoWay}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Margin="2"
Text="{Binding FirstName}" />
<TextBlock Margin="2"
Text="{Binding LastName}" />
<TextBlock Margin="0 2"
Text="[" />
<TextBlock Margin="2"
Text="{Binding Age}" />
<TextBlock Margin="0 2"
Text="]" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="0.75*" />
<RowDefinition Height="0.25*" />
</Grid.RowDefinitions>
<Grid x:Name="EmployeeDetails"
Grid.Row="0"
DataContext="{Binding SelectedEmployee}"
Margin="5">
<Grid.RowDefinitions>
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<TextBlock Text="{Binding FirstName}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Grid.Column="0"/>
<TextBlock Text="{Binding LastName}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Grid.Row="1" />
<TextBlock Text="{Binding Age}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Grid.Row="2" />
</Grid>
<StackPanel Orientation="Vertical"
HorizontalAlignment="Center"
Grid.Row="1">
<Button x:Name="button"
Content="-"
Width="32"
Height="32"
Command="{Binding DecreaseCommand}">
</Button>
<Button x:Name="button1"
Content="+"
Width="32"
Height="32"
Command="{Binding IncreaseCommand}">
</Button>
</StackPanel>
</Grid>
</Grid>
</UserControl>
在项目中,实际上并没有在视图模型上实现INotifyPropertyChanged。你有:
public class ViewModelBase
但这应该是:
public class ViewModelBase : INotifyPropertyChanged
由于未实现INotifyPropertyChange,WPF绑定系统将无法为PropertyChanged事件添加处理程序。在ViewModelBase上实现INotifyPropertyChanged接口。
您已经定义了PropertyChanged事件,但重要的是接口。我使用而不是BaseViewModel实现检查了您的应用程序,它正常工作 我建议使用MVVM Light,因为还有其他功能,如消息传递、处理和可混合性 您可以使用轻松下载和安装它 如果仍要实现INotifyPropertyChange,以下代码将执行此操作:
public class MainViewModel: INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
var e = new PropertyChangedEventArgs(propertyName);
handler(this, e);
}
}
}
您是否在XAML中设置了双向绑定?您是否向PropertyChanged事件添加了事件处理程序?@Randolf Rincón-Fadul我认为这里不需要这样做,我正在通过按钮更改属性值,请查看该项目,这是代表我问题的小样本解决方案。@Lasse V.Karlsen♦ - 请你解释一下应该添加什么事件处理程序,我想我遗漏了一些东西。我在问题中添加了完整的ViewModelBase代码。@MyUserName我问您,如果您的绑定模式设置为OneTime,则即使您更改了视图模型,它也永远不会更新。对不起,我在我的BB上,无法下载文件,所以无法查看。哇,谢谢!你是完全正确的,我认为有一些绑定,甚至没有注意到我没有在视图模型中更改INotifyPropertyChanged。只是也经历了同样的事情!:-)谢谢,这刚刚解决了我过去几个小时遇到的同一个bug。