[英]WPF: two way data binding is not working
我發現了一些類似的問題,但這些並不是我所需要的。 我想將堆棧面板“IsEnabled”值綁定到我的項目的布爾值“!IsIterrupted”。 這是我的 XAML 文件:
<ListView ItemsSource="{Binding Path=Items}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel IsEnabled="{Binding !IsInterrupted, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}">
<Button Command="{Binding Path=StopThreadCommand, Source={StaticResource viewModel}}" CommandParameter="{Binding Id}"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
這是項目的樣子:
public class ThreadDecorator : BaseThread , INotifyPropertyChanged
{
...
public event PropertyChangedEventHandler PropertyChanged;
private bool _is_interrupted;
public bool IsInterrupted
{
get { return _is_interrupted; }
set
{
_is_interrupted = value;
OnPropertyChanged("IsInterrupted");
}
}
protected virtual void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
...
}
還有我的視圖模型:
public class ThreadsViewModel : DependencyObject
{
private ThreadsModel _model;
public ThreadsModel Model
{
get { return _model; }
set
{
_model = value;
}
}
public ICollectionView Items
{
get { return (ICollectionView)GetValue(ItemsProperty); }
set { SetValue(ItemsProperty, value); }
}
public static readonly DependencyProperty ItemsProperty =
DependencyProperty.Register("Items", typeof(ICollectionView), typeof(ThreadsViewModel), new PropertyMetadata(null));
public StopThreadCommand StopThreadCommand { get; set; }
public ThreadsViewModel()
{
this.Model = new ThreadsModel();
Items = CollectionViewSource.GetDefaultView(Model.Threads);
this.StopThreadCommand = new StopThreadCommand(this);
}
public void InterruptThread(int id)
{
_model.InterruptThread(id);
}
}
停止線程命令:
public class StopThreadCommand : ICommand
{
public ThreadsViewModel ViewModel {get; set;}
public StopThreadCommand(ThreadsViewModel viewModel)
{
this.ViewModel = viewModel;
}
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
this.ViewModel.InterruptThread((int)parameter);
}
}
當我單擊“停止”按鈕時,IsInterrupted 值從 false 變為 true,並且必須禁用堆棧面板,但 UI 不會更新。 請幫忙!
Binding
的默認屬性是Path
,它是DataContext
的屬性/子屬性的路徑。 它不是任意的 C# 表達式。 所以你將Binding.Path
設置為"!IsInterrupted"
。 !IsInterrupted
不會計算為IsInterrupted
的布爾逆; 它不會評估任何東西。 它會在調試輸出流中為您提供:
System.Windows.Data 錯誤:40:BindingExpression 路徑錯誤:在“對象”“ThreadDecorator”上找不到“!IsInterrupted”屬性等等
<StackPanel
IsEnabled="{Binding !IsInterrupted, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}">
一種方法是編寫一個布爾值-逆值轉換器(從該鏈接另一端的 Chris Nicol 的回答中逐字竊取):
[ValueConversion(typeof(bool), typeof(bool))]
public class InverseBooleanConverter: IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
if (targetType != typeof(bool))
throw new InvalidOperationException("The target must be a boolean");
return !(bool)value;
}
public object ConvertBack(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
throw new NotSupportedException();
}
#endregion
}
用法:
<UserControl.Resources>
<local:InverseBooleanConverter x:Key="InverseBooleanConverter" />
</UserControl.Resources>
<!-- stuff etc. -->
IsEnabled="{Binding Path=IsReadOnly, Converter={StaticResource InverseBooleanConverter}}"
您還可以編寫帶有DataTrigger
的 Style,如果IsInterrupted
為 true,則將IsEnabled
設置為False
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.