c# – WPF:TwoWay绑定始终更新 – OneWay绑定仅在ONCE上更新
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# – WPF:TwoWay绑定始终更新 – OneWay绑定仅在ONCE上更新,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4666字,纯文字阅读大概需要7分钟。
内容图文
![c# – WPF:TwoWay绑定始终更新 – OneWay绑定仅在ONCE上更新](/upload/InfoBanner/zyjiaocheng/811/98527b65d6fe4b739a06af40c990f03a.jpg)
我知道你的想法:2017年,请不要再提出这个,但我真的找不到任何有价值的解释.
请查看此XAML代码中的ActiveNotes属性.
我在我的XAML中有这个TwoWay绑定,它完美地运行.如果触发了ScaleNotes的PropertyChanged事件并且绑定设置为TwoWay,则它始终更新.
<c:Keyboard
Grid.Row="2"
Grid.Column="0"
PlayCommand="{Binding PlayCommand}"
StopCommand="{Binding StopCommand}"
ActiveNotes="{Binding ScaleNotes, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
ViewModel中的ScaleNotes属性如下所示.每当它发生变化时,都会保证触发PropertyChanged事件.我检查并仔细检查了一下. ViewModel中的业务逻辑有效.
private ReadOnlyCollection<eNote> _ScaleNotes;
public ReadOnlyCollection<eNote> ScaleNotes
{
get { return _ScaleNotes; }
set { SetField(ref _ScaleNotes, value); }
}
[DebuggerStepThrough]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
[DebuggerStepThrough]
protected bool SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
field = value;
OnPropertyChanged(propertyName);
return true;
}
到这里一切都很好.每当更改VM中的ScaleNotes属性时,都会更新目标属性ActiveNotes.
现在的问题是:
如果我只将XAML中的绑定更改为OneWay并且VM中的业务逻辑保持100%相同,则即使触发了PropertyChanged事件,目标对象中的ActivesNotes属性也只更新一次.我检查并仔细检查了一下.始终触发ScaleNotes属性的PropertyChanged事件.
<c:Keyboard
Grid.Row="2"
Grid.Column="0"
PlayCommand="{Binding PlayCommand}"
StopCommand="{Binding StopCommand}"
ActiveNotes="{Binding ScaleNotes, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/>
只是为了完成这个,这里是目标对象中的DP.
public static DependencyProperty ActiveNotesProperty = DependencyProperty.Register(
"ActiveNotes",
typeof(ReadOnlyCollection<eNote>),
typeof(Keyboard),
new PropertyMetadata(OnActiveNotesChanged));
public ReadOnlyCollection<eNote> ActiveNotes
{
get
{
return (ReadOnlyCollection<eNote>)GetValue(ActiveNotesProperty);
}
set
{
SetValue(ActiveNotesProperty, value);
}
}
private static void OnActiveNotesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Keyboard keyboard = (Keyboard)d;
keyboard.ActiveNotes = (ReadOnlyCollection<eNote>)e.NewValue;
if ((keyboard.ActiveNotes != null) && (keyboard.ActiveNotes.Count > 0))
{
keyboard.AllKeys.ForEach(k => { if ( k.Note != eNote.Undefined) k.IsActiveKey = true; });
keyboard.AllKeys.ForEach(k => { if ((k.Note != eNote.Undefined) && (!keyboard.ActiveNotes.Contains(k.Note))) k.IsActiveKey = false; });
}
else
{
keyboard.AllKeys.ForEach(k => { if (k.Note != eNote.Undefined) k.IsActiveKey = true; });
}
}
我不明白这一点.据我所知,OneWay和TwoWay只定义值更新的方向,而不是更新它们的频率.
我无法理解,一切都运行良好的TwoWay,业务逻辑保持100%相同,OneWay是一个交易破坏者.
如果你问自己,为什么我想知道这个:这个绑定计划为OneWay绑定.以任何方式更新源都没有意义.我只将它改为TwoWay,因为OneWay没有按预期工作.
在@MikeStrobel的帮助下解决方案:(见评论)
代码需要以这种方式更改:
private static void OnActiveNotesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Keyboard keyboard = (Keyboard)d;
//THIS LINE BREAKED THE CODE, WHEN USING OneWay binding BUT NOT WITH TwoWay binding
//keyboard.ActiveNotes = (ReadOnlyCollection<eNote>)e.NewValue;
if ((keyboard.ActiveNotes != null) && (keyboard.ActiveNotes.Count > 0))
{
keyboard.AllKeys.ForEach(k => { if ( k.Note != eNote.Undefined) k.IsActiveKey = true; });
keyboard.AllKeys.ForEach(k => { if ((k.Note != eNote.Undefined) && (!keyboard.ActiveNotes.Contains(k.Note))) k.IsActiveKey = false; });
}
else
{
keyboard.AllKeys.ForEach(k => { if (k.Note != eNote.Undefined) k.IsActiveKey = true; });
}
}
使用OneWay绑定,OnActiveNotesChanged事件处理程序方法中的赋值将删除或清除绑定.迈克是正确的说,这种分配是完全没必要的,因为在这个时间点,价值已经在物业中设定.因此,无论我使用OneWay还是TwoWay绑定,它都毫无意义.
解决方法:
依赖项属性具有precedence的复杂系统.任何给定时间的依赖项属性的值可能来自各种来源:绑定,样式设置器,触发器设置器等.本地值具有最高优先级,并且当您设置本地值时,你压制来自其他来源的价值.
在绑定的情况下,设置本地值将导致*删除源到目标绑定(OneWay或OneTime)*.但是,当您使用目标到源绑定(TwoWay或OneWayToSource)在属性上设置本地值时,将保持绑定,并且您指定的本地值将传播回源.
在您的情况下,问题出在这里:
keyboard.ActiveNotes = (ReadOnlyCollection<eNote>)e.NewValue;
在OnActiveNotesChanged处理程序中,您将为ActiveNotes分配一个新的本地值,这会导致您的OneWay绑定被删除.幸运的是,解决方案很简单:您可以完全删除此行,因为它是多余的.在大多数情况下,不必在自己的更改处理程序中分配依赖项属性 – 已经应用了新值. (如果您希望有机会在应用之前替换建议值,那么执行此操作的位置将是CoerceValueCallback,您也可以在PropertyMetadata中指定.)
内容总结
以上是互联网集市为您收集整理的c# – WPF:TwoWay绑定始终更新 – OneWay绑定仅在ONCE上更新全部内容,希望文章能够帮你解决c# – WPF:TwoWay绑定始终更新 – OneWay绑定仅在ONCE上更新所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。