MVVMLight - UI 在 属性 发生变化时不更新
MVVMLight - UI not updating when property has changed
我正在使用 C# 和 MVVMLight 开发一个小型数据驱动应用程序,但在尝试 add/edit 新项目时我 运行 遇到了问题。
基本上,我可以毫无问题地将 SelectedMember 属性 设置为数据库中已有的成员对象:
public MemberDetailViewModel()
{
_context = new DatabaseEntities();
GetMembers(); // This just loads the Member objects into an ObservableCollection.
SelectedMember = _members.FirstOrDefault(); // UI updates as expected.
}
SelectedMember 是这样实现的:
public Member SelectedMember
{
get { return _selectedMember; }
set { Set(ref _selectedMember, value); }
}
现在这很好,因为当我编辑对象时,所有数据验证都有效。
然而,当我使用此代码添加新对象时:
private void NewMember()
{
var member = new Member();
SelectedMember = member; // UI doesn't update, is still on previous object.
}
UI 没有更新,似乎 SelectedMember 中的 Member 对象与构造函数中加载的对象相同。
此外,当我从构造函数将空对象加载到 SelectedMember 属性 时,应用程序似乎不知道它的存在,并且当我编辑控件中的值时没有数据验证例程触发:
public MemberDetailViewModel()
{
_context = new DatabaseEntities();
SelectedMember = new Member(); // Binding appears to fail, data validation code not firing when control values changed.
}
我做错了什么?
编辑:
只是在实际加载视图模型时查看了输出,我已经看到了。
System.Windows.Data Error: 40 : BindingExpression path error: 'Centres' property not found on 'object' ''Member_B31A44ECE333F4E7E07BE25FA5BDC79874BAE6C64589F9765ACA373D89BBBD6B' (HashCode=45485186)'. BindingExpression:Path=Centres; DataItem='Member_B31A44ECE333F4E7E07BE25FA5BDC79874BAE6C64589F9765ACA373D89BBBD6B' (HashCode=45485186); target element is 'ComboBox' (Name=''); target property is 'ItemsSource' (type 'IEnumerable')
System.Windows.Data Warning: 40 : BindingExpression path error: 'SelectedMember' property not found on 'object' ''Member_B31A44ECE333F4E7E07BE25FA5BDC79874BAE6C64589F9765ACA373D89BBBD6B' (HashCode=45485186)'. BindingExpression:Path=SelectedMember.LocalCentre; DataItem='Member_B31A44ECE333F4E7E07BE25FA5BDC79874BAE6C64589F9765ACA373D89BBBD6B' (HashCode=45485186); target element is 'ComboBox' (Name=''); target property is 'SelectedValue' (type 'Object')
我觉得我做了一些愚蠢的事情...但是什么?
编辑 2:
上述错误已修复,但即使显式调用 RaisePropertyChanged,即使 SelectedMember 发生更改,UI 仍然不会更新。
编辑3:
希望这是您需要的XAML:
<UserControl x:Class="Project.Views.MemberDetailView"
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:models="clr-namespace:Project.Client.Models"
mc:Ignorable="d"
d:DesignHeight="600" d:DesignWidth="800">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Assets/ResourceDictionaries/DataEntryScreens.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<WrapPanel>
<Expander Header="Personal Information">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Vertical">
<TextBlock Text="Forename:" />
<TextBox Text="{Binding SelectedMember.Forename, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
<!-- Other controls omitted. -->
</Expander>
</WrapPanel>
</UserControl>
<!--MemberDetailView.xaml.cs-->
public partial class MemberDetailView : UserControl
{
public MemberDetailView()
{
InitializeComponent();
this.DataContext = new MemberDetailViewModel();
}
}
我已经解决了这个...不知何故...
我不确定我做了什么,但显然在视图的构造函数中设置 ViewModel 设法搞砸了一切。
所以从这里开始:
public MemberDetailView()
{
InitializeComponent();
this.DataContext = new MemberDetailViewModel() { Header = "Members" };
}
对此:
public MemberDetailView()
{
InitializeComponent();
//this.DataContext = new MemberDetailViewModel() { Header = "Members" };
}
已解决问题。
我正在使用 C# 和 MVVMLight 开发一个小型数据驱动应用程序,但在尝试 add/edit 新项目时我 运行 遇到了问题。
基本上,我可以毫无问题地将 SelectedMember 属性 设置为数据库中已有的成员对象:
public MemberDetailViewModel()
{
_context = new DatabaseEntities();
GetMembers(); // This just loads the Member objects into an ObservableCollection.
SelectedMember = _members.FirstOrDefault(); // UI updates as expected.
}
SelectedMember 是这样实现的:
public Member SelectedMember
{
get { return _selectedMember; }
set { Set(ref _selectedMember, value); }
}
现在这很好,因为当我编辑对象时,所有数据验证都有效。
然而,当我使用此代码添加新对象时:
private void NewMember()
{
var member = new Member();
SelectedMember = member; // UI doesn't update, is still on previous object.
}
UI 没有更新,似乎 SelectedMember 中的 Member 对象与构造函数中加载的对象相同。
此外,当我从构造函数将空对象加载到 SelectedMember 属性 时,应用程序似乎不知道它的存在,并且当我编辑控件中的值时没有数据验证例程触发:
public MemberDetailViewModel()
{
_context = new DatabaseEntities();
SelectedMember = new Member(); // Binding appears to fail, data validation code not firing when control values changed.
}
我做错了什么?
编辑: 只是在实际加载视图模型时查看了输出,我已经看到了。
System.Windows.Data Error: 40 : BindingExpression path error: 'Centres' property not found on 'object' ''Member_B31A44ECE333F4E7E07BE25FA5BDC79874BAE6C64589F9765ACA373D89BBBD6B' (HashCode=45485186)'. BindingExpression:Path=Centres; DataItem='Member_B31A44ECE333F4E7E07BE25FA5BDC79874BAE6C64589F9765ACA373D89BBBD6B' (HashCode=45485186); target element is 'ComboBox' (Name=''); target property is 'ItemsSource' (type 'IEnumerable')
System.Windows.Data Warning: 40 : BindingExpression path error: 'SelectedMember' property not found on 'object' ''Member_B31A44ECE333F4E7E07BE25FA5BDC79874BAE6C64589F9765ACA373D89BBBD6B' (HashCode=45485186)'. BindingExpression:Path=SelectedMember.LocalCentre; DataItem='Member_B31A44ECE333F4E7E07BE25FA5BDC79874BAE6C64589F9765ACA373D89BBBD6B' (HashCode=45485186); target element is 'ComboBox' (Name=''); target property is 'SelectedValue' (type 'Object')
我觉得我做了一些愚蠢的事情...但是什么?
编辑 2: 上述错误已修复,但即使显式调用 RaisePropertyChanged,即使 SelectedMember 发生更改,UI 仍然不会更新。
编辑3: 希望这是您需要的XAML:
<UserControl x:Class="Project.Views.MemberDetailView"
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:models="clr-namespace:Project.Client.Models"
mc:Ignorable="d"
d:DesignHeight="600" d:DesignWidth="800">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Assets/ResourceDictionaries/DataEntryScreens.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<WrapPanel>
<Expander Header="Personal Information">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Vertical">
<TextBlock Text="Forename:" />
<TextBox Text="{Binding SelectedMember.Forename, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
<!-- Other controls omitted. -->
</Expander>
</WrapPanel>
</UserControl>
<!--MemberDetailView.xaml.cs-->
public partial class MemberDetailView : UserControl
{
public MemberDetailView()
{
InitializeComponent();
this.DataContext = new MemberDetailViewModel();
}
}
我已经解决了这个...不知何故...
我不确定我做了什么,但显然在视图的构造函数中设置 ViewModel 设法搞砸了一切。
所以从这里开始:
public MemberDetailView()
{
InitializeComponent();
this.DataContext = new MemberDetailViewModel() { Header = "Members" };
}
对此:
public MemberDetailView()
{
InitializeComponent();
//this.DataContext = new MemberDetailViewModel() { Header = "Members" };
}
已解决问题。