簡體   English   中英

在WPF中對ToggleButton的IsChecked屬性進行OneWay綁定

[英]OneWay binding for ToggleButton's IsChecked property in WPF

我有一個ToggleButton ,其IsChecked屬性使用OneWay綁定綁定到屬性。

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

SomeCommand切換布爾SomeProperty值和PropertyChanged事件引發的SomeProperty

如果我在viewmodel中更改SomeProperty ,則ToggleButton正確壓下。 但是,如果我單擊ToggleButton ,綁定似乎會丟失,並且不再根據SomeProperty的值檢查按鈕。 關於如何解決這個問題的任何想法?

有一種簡單而優雅的方法來解決原始海報的問題 - 將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控件的方式) - 設置屬性將從中刪除綁定,因此它停止工作。

通過使用附加屬性,我們可以克服這個問題,因為它從未在代碼中賦值,因此綁定保持不變。

這是設計時使用單向數據綁定。 將附加屬性PresentationTraceSources.TraceLevel = High添加到綁定中,您將看到它何時斷開連接。 此鏈接也描述了該問題(未提供任何解決方案): 在WPF中調試數據綁定

我通常解決它的方法是使用命令進行用戶交互和代碼隱藏,以更改控件外觀,因為一些更改的屬性。

我有類似的問題。

不是 “綁定似乎迷失” (除非它早期的框架問題)。 綁定繼續工作,可以通過更改該命令之外的屬性(例如,在另一個按鈕單擊事件/命令的處理程序中)輕松證明。

問題是IsChecked可以通過兩種方式進行更改:1)綁定(當SomeProperty值更改時按鈕將更新2)用戶(如果用戶按下按鈕他將更改IsChecked ,但綁定是OneWay因此SomeProperty不會更新) 。

所以,你可能有不同步時出現SomeProperty == false ,但按鍵IsChecked == true或反之亦然。

優化性能綁定機制是檢查新值是否與當前值不同。 因此,如果發生了desync並且您嘗試使用已有的值更新SomeProperty ,則不會發生任何事情。

解決方法很簡單:分兩步更新屬性

SomeProperty = !set;
SomeProperty = set;

其中set是您需要的值(例如,與當前SomeProperty相反)。

我認為問題歸結為命令和IsChecked綁定之間的沖突。 我的解決方案是更改我的viewmodel以暴露bool? 並將其綁定到IsChecked屬性。 我沒有將命令綁定到ToggleButton 在我的代碼中,我想切換屬性,我使用SomeCommand

據我所知,Sinatr對於發生的'desync'是正確的,至少在較新的框架中是這樣。

解決這個問題的另一個簡單方法是刪除mode = oneway並實現一個空的setter。 例如:

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

使用此綁定設置,您可以從命令綁定功能或您是否需要更改后備變量的值。 只記得調用RaisePropertyChanged。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM