如果选择了数据网格行,则WPF MVVM Light启用按钮

时间:2014-08-13 00:29:25

标签: wpf button datagrid wpf-controls mvvm-light

我似乎无法在任何地方找到答案。我有一个按钮,我想要禁用UNTIL一个DataGrid行被选中。哪一排并不重要。一旦取消选择,我希望它再次被禁用。

4 个答案:

答案 0 :(得分:3)

你去吧

<StackPanel>
    <DataGrid x:Name="dGrid">
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding}"
                                Header="A Column" />
        </DataGrid.Columns>
        <sys:String>item 1</sys:String>
        <sys:String>item 2</sys:String>
        <sys:String>item 3</sys:String>
        <sys:String>item 4</sys:String>
    </DataGrid>
    <Button x:Name="button"
            Content="A Button">
        <Button.Style>
            <Style TargetType="Button">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding SelectedItems.Count,ElementName=dGrid}"
                                 Value="0">
                        <Setter Property="IsEnabled"
                                Value="False" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Button.Style>
    </Button>
</StackPanel>

以上示例将在DataGrid的SelectedItems.Count上放置一个触发器,如果​​该按钮为零则将禁用该按钮

这是一个纯xaml解决方案,其他解决方案也可以使用转换器或vm属性


修改

这里要求的

是一个不使用Name属性

的样本
<StackPanel>
    <DataGrid>
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding}"
                                Header="A Column" />
        </DataGrid.Columns>
        <sys:String>item 1</sys:String>
        <sys:String>item 2</sys:String>
    </DataGrid>
    <Button Content="A Button">
        <Button.Style>
            <Style TargetType="Button">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Parent.Children[0].SelectedItems.Count,RelativeSource={RelativeSource Self}}"
                                 Value="0">
                        <Setter Property="IsEnabled"
                                Value="False" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Button.Style>
        </Button>
</StackPanel>

上面的代码假设datagrid是父容器Parent.Children[0]的第一个子容器,您可以根据需要进行调整。

答案 1 :(得分:3)

使用WPF提供的bool bool的自动评估要容易得多:

IsEnabled="{Binding ElementName=YourDataGrid, Path=SelectedItems.Count}"

答案 2 :(得分:1)

在XAML中:

IsEnabled="{Binding ElementName=DataGridName, Path=SelectedItems.Count}"

在MainMethod中:

// depends how much do you need
if(dataGrid.SelectedItems.Count >= 1)
            {
                Button.IsEnabled = true;
            }

并创建

void dataGrid_OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (sender != null)
            {
                DataGrid grid = sender as DataGrid;
                if (grid != null && grid.SelectedItems != null && grid.SelectedItems.Count == 1)
                {
                    DataGridRow dgr = grid.ItemContainerGenerator.ContainerFromItem(grid.SelectedItem) as DataGridRow;
                    if (!dgr.IsMouseOver)
                    {
                        (dgr as DataGridRow).IsSelected = false;
                    }
                }
            }
        }

IsEnabled属性将能够实时更改。

答案 3 :(得分:0)

由于您使用的是MVVM Light,因此可以使用RelayCommand的CanExecute属性。

我的观点是假设DataContext(我的ViewModel)具有一个名为ButtonCommand的ICommand类型属性,一个ObservableCollection属性作为DataGrid的ItemsSource,一个YourClass属性作为DataGrid的SelectedItem。

查看

<Grid>
    <Button Content="Button"
            Command="{Binding ButtonCommand}"/>
    <DataGrid SelectionMode="Single"
              SelectedItem="{Binding SelectedRow}"
              ItemsSource="{Binding Items}">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Some Property"
                                Binding="{Binding SomeProperty}" />
        </DataGrid.Columns>
    </DataGrid>
</Grid>

然后我使用一个方法返回一个bool作为ButtonCommand的CanExecute参数。当我的SelectedRow变为null时,该按钮将自动禁用。同样,当我选择一行时,该按钮将自动启用。

<强>视图模型

private ICommand _ButtonCommand;
public ICommand ButtonCommand
{
    get
    {
        if (_ButtonCommand == null)
        {
            _ButtonCommand = new RelayCommand(() => MethodToCall(), () => MethodCanExecute());
        }

        return _ButtonCommand;
    }
}

private bool MethodCanExecute()
{
    return SelectedRow != null;
}

private void MethodToCall()
{
    MessageBox.Show(SelectedRow.SomeProperty);
}