1

My WPF-Application contains a DataGrid with 3 Columns and a disabled Button. One Column of my DataGrid is a DataGridCheckBoxColumn. Now I want to bind Button's IsEnabled-Property, to be enable if at least one of them is checked, else remain disabled.

Actually I've following implementation:

<Button x:Name="buttonStart" Content="Start" IsEnabled="{Binding Converter={StaticResource ButtonEnableConverter}, ElementName=gridTestCaseChooser}" />

But the Converter is only called once at startup the application. If the DataGrid content change, or I check/uncheck a CheckBox, there isn't a new call to my converter.

How could I do this?

4

3 回答 3

1

您不需要绑定到像网格这样的可视元素,而是绑定到一些 DependencyProperty,该值正在发生变化。电网本身通常不会改变,这就是为什么转换器在启动时只被调用一次。我将创建一个 UserControl,它具有带有复选框和按钮的网格。USERCONTROL将定义BOOL类型的依赖关系,当检查或未选中其中一个Check-box时,该依赖性将设置为true或false。然后 Button 的 IsEnabled 属性将绑定到该 DependencyProperty。

于 2013-01-23T13:31:20.243 回答
1

使用MVVM可以非常简单:

  1. 使用RelayCommand声明一个ICommand属性以执行按钮的逻辑。
  2. 您添加的项目必须实现INotifyPropertyChanged接口并具有 bool IsChecked 属性触发PropertyChanged事件。
  3. 每次添加新项目时,订阅它的PropertyChanged事件,删除时也删除钩子。
  4. 每次调用挂钩方法时,都会触发PropertyChangedICommand 属性。
  5. 在 XAML 中,只需将按钮绑定到ICommand属性。

视图模型

    public class Item: INotifyPropertyChanged
    {
        private bool isChecked;
        public event PropertyChangedEventHandler PropertyChanged;
        public bool IsChecked
        {
            get
            {
                return this.isChecked;
            }
            set
            {
                this.isChecked = value;
                var propertyChangedEvent = PropertyChanged;
                if(propertyChangedEvent != null)
                {
                    propertyChangedEvent(this, new PropertyChangedEventArgs("UpdateSomething");
                }                
            }
        }
    }

    public class MyViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public ICommand UpdateSomething { get; private set; }
        public ObservableCollection<Item> MyItems { get; set; }

        public MyViewModel()
        {
            UpdateSomething = new RelayCommand(MyCommandExecute, MyCommandCanExecute);
            MyItems = new ObservableCollection<Item>();
        }

        private void MyCommandExecute(object parameter)
        {
            // Your logic here.
        }

        private void MyCommandCanExecute(object parameter)
        {
            return MyItems.Any(item => item.IsChecked);
        }

        private void AddItem(Item item)
        {
            item.PropertyChanged += ItemsPropertyChanged;
            MyItems.Add(item);
        }

        private void ItemsPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            var propertyChangedEvent = PropertyChanged;
            if(propertyChangedEvent != null &&
               e.PropertyName == "IsChecked")
            {
                propertyChangedEvent(this, new PropertyChangedEventArgs("UpdateSomething");
            }                
    }
于 2013-01-24T09:12:38.883 回答
1

对于您的按钮:

   IsEnabled="{Binding ElementName=NN, Path=IsChecked}">

问题更新后更新

此处讨论了您遇到的相同情况: 什么导致值转换器触发?

这个想法是选择真正改变自己状态的东西

更新

尝试这样的事情:

<dg:DataGrid.Columns> 
   <dg:DataGridTextColumn Header="First Name" Width="50">  
      <dg:DataGridTextColumn.DataFieldBinding> 
         <Binding Path="FirstName" /> 
      </dg:DataGridTextColumn.DataFieldBinding> 
    </dg:DataGridTextColumn> 
    <dg:DataGridCheckBoxColumn Header="Active" Width="50" DataFieldBinding="{Binding Path= IsActive}" /> 
</dg:DataGrid.Columns> 
于 2013-01-23T12:54:11.447 回答