作为一名程序员新手,我正在尝试使用XAML和C#测试数据绑定。我有两个绑定到属性的滑块,我希望使用滑块设置的两个属性值之和来更新TextBox。
我正在使用INotifyPropertyChanged
并尝试更改我能找到的每个属性,但直到编辑文本框时才能更新文本框,此时,文本框将更新为正确的值。使用UpdateSourceTrigger=PropertyChanged
只会在编辑文本框时更新文本框,而不会在选择另一个元素时更新。我曾尝试编写一个单独的事件处理程序,该处理程序不我不使用[CallerNameMember]
,而是使用一个指定属性,但它似乎没有改变任何东西。
<Grid>
<Grid.RowDefinitions>
</Grid.RowDefinitions>
<TextBox Grid.Row="0"
Text="{Binding BoundNumber, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
FontSize="20"
FontWeight="Bold"
AllowDrop="False" />
<Slider Grid.Row="1"
Value="{Binding BoundNumber, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Maximum="100"
Minimum="10"
IsSnapToTickEnabled="True"
TickFrequency="10" />
<TextBox Grid.Row="2"
Text="{Binding BoundNumber2, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
AllowDrop="False" />
<Slider Grid.Row="3"
Value="{Binding BoundNumber2, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Maximum="100"
Minimum="10"
IsSnapToTickEnabled="True"
TickFrequency="10" />
<TextBox Grid.Row="4"
Name="MathBox"
Text="{Binding QuickMath, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}">
</TextBox>
</Grid>
public partial class OrderScreen : INotifyPropertyChanged
{
public OrderScreen()
{
DataContext = this;
InitializeComponent();
}
private int quickMath;
public int QuickMath
{
get { return _boundNumber + _boundNumber2; }
set
{
if (value != quickMath)
{
quickMath = value;
OnPropertyChanged();
}
}
}
private int _boundNumber;
public int BoundNumber
{
get { return _boundNumber; }
set
{
if (_boundNumber != value)
{
_boundNumber = value;
// MathBox.Text = quickMath.ToString();
OnPropertyChanged();
}
}
}
private int _boundNumber2;
public int BoundNumber2
{
get { return _boundNumber2; }
set
{
if (_boundNumber2 != value)
{
_boundNumber2 = value;
MathBox.Text = quickMath.ToString();
OnPropertyChanged();
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
我可以让它与注解掉的MathBox.Text = quickMath.ToString();
一起工作,但我希望有一个更好的方法来与数据绑定一起工作。期待中的感谢!
3条答案
按热度按时间ijxebb2r1#
绑定机制订阅
DataSource
对象的PropertyChanged
事件,因此不需要将该事件与INPC
实现沿着“初始化”,但正如您可能已经注意到的,当BoundNumber
或BoundNumber2
发生更改时,QuickMath
属性的PropertyChanged
事件确实从未触发。您可以用不同的方式修复它,例如,为所有受影响的属性显式调用OnPropertyChanged:
请注意,这种方法可以使
QuickMath
属性保持只读。这种方法在其他情况下也能很好地工作,比如与时间相关的属性,比如说,如果数据源属性根据记录的时间戳和当前时间将字符串格式化为 “Edited 2 minutes ago”,并且将PropertyChanged
作为定时任务调用。或者,您可以更新
QuickMath
沿着修改BoundNumber
和BoundNumber2
,以触发QuickMath
setter中的OnPropertyChanged()
调用:如果
QuickMath
中的逻辑不允许将其设为只读属性,则这是有意义的。在这种情况下,您必须相应地调整getter,并在那里使用private或protected setter,以避免数据不一致和意外行为。在这两种情况下,都不需要双向绑定到
QuickMath
:顺便提一下,看看代码的其余部分,确实值得一提的是,绑定机制应该将UI与数据隔离,其中XAML知道数据源对象的属性(名称和类型),但不知道它的内部实现,而数据源对象可能根本不知道XAML。
1.数据对象不应调用
FrameworkElement
,如MathBox.Text
1.将数据对象类与页面或控件类完全分开被认为是一种好的设计。
希望这对你有帮助。
nnt7mjpx2#
你还没有初始化你的
PropertyChanged
事件,所以它永远不会被调用。声明并初始化它,如下所示:public event PropertyChangedEventHandler PropertyChanged = delegate { };
w8rqjzmb3#
绑定到计算属性
QuickMath
的TextBox应接收来自它的PropertyChanged
事件,以便更新字段中的文本。尽管OrderScreen
实现了INotifyPropertyChanged
接口,但当QuickMath
更改时,它不会引发该事件,因为它的setter(事件引发的位置)。您可以修复它,例如,按照其他答案中的建议从独立属性setter中调用QuickMath setter,或者将其委托给DependenciesTracking lib: