我需要一个绑定到ClassA的TextBox,它显示来自ClassB中两个Object的变量的和。只有当我尝试手动编辑TextBox时,它才会更改其值。我的问题是,我不知道如何在ClassA中实现一个方法,如果ClassB中的变量发生了变化,该方法就会列出。我试图让ClassB从ClassA变成SubClass,但后来我得到了StackOverflowException,所以这不起作用。
MainWindow.xaml
<Window x:Class="INPCTest.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:INPCTest"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
<local:ClassA/>
</Window.DataContext>
<Grid x:Name="BaseGrid" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="10" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="10"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBox x:Name="TextBoxClassA" Grid.Row="1" Grid.Column="1" Text="{Binding Sum, UpdateSourceTrigger=PropertyChanged}" />
<TextBox x:Name="TextBox1ClassB" Grid.Row="2" Grid.Column="1" Text="{Binding MyClassB1.Var, UpdateSourceTrigger=PropertyChanged}" />
<TextBox x:Name="TextBox2ClassB" Grid.Row="2" Grid.Column="2" Text="{Binding MyClassB2.Var, UpdateSourceTrigger=PropertyChanged}" />
</Grid>
</Window>
ClassA.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace INPCTest
{
public class ClassA : ObservableObject
{
private decimal _sum;
public decimal Sum
{
get { _sum = MyClassB1.Var + MyClassB2.Var; return _sum; }
set { _sum = value; OnPropertyChanged();}
}
public ClassB MyClassB1 { get; set; } = new ClassB(1);
public ClassB MyClassB2 { get; set; } = new ClassB(2);
}
}
ClassB.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace INPCTest
{
public class ClassB : ObservableObject
{
private decimal _var;
public ClassB(decimal var)
{
_var = var;
}
public decimal Var
{
get { return _var; }
set { _var = value; OnPropertyChanged();}
}
}
}
ObservableObject.cs
using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace INPCTest
{
public class ObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string propertyname = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyname));
}
}
}
您可以从Action
使用。
A类:
public class ClassA : ObservableObject
{
private decimal _sum;
public ClassA()
{
MyClassB1 = new ClassB(1) {OnVarChanged = OnVarChange};
MyClassB2 = new ClassB(2) {OnVarChanged = OnVarChange};
}
public decimal Sum
{
get { _sum = MyClassB1.Var + MyClassB2.Var; return _sum; }
set { _sum = value; OnPropertyChanged(); }
}
public ClassB MyClassB1 { get; set; }
public ClassB MyClassB2 { get; set; }
private void OnVarChange() => OnPropertyChanged(nameof(Sum));
}
B类:
public class ClassB : ObservableObject
{
private decimal _var;
public ClassB(decimal var)
{
_var = var;
}
public Action OnVarChanged { get; set; }
public decimal Var
{
get { return _var; }
set
{
_var = value;
OnPropertyChanged();
OnVarChanged?.Invoke();
}
}
}
使用INotifyPropertyChanged
和WPFPropertyChangedEventManager
使ClassA
侦听其每个ClassB
对象。当任一Var
属性发生更改时,ClassA
可以为其Sum
属性引发PropertyChanged
事件。例如,您可以为类a编写一个构造函数来完成
public ClassA()
{
PropertyChangedEventManager.AddHandler(
MyClassB1,
(_,_) => OnPropertyChanged(nameof(Sum)),
nameof(ClassB.Var));
PropertyChangedEventManager.AddHandler(
MyClassB2,
(_,_) => OnPropertyChanged(nameof(Sum)),
nameof(ClassB.Var));
}
但有一个问题:您有一个ClassA.Sum
的公共setter。如果Sum
应该是每两个ClassB.Var
值的相加,那么这怎么可能起作用呢?你怎么往另一个方向走?
每次有人设置ClassA.Sum
时,你都必须以某种方式将新的Sum除以两个ClassB
,或者下次有人调用getter时,值就会变回来。
我不知道怎么办。