简体   繁体   中英

Bind Button to DataGrid Content

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?

for your button:

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

Update after question was updated

the same situation you have is discussed here: What causes a Value Converter to fire?

The idea is to choose something that is really change its own state

Updated

try something like this:

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

You need to bind not to visual element like grid, but rather to some DependencyProperty, which value is changing. Grid itself is not changing usually, that's why converter is only called one time on startup. I would create a UserControl, which has the grid with check-boxes and the button. That UserControl would define a DependencyProperty of type bool, which would be set to true or false when one of the check-boxes is checked or unchecked. Then IsEnabled property of Button would bind to that DependencyProperty.

Using MVVM can be very easy:

  1. Declare an ICommand property to execute the logic of the button with a RelayCommand .
  2. The items you add must implement INotifyPropertyChanged interface and have a bool IsChecked property firing PropertyChanged event.
  3. Every time a new item is added, subscribe to its PropertyChanged event and when removed, remove the hook as well.
  4. Every time the hooking method is called, fire the PropertyChanged for the ICommand property.
  5. In XAML just bind the button to the ICommand property.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM