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