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

时间:2017-12-05 14:18:42

标签: c# wpf

我搜索过很多问题,但我只能找到不适用于我情况的“可观察”收藏品。

我有一个基本的WPF应用程序,一个Address类和一个简单的表单,其中包含“交付地址”和“帐单地址”以及一个复选框,用于将del地址复制到帐单地址(我通过克隆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>

namespace WpfApp1 {
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window {

    public class Address {
        public string Line1 { get; set; }
        public string Line2 { get; set; }
        public string Line3 { get; set; }
        public Address Clone() {
            return (Address)this.MemberwiseClone();
        }
    }
    public Address DelAddress { get; set; }
    public Address BillAddress { get; set; }
    public MainWindow() {
        InitializeComponent();

        BillAddress = new Address();
        DelAddress = new Address();

        DataContext = this;
    }

    private void CopyDelAddress(object sender, RoutedEventArgs e) {
        BillAddress = DelAddress.Clone();
    // Values are copied to BillAddress but don't appear in the UI
    }
}
}

1 个答案:

答案 0 :(得分:1)

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

您应该将BillAddressDelAddress移动到implements INotifyPropertyChanged的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
}