![](/img/trans.png)
[英]Why could not do OneWay binding to ToggleButton IsChecked property?
[英]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.