Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 属性更改时不会反映MVVMLight Toolkit更改_C#_Wpf_Data Binding_Mvvm Light_Inotifypropertychanged - Fatal编程技术网

C# 属性更改时不会反映MVVMLight Toolkit更改

C# 属性更改时不会反映MVVMLight Toolkit更改,c#,wpf,data-binding,mvvm-light,inotifypropertychanged,C#,Wpf,Data Binding,Mvvm Light,Inotifypropertychanged,我正在我的WPF项目中使用。我所有的ViewModel都源自工具箱的ViewModelBase类,它为您实现了INotifyPropertyChanged,并完成所有通知工作 我目前的设置非常简单。我有一个Person类,它有一个名称属性 public class Person { public string Name { get; set; } } 我的窗口有一个TextBlock和一个按钮,我将我拥有的Person类对象的Name属性绑定到TextBlockDataContext是

我正在我的
WPF
项目中使用。我所有的
ViewModel
都源自工具箱的
ViewModelBase
类,它为您实现了
INotifyPropertyChanged
,并完成所有通知工作

我目前的设置非常简单。我有一个
Person
类,它有一个
名称
属性

public class Person
{
    public string Name { get; set; }
}
我的窗口有一个
TextBlock
和一个
按钮
,我将我拥有的
Person
类对象的
Name
属性绑定到
TextBlock
DataContext
是使用
ViewModelLocator
类设置的

<Window x:Class="BindingTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:ignore="http://www.galasoft.ch/ignore"
        mc:Ignorable="d ignore"
        Height="300" Width="300"
        Title="MVVM Light Application"
        DataContext="{Binding Main, Source={StaticResource Locator}}">
    <Grid x:Name="LayoutRoot">
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <TextBlock Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center"
                   Text="{Binding Contact.Name}"/>
        <Button Grid.Row="1" Content="Click" Command="{Binding ClickCommand}"/>
    </Grid>
</Window>

我缺少什么?

设置
联系人。姓名
不会触发
INotifyPropertyChanged.NotifyChanged
事件,因为未执行联系人设置程序。您可以使用以下技术之一修复此问题:

在模型类中也实现InotifyProperty更改

public class Person : INotifyPropertyChanged
{
    private string _name;

    public string Name 
    { 
       get => _name; 
       set
       {
           _name = value;
           if (PropertyChanged != null)
               PropertyChanged(this, nameof(Name)); 
       }
    }

    public event PropertyChangedHandler PropertyChanged;
}
或将PersonClass包装在PersonViewModel中

public class PersonViewModel : ViewModelBase
{
    private readonly Person _person;

    public PersonViewModel(Person person)
    {
        _person = person;
    }

    public string Name 
    { 
       get => _person.Name; 
       set
       {
            var name = _person.Name;
            if (Set(ref name, value))
                _person.Name = name;
       }
    }
}
在MainViewModel中:

private PersonViewModel _contactViewModel
public PersonViewModel Contact
{
    get { return _contactViewModel ?? (_contactViewModel = new PersonViewModel(_contact)); }
}
或在MainViewModel中创建单独的ContactName属性

public class PersonViewModel : ViewModelBase
{
    private readonly Person _person;

    public PersonViewModel(Person person)
    {
        _person = person;
    }

    public string Name 
    { 
       get => _person.Name; 
       set
       {
            var name = _person.Name;
            if (Set(ref name, value))
                _person.Name = name;
       }
    }
}
。。。并在绑定和单击事件处理程序中使用
ContactName
而不是
Contact.Name

public string ContactName
{
    get { return _contact.Name; }
    set 
    {
        var name = _contact.Name;
        if (Set(ref name, value))
            _contact.Name = name;
    }
}

是的,我知道您可以在模型中实现
INotifyPropertyChanged
,但希望我不必这样做,因为我拥有的不仅仅是几个属性。另外,用这些垃圾来污染模型似乎是一种不好的做法。我本想使用第二种方法,但它仍然不能更新GUI。在第二种方法中,问题是设置
Contact.Name
甚至不能调用setter,所以
ContactName
中的setter永远不会被调用。是的,您必须更改单击处理程序top以设置ContactName,但这完全消除了使用
Contact
属性的需要,但我需要它用于显示数据以外的其他用途。但是谢谢你把事情弄清楚。