WPF 中 ToggleButton 的 IsChecked 属性的 OneWay 绑定
我有一个 ToggleButton
,其 IsChecked
属性使用 OneWay 绑定绑定到一个属性。
<ToggleButton
Command="{Binding Path=SomeCommand}"
IsChecked="{Binding Path=SomeProperty, Mode=OneWay}" />
SomeCommand
切换布尔 SomeProperty
值,并为 SomeProperty
引发 PropertyChanged
事件。
如果我在视图模型中更改 SomeProperty
,则 ToggleButton
会正确按下。但是,如果我单击 ToggleButton
,绑定似乎会丢失,并且不再根据 SomeProperty
的值检查按钮。关于如何解决这个问题有什么想法吗?
I have a ToggleButton
with its IsChecked
property bound to a property using a OneWay binding.
<ToggleButton
Command="{Binding Path=SomeCommand}"
IsChecked="{Binding Path=SomeProperty, Mode=OneWay}" />
The SomeCommand
toggles the boolean SomeProperty
value, and a PropertyChanged
event is raised for SomeProperty
.
If I change SomeProperty
in my viewmodel the ToggleButton
depresses correctly. However if I click the ToggleButton
the binding seems to get lost and the button no longer gets checked according to the value of SomeProperty
. Any ideas on how to fix this problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
有一种简单而优雅的方法可以解决原始海报的问题 - 将 ToggleButton 的 IsChecked 属性替换为可附加属性,该属性将在其更改处理程序中设置按钮的 IsChecked:
XAML 然后将如下所示:
编辑:OP 解决方案不工作,因为当按下按钮时,IsChecked 属性会在代码中设置(这是 MS 实现 ToggleButton 控件的方式) - 设置该属性会从中删除绑定,因此它会停止工作。
通过使用附加属性,我们可以克服这个问题,因为它永远不会在代码中分配值,因此绑定保持不变。
There is a simple and elegant way to solve the original poster's problem - replacing IsChecked property of the ToggleButton with an attachable property that will set IsChecked of the button in its change handler:
XAML then will look like this:
EDIT: The OP solution does not work, because when the button is pressed the IsChecked property is set in the code (this is the way MS implemented ToggleButton control) - setting the property removes the binding from it and so it stops working.
By using attached property we can overcome this problem because it is never assigned a value in code and so the bindings stays intact.
这是使用单向数据绑定时设计的。将附加属性PresentationTraceSources.TraceLevel=High 添加到您的绑定中,您将看到它何时断开连接。此链接也描述了该问题(未提供任何解决方案): 在 WPF 中调试数据绑定
我通常解决此问题的方法是使用用户交互命令和隐藏代码来更改控件外观,因为某些属性已更改。
This is by design when using oneway data binding. Add the attached property PresentationTraceSources.TraceLevel=High to your binding and you will see when it gets disconnected. This link describes the problem as well (without offering any solution): Debugging Data Binding in WPF
The way I normally solve it is to use a command for user interaction and code behind to change the control appearance because of some changed properties.
据我所知,Sinatr 关于发生的“不同步”是正确的,至少在较新的框架中是这样。
解决该问题的另一种简单方法是删除 mode=oneway 并实现一个空设置器。例如:
通过此绑定设置,您可以从命令绑定函数更改支持变量的值,或者是否需要更改。只需记住调用 RaisePropertyChanged 即可。
To my knowledge Sinatr is correct regarding the 'desync' that occurs, at least in newer frameworks.
Another simple way around the issue is to remove the mode=oneway and implement an empty setter. Ex:
With this binding setup you can you change the value of the backing variable from your command binding function, or from whether you need to. Just remember to call RaisePropertyChanged.
我有类似的问题。
它不是“绑定似乎丢失了”(除非是早期的框架问题)。绑定继续工作,并且可以通过更改该命令之外的属性(例如在另一个按钮单击事件/命令的处理程序中)轻松证明。
问题是
IsChecked
可以通过两种方式更改:1)绑定(当SomeProperty
的值更改时按钮将更新 2)用户(如果用户按下按钮,他将更新更改IsChecked
,但绑定是OneWay
,因此SomeProperty
将不会更新)。因此,当
SomeProperty == false
但按钮IsChecked == true
时,可能会发生不同步,反之亦然。优化性能绑定机制是检查新值是否与当前值不同。因此,如果发生不同步并且您尝试使用已有的值更新
SomeProperty
,那么什么也不会发生。解决方法很简单:分两步更新属性
,其中
set
是您需要的值(例如与当前SomeProperty
相反)。I have similar problem.
It is not "the binding seems to get lost" (unless it's earlier frameworks problems). Binding continues working and can be easily proved by changing property outside of that command (e.g. in handler of another button click event/command).
The problem is what
IsChecked
can be changed in two ways: 1) binding (when value ofSomeProperty
is changed button will be updated 2) user (if user press button he will changeIsChecked
, but binding isOneWay
soSomeProperty
will not be updated).So you may have desync occurs when
SomeProperty == false
but buttonIsChecked == true
or vice-versa.To optimize performance binding mechanism is checking if new value is different from current. So if desync occurs and you try to update
SomeProperty
with the value which it already have, then nothing will happens.Workaround is simple: update property in 2 steps
where
set
is the value you need (e.g. opposite to currentSomeProperty
).我认为问题归结为命令和 IsChecked 绑定之间的冲突。我的解决方案是更改视图模型以公开
bool?
并将其绑定到IsChecked
属性。我没有将命令绑定到 ToggleButton。在我的代码中想要切换属性的其他地方,我使用SomeCommand
。I think what the problem boils down to is a conflict between the command and the
IsChecked
binding. My solution was to change my viewmodel to expose abool?
and bind that to theIsChecked
property. I did not bind a command to theToggleButton
. Elsewhere in my code where I want to toggle the property I useSomeCommand
.