将按钮绑定到DataGrid内容

时间:2013-01-23 12:50:17

标签: c# wpf data-binding datagrid

我的WPF应用程序包含一个包含3列的DataGrid和一个禁用的Button。 我的DataGrid的一列是DataGridCheckBoxColumn。现在我想绑定Button的IsEnabled - 属性,如果至少检查其中一个属性,则启用它,否则保持禁用状态。

其实我一直在实施:

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

但转换器仅在启动应用程序时调用一次。如果DataGrid内容发生更改,或者我选中/取消选中CheckBox,则不会对我的转换器进行新的调用。

我怎么能这样做?

3 个答案:

答案 0 :(得分:1)

按钮:

   IsEnabled="{Binding ElementName=NN, Path=IsChecked}">
问题更新后

更新

这里讨论的情况如下: What causes a Value Converter to fire?

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

更新

尝试这样的事情:

<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> 

答案 1 :(得分:1)

您需要不绑定到像grid这样的可视元素,而是绑定到某个DependencyProperty,这个值正在改变。网格本身通常不会改变,这就是为什么转换器只在启动时被调用一次。我会创建一个UserControl,其中包含带有复选框和按钮的网格。 UserControl将定义bool类型的DependencyProperty,当选中或取消选中其中一个复选框时,将设置为true或false。然后Button的IsEnabled属性将绑定到该DependencyProperty。

答案 2 :(得分:1)

使用MVVM非常简单:

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

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