10

我有一个使用 OneWay 绑定将ToggleButtonIsChecked属性绑定到属性的属性。

<ToggleButton
    Command="{Binding Path=SomeCommand}"
    IsChecked="{Binding Path=SomeProperty, Mode=OneWay}" />

SomeCommand切换布尔SomeProperty值,并引发PropertyChanged事件SomeProperty

如果我改变SomeProperty我的视图模型,ToggleButton就会正确地按下。但是,如果我单击ToggleButton绑定似乎丢失并且按钮不再根据SomeProperty. 关于如何解决这个问题的任何想法?

4

5 回答 5

13

有一种简单而优雅的方法可以解决原始海报的问题 - 将 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 控件的方式) - 设置属性会从中删除绑定,因此它停止工作。

通过使用附加属性,我们可以克服这个问题,因为它从来没有在代码中赋值,所以绑定保持不变。

于 2011-04-28T17:21:17.293 回答
7

这是使用单向数据绑定时的设计。将附加属性 PresentationTraceSources.TraceLevel=High 添加到您的绑定中,您将看到它何时断开连接。此链接也描述了该问题(不提供任何解决方案):Debugging Data Binding in WPF

我通常解决它的方法是使用用户交互的命令和代码来更改控件外观,因为一些更改的属性。

于 2010-09-22T18:12:14.473 回答
2

据我所知,Sinatr 关于发生的“不同步”是正确的,至少在较新的框架中是这样。

解决此问题的另一种简单方法是删除 mode=oneway 并实现一个空设置器。前任:

    bool _MyIsEnabled;
    public bool MyIsEnabled
    {
        get { return _MyIsEnabled; }
        set { }
    }

使用此绑定设置,您可以从命令绑定函数或是否需要更改支持变量的值。只要记住调用 RaisePropertyChanged。

于 2018-01-26T15:55:33.060 回答
1

我有类似的问题。

不是 “绑定似乎丢失了”(除非它是早期的框架问题)。绑定继续工作,并且可以通过更改该命令之外的属性轻松证明(例如,在另一个按钮单击事件/命令的处理程序中)。

问题是IsChecked可以通过两种方式进行更改:1)绑定(SomeProperty更改按钮的值时将更新 2)用户(如果用户按下按钮,他将更改,但IsChecked绑定不会更新)。OneWaySomeProperty

所以你可能会在按钮时发生不同步,反之亦然。SomeProperty == falseIsChecked == true

优化性能绑定机制是检查新值是否与当前值不同。因此,如果发生异步并且您尝试SomeProperty使用它已经拥有的值进行更新,那么什么都不会发生。

解决方法很简单:分两步更新属性

SomeProperty = !set;
SomeProperty = set;

set您需要的值在哪里(例如与 current 相反SomeProperty)。

于 2016-02-05T11:02:45.697 回答
0

我认为问题归结为命令和IsChecked绑定之间的冲突。我的解决方案是更改我的视图模型以公开 abool?并将其绑定到IsChecked属性。我没有将命令绑定到ToggleButton. 在我想要切换我使用的属性的代码中的其他地方SomeCommand

于 2010-09-22T18:13:37.710 回答