WPF:双向数据绑定不工作

本文关键字:工作 数据绑定 WPF | 更新日期: 2023-09-27 18:08:16

我发现了一些类似的问题,但这些并不是我所需要的。我想绑定stackpanel"IsEnabled"值bool !我的物品的价值。这是我的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));
        }
    }
    ...
}

和我的ViewModel:

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);
    }
}

StopThreadCommand:

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, stackpanel必须被禁用,但UI不更新。请帮助!

WPF:双向数据绑定不工作

Binding的默认属性为Path,是DataContext的一个属性/子属性的路径。它不是一个任意的c#表达式。所以你将Binding.Path设置为"!IsInterrupted"!IsInterrupted不会求值为IsInterrupted的布尔逆;它不等于任何值。它将在调试输出流中为您提供以下内容:

System.Windows。BindingExpression路径错误:'!在'object' '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设置IsEnabledFalse,如果IsInterrupted为真。