我搜索过很多问题,但我只能找到不适用于我情况的“可观察”收藏品。
我有一个基本的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
}
}
}
答案 0 :(得分:1)
您如何期望UI知道您更改了该属性的值?你从来没有说过。
您应该将BillAddress
和DelAddress
移动到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
}