C# 克隆对象不会更新UI-WPF中的绑定值

C# 克隆对象不会更新UI-WPF中的绑定值,c#,wpf,C#,Wpf,我已经搜索了很多问题,但我只能找到提到的“可观察的”收藏,这不适用于我的情况 我有一个基本的WPF应用程序、一个Address类和一个简单的表单,其中包含“delivery Address”和“billing Address”,还有一个复选框,用于将del Address复制到billing Address(我通过克隆Address对象来实现)。我可以看到帐单地址属性更新为输入的递送地址,但该值不会更新回UI。我相信有更好的方法来实现这一点。到目前为止我已经 <Window x:Class

我已经搜索了很多问题,但我只能找到提到的“可观察的”收藏,这不适用于我的情况

我有一个基本的WPF应用程序、一个Address类和一个简单的表单,其中包含“delivery Address”和“billing Address”,还有一个复选框,用于将del Address复制到billing Address(我通过克隆Address对象来实现)。我可以看到帐单地址属性更新为输入的递送地址,但该值不会更新回UI。我相信有更好的方法来实现这一点。到目前为止我已经

<Window x:Class="WpfApp1.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:local="clr-namespace:WpfApp1"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <StackPanel Orientation="Vertical">
    <TextBox Text="{Binding Path=DelAddress.Line1, Mode=TwoWay}"></TextBox>
        <TextBox Text="{Binding Path=DelAddress.Line2, Mode=TwoWay}"></TextBox>
        <TextBox Text="{Binding Path=DelAddress.Line3, Mode=TwoWay}"></TextBox>

    <CheckBox Checked="CopyDelAddress"> Same as Delivery</CheckBox>
        <TextBox Text="{Binding Path=BillAddress.Line1, Mode=TwoWay}"></TextBox>
        <TextBox Text="{Binding Path=BillAddress.Line2, Mode=TwoWay}"></TextBox>
        <TextBox Text="{Binding Path=BillAddress.Line3, Mode=TwoWay}"></TextBox>
    </StackPanel>
</Grid>

和送货一样

名称空间WpfApp1{
/// 
///MainWindow.xaml的交互逻辑
/// 
公共部分类主窗口:窗口{
公共课堂演讲{
公共字符串Line1{get;set;}
公共字符串第2行{get;set;}
公共字符串第3行{get;set;}
公共广播克隆(){
返回(地址)this.MemberwiseClone();
}
}
公共地址{get;set;}
公共广播BillAddress{get;set;}
公共主窗口(){
初始化组件();
BillAddress=新地址();
DelAddress=新地址();
DataContext=this;
}
私有void CopyDelAddress(对象发送方,路由目标){
BillAddress=DelAddress.Clone();
//值被复制到BillAddress,但不显示在UI中
}
}
}

您希望UI如何知道您更改了属性的值?你从来没说过

您应该将
BillAddress
DelAddress
移动到一个viewmodel类,并将其作为您的DataContext

这个代码是C#7。如果您使用的是早期版本,请告诉我,我会将其修复为与您的编译器兼容

MainWindow.xaml.cs

public MainWindow() {
    InitializeComponent();

    DataContext = new MainViewModel();
}

public MainViewModel ViewModel => (MainViewModel)DataContext;


private void CopyDelAddress(object sender, RoutedEventArgs e) {
    ViewModel.BillAddress = ViewModel.DelAddress.Clone();

    //  Values ARE NOT copied to BillAddress. A clone of DelAddress 
    //  is assigned to BillAddress.
}
ViewModels.cs

public class MainViewModel : ViewModelBase
{
    public MainViewModel()
    {
        BillAddress = new Address();
        DelAddress = new Address();
    }

    private Address _billAddress = null;
    public Address BillAddress
    {
        get { return _billAddress; }
        set
        {
            if (value != _billAddress)
            {
                _billAddress = value;
                OnPropertyChanged();
            }
        }
    }

    private Address _delAddress = null;
    public Address DelAddress
    {
        get { return _delAddress; }
        set
        {
            if (value != _delAddress)
            {
                _delAddress = value;
                OnPropertyChanged();
            }
        }
    }
}

public class ViewModelBase : INotifyPropertyChanged
{
    #region INotifyPropertyChanged
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propName = null) =>
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
    #endregion INotifyPropertyChanged
}

BillAddress属性更改时,不会触发更改通知事件。实现INotifyPropertyChanged或使BillAddress成为依赖项属性。您必须将类设置为继承INotifyPropertyChanged,这将告诉UI对象的属性已更改。您缺少一些使数据绑定工作所需的内容。我建议在谷歌上搜索数据绑定,并找到一个可以修改的简单示例。感谢您为我指明了正确的方向,切换到具有上述代码的视图模型正是我想要的。向失败的选民大声呼喊!
public class MainViewModel : ViewModelBase
{
    public MainViewModel()
    {
        BillAddress = new Address();
        DelAddress = new Address();
    }

    private Address _billAddress = null;
    public Address BillAddress
    {
        get { return _billAddress; }
        set
        {
            if (value != _billAddress)
            {
                _billAddress = value;
                OnPropertyChanged();
            }
        }
    }

    private Address _delAddress = null;
    public Address DelAddress
    {
        get { return _delAddress; }
        set
        {
            if (value != _delAddress)
            {
                _delAddress = value;
                OnPropertyChanged();
            }
        }
    }
}

public class ViewModelBase : INotifyPropertyChanged
{
    #region INotifyPropertyChanged
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propName = null) =>
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
    #endregion INotifyPropertyChanged
}