在WPF数据网格中选中复选框时启用按钮

时间:2015-06-09 05:18:25

标签: wpf wpfdatagrid

我在WPF中有一个-(IBAction) epic:(id)sender { ,其中Datagridfirst column列,checkboxlast column。 最初,我想禁用所有按钮,每当检查任何buttons时,该行的按钮应该被启用。 checkboxcheckbox,然后应禁用按钮。

搜索了很多但找不到与此相关的任何内容。

我没有使用MVVM ..如何对后面的代码执行此操作?

由于

这是我的Xaml代码,我只是在后面的代码上分配我的itemsource

unchecked

5 个答案:

答案 0 :(得分:2)

你走了!

没有必要在ViewModel中执行启用/禁用,因为这可以在XAML中完成。

XAML:

<DataGrid ItemsSource="{Binding Items}" AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridCheckBoxColumn Binding="{Binding IsChecked, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
        <DataGridTemplateColumn>
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Button Width="100">
                        <Button.Style>
                            <Style TargetType="Button">
                                <Setter Property="IsEnabled" Value="false"/>
                                <Style.Triggers>
                                    <DataTrigger Binding="{Binding IsChecked}" Value="true">
                                        <Setter Property="IsEnabled" Value="True"/>
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </Button.Style>
                    </Button>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

视图模型:

public class ViewModel
{
    public List<Data> Items { get; private set; }
    public ViewModel()
    {
        Items = new List<Data>
        {
            new Data(),
            new Data(),
            new Data()
        };
    }
}

public class Data : INotifyPropertyChanged
{
    private bool _isChecked;
    public bool IsChecked 
    { 
        get  {return _isChecked; }
        set 
        {
            _isChecked = value;
            OnPropertyChanged("IsChecked");               
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string property)
    {
        var handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(property));
        }
    }
}

修改 既然您已经请求了代码隐藏实现,那么就去吧。这可以通过基于单击复选框的当前行遍历可视树来实现。

XAML:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <DataGrid AutoGenerateColumns="False" x:Name="MyDataGrid">
        <DataGrid.Columns>
            <DataGridTemplateColumn>
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <CheckBox Click="CheckBox_Clicked"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            <DataGridTemplateColumn>
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <Button Width="100" x:Name="Button" IsEnabled="false" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>
</Window>

XAML.CS:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        MyDataGrid.ItemsSource = new List<string>
        {
            "test",
            "test1",
            "test2",
            "test3"
        };
    }

    private void CheckBox_Clicked(object sender, RoutedEventArgs e)
    {
        var checkBox = sender as CheckBox;
        if (checkBox != null)
        {
            var associatedRow = VisualTreeHelper.GetParent(checkBox);

            while ((associatedRow != null) && (associatedRow.GetType() != typeof(DataGridRow)))
            {
                associatedRow = VisualTreeHelper.GetParent(associatedRow);
            }

            var dataGridRow = associatedRow as DataGridRow;
            if (dataGridRow != null)
            {
                var associatedButton = FindChild(dataGridRow, "Button");
                if (associatedButton != null)
                {
                    associatedButton.IsEnabled = checkBox.IsChecked.HasValue ? checkBox.IsChecked.Value : false;
                }
            }
        }
    }

    public static Button FindChild(DependencyObject parent, string childName)
    {
        if (parent == null) return null;

        Button foundChild = null;

        var childrenCount = VisualTreeHelper.GetChildrenCount(parent);
        for (var i = 0; i < childrenCount; i++)
        {
            var child = VisualTreeHelper.GetChild(parent, i);
            var childType = child is Button;
            if (!childType)
            {
                foundChild = FindChild(child, childName);
                if (foundChild != null) break;
            }
            else if (!string.IsNullOrEmpty(childName))
            {
                var frameworkElement = child as FrameworkElement;
                if (frameworkElement != null && frameworkElement.Name == childName)
                {
                    foundChild = (Button)child;
                    break;
                }
            }
            else
            {
                foundChild = (Button)child;
                break;
            }
        }
        return foundChild;
    }
}

答案 1 :(得分:1)

这可以是您的DataGrid定义:

<DataGrid x:Name="TestDataGrid" ItemsSource="{Binding source}" AutoGenerateColumns="False" CanUserAddRows="False">
        <DataGrid.Columns>
            <DataGridTemplateColumn>
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                            <CheckBox x:Name="TestBox" Content="Test" IsChecked="{Binding IsChecked, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            <DataGridTemplateColumn>
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                            <Button Content="Click" IsEnabled="{Binding IsChecked}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>

背后非常简单的代码:

public partial class MainWindow : Window
{
    public ObservableCollection<Model> source { get; set; } 

    public MainWindow()
    {
        InitializeComponent();
        source = new ObservableCollection<Model>();
        source.Add(new Model());
        source.Add(new Model());
        this.DataContext = this;
    }
}

这可能是你的模特:

public class Model : DependencyObject
{
    public bool IsChecked
    {
        get { return (bool)GetValue(IsCheckedProperty); }
        set { SetValue(IsCheckedProperty, value); }
    }

    // Using a DependencyProperty as the backing store for IsChecked.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty IsCheckedProperty =
        DependencyProperty.Register("IsChecked", typeof(bool), typeof(Model), new PropertyMetadata(false));

}

或实现INPC接口:

public class Model : INotifyPropertyChanged
{
    private bool _IsChecked;

    public bool IsChecked
    {
        get { return _IsChecked; }
        set
        {
            _IsChecked = value;
            PropertyChanged(this, new PropertyChangedEventArgs("IsChecked"));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged = delegate { };
}

答案 2 :(得分:1)

如果datagrid绑定到您拥有的对象集合(理想情况下是模型的Facade),则将IsSelected属性添加到组成集合的对象中。您可以将复选框数据绑定到该属性。

要启用/禁用按钮,请在集合实现ICommand中使用模型/外观。然后,您可以使用CanExecute方法根据IsSelected的值启用/禁用按钮。

public class User : ICommand, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public event EventHandler CanExecuteChanged
    {
        add
        {
            CommandManager.RequerySuggested += value;
        }
        remove
        {
            CommandManager.RequerySuggested -= value;
        }        
    }

    public bool IsSelected
    {
        get
        {
            return this.isSelected;
        }
        set
        {
            this.isSelected = value;
            CommandManager.InvalidateRequerySuggested();
            this.OnPropertyChanged("IsSelected");
        }
    }

    public bool CanExecute(object parameter) 
    { 
        return this.IsSelected; 
    }

    public void Execute(object parameter)
    {
        // ... Do stuff ...
    }

    private void RaiseCanExecuteChanged()
    {
        var handler = this.CanExecuteChanged;
        if (handler == null)
        {
            return;
        }

        handler(this, new PropertyChangedEventArgs(property));
    }

    private void OnPropertyChanged(string property)
    {
        var handler = this.PropertyChanged;
        if (handler == null)
        {
            return;
        }

        handler(this, new PropertyChangedEventArgs(property));
    }
}

现在将复选框绑定到IsSelected属性。只要选中该复选框,CanExecute方法就会触发该类。

理想情况下,您将使用MVVMLight或Prism中的DelegateCommand类,它具有RaiseCanExecuteChanged()方法。这样可以避免使用CommandManager重新查询它。

答案 3 :(得分:0)

 <receiver
            android:name=".BRPing"
            android:exported="false">
            <intent-filter>
                <action android:name="Some.Intent.Name.BRPing" />
            </intent-filter>
        </receiver>

答案 4 :(得分:-3)

你应该使用 MVVM .DataBinding很方便。

<强>的Xaml

<CheckBox Name="checkbox"  IsChecked="{Binding Checked, Mode = TwoWay}" />
<Button  IsEnabled="{Binding ButtonEnabled , Mode = TwoWay}" />

<强> C#

ViewModel

public class ViewMode : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private bool _buttonChecked = false;
    public bool ButtonChecked
    { 
       get
       {
        return _buttonChecked;
       }
       set
       {
         if(value == true)
         {
          _buttonChecked = value;
           OnPropertyChanged("ButtonChecked");
         }
       }
   }

   private bool _checked;
   public bool Checked
   { 
     get
      {
        return _checked;
      }
     set
      {
         if(value == true)
         {
            _checked= value;
            ButtonChecked = value;
            OnPropertyChanged("Checked");
         }
      }
    }

   [NotifyPropertyChangedInvocator]
    private virtual void OnPropertyChanged(string propertyName = null)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}