我有一个ToggleButton
,其IsChecked
属性使用OneWay绑定绑定到属性。
<ToggleButton
Command="{Binding Path=SomeCommand}"
IsChecked="{Binding Path=SomeProperty, Mode=OneWay}" />
SomeCommand
切换布尔SomeProperty
值,并为PropertyChanged
引发SomeProperty
事件。
如果我在视图模型中更改SomeProperty
,则ToggleButton
会正确按下。但是,如果我单击ToggleButton
,绑定似乎会丢失,并且不再根据SomeProperty
的值检查按钮。关于如何解决这个问题的任何想法?
答案 0 :(得分:11)
有一种简单而优雅的方法来解决原始海报的问题 - 将ToggleButton的IsChecked属性替换为可附加属性,该属性将在其更改处理程序中设置按钮的IsChecked:
namespace TBFix
{
public class TBExtender
{
public static readonly DependencyProperty IsCheckedProperty =
DependencyProperty.RegisterAttached("IsChecked",
typeof(bool),
typeof(TBExtender),
new PropertyMetadata(OnChanged));
public static bool GetIsChecked(DependencyObject obj)
{
return (bool)obj.GetValue(IsCheckedProperty);
}
public static void SetIsChecked(DependencyObject obj, bool value)
{
obj.SetValue(IsCheckedProperty, value);
}
private static void OnChanged(DependencyObject o,
DependencyPropertyChangedEventArgs args)
{
ToggleButton tb = o as ToggleButton;
if (null != tb)
tb.IsChecked = (bool)args.NewValue;
}
}
}
然后XAML将如下所示:
<ToggleButton Command="{Binding Path=SomeCommand}"
TBFix:TBExtender.IsChecked="{Binding Path=SomeProperty,
Mode=OneWay}" />
编辑:OP解决方案不起作用,因为当按下按钮时,IsChecked属性在代码中设置(这是MS实现ToggleButton控件的方式) - 设置属性会从中删除绑定,因此它停止工作
通过使用附加属性,我们可以克服这个问题,因为它从未在代码中赋值,因此绑定保持不变。
答案 1 :(得分:5)
这是设计时使用单向数据绑定。将附加属性PresentationTraceSources.TraceLevel = High添加到绑定中,您将看到它何时断开连接。此链接也描述了该问题(未提供任何解决方案):Debugging Data Binding in WPF
我通常解决的方法是使用命令进行用户交互,然后使用代码更改控件外观,因为某些更改的属性。
答案 2 :(得分:1)
我有类似的问题。
不 “绑定似乎迷失”(除非是早期的框架问题)。绑定继续工作,可以通过更改该命令之外的属性轻松证明(例如,在另一个按钮单击事件/命令的处理程序中)。
问题在于IsChecked
可以通过两种方式进行更改:1)绑定(当SomeProperty
的值被更改时,按钮将被更新2)用户(如果用户按下按钮,他将更改{{ 1}},但绑定为IsChecked
,因此OneWay
不会更新。
因此,SomeProperty
可能会发生 desync ,但会按SomeProperty == false
,反之亦然。
优化性能绑定机制是检查新值是否与当前值不同。因此,如果发生了异步,并且您尝试使用已有的值更新IsChecked == true
,则不会发生任何事情。
解决方法很简单:分两步更新属性
SomeProperty
其中SomeProperty = !set;
SomeProperty = set;
是您需要的值(例如,与当前set
相反)。
答案 3 :(得分:0)
我认为问题归结为命令与IsChecked
绑定之间的冲突。我的解决方案是更改我的viewmodel以公开bool?
并将其绑定到IsChecked
属性。我没有将命令绑定到ToggleButton
。在我的代码中,我要切换属性,我使用SomeCommand
。
答案 4 :(得分:0)
据我所知,Sinatr对于&#39; desync&#39;是正确的。这种情况至少在较新的框架中发生。
解决这个问题的另一个简单方法是删除mode = oneway并实现一个空的setter。例如:
bool _MyIsEnabled;
public bool MyIsEnabled
{
get { return _MyIsEnabled; }
set { }
}
使用此绑定设置,您可以从命令绑定功能更改支持变量的值,或者从是否需要更改。只记得调用RaisePropertyChanged。