【问题标题】:WPF MVVM Light enabling button if data grid row is selected如果选择了数据网格行,则 WPF MVVM Light 启用按钮
【发布时间】:2014-10-06 05:29:14
【问题描述】:

我似乎无法在任何地方找到一个直接的答案。我有一个按钮,我想禁用直到选中 DataGrid 行。无所谓是哪一排。一旦它被取消选择,我希望它再次被禁用。

【问题讨论】:

  • 你允许多选吗?
  • 没有。我不是。单身
  • 按钮在数据网格列内或在数据网格之外,也许一个示例 xaml 将有助于理解这一点。
  • 数据网格位于选项卡控件中。添加和编辑按钮位于数据网格下方,但不是其中的一部分。

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


【解决方案1】:

在 XAML 中:

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

在主方法中:

// 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 属性将能够实时更改。

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案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 属性


      编辑

      这里的要求是一个不使用名称属性的示例

      <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]的第一个子容器,您可以根据需要进行调整。

      【讨论】:

      • 是否可以在数据网格上没有 Name 属性?
      • 会有点困难,如果您可以分享您要使用的确切 xaml,那么也许我们可以找到解决方法。按钮可能不需要名称,您可以将其删除。
      【解决方案4】:

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

      我的视图假设 DataContext(我的 ViewModel)具有一个称为 ButtonCommand 的 ICommand 类型属性、一个作为 DataGrid 的 ItemsSource 的 ObservableCollection 属性以及一个作为 DataGrid 的 SelectedItem 的 YourClass 属性。

      查看

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

      然后我使用一个返回布尔值的方法作为 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);
      }  
      

      【讨论】:

        猜你喜欢
        • 2017-09-02
        • 1970-01-01
        • 2013-09-10
        • 1970-01-01
        • 2015-09-23
        • 1970-01-01
        • 2022-11-15
        • 1970-01-01
        • 2014-10-11
        相关资源
        最近更新 更多