简体   繁体   English

WPF Datagrid RowDetailsTemplate绑定到属性的可见性

[英]WPF Datagrid RowDetailsTemplate visibility bound to a property

I am using a WPF Datagrid with a RowDetails panel where the RowDetailsVisibilityMode is set to "VisibleWhenSelected" and the SelectionMode="Extended" so that multiple rows can be selected and hence display RowDetails, as below: 我正在使用带有RowDetails面板的WPF Datagrid,其中RowDetailsVisibilityMode设置为“VisibleWhenSelected”,SelectionMode =“Extended”,以便可以选择多行,从而显示RowDetails,如下所示:

<dg:DataGrid x:Name="MyGrid"
             ItemsSource="{Binding Path=MyItems}"
             AutoGenerateColumns="True"
             SelectionMode="Extended"
             RowDetailsVisibilityMode="VisibleWhenSelected">

  <dg:DataGrid.RowDetailsTemplate>
    <DataTemplate>
      <TextBlock Text="Further Details..."/>
    </DataTemplate>
  </dg:DataGrid.RowDetailsTemplate>
  ...
</dg:DataGrid>

Unfortunately, for this application it isn't intuitive to display row details on 'selected' rows, the client would like to click a checkbox on a number of rows to display the RowDetails pane, but also scroll around the grid selecting other rows. 遗憾的是,对于此应用程序,在“选定”行上显示行详细信息并不直观,客户端希望单击多个行上的复选框以显示RowDetails窗格,还可以在网格中滚动选择其他行。 In other words fix the rows that display RowDetails no matter what happens on the DataGrid. 换句话说,无论DataGrid上发生什么,都要修复显示RowDetails的行。

So currently scrolling around closes the RowDetailsPanes that they have opened. 因此,目前滚动关闭他们已打开的RowDetailsPanes。 What I would like to do is to have a checkbox in one of the columns and bind the RowDetails panel visibility to this property but I can't figure out how to do it. 我想要做的是在其中一个列中有一个复选框,并将RowDetails面板可见性绑定到此属性,但我无法弄清楚如何执行此操作。 The problem is simply that RowDetailsPane only operates on the row selection(s) in the datagrid - can it be extended somehow to operate on a property of my choosing? 问题只是RowDetailsPane只对数据网格中的行选择进行操作 - 是否可以以某种方式扩展以对我选择的属性进行操作?

Thanks in advance, Will 先谢谢,威尔

Looking at the WPF toolkit source code each DataGridRow has a DetailsVisibility property. 查看WPF工具包源代码,每个DataGridRow都有一个DetailsVisibility属性。

I put a button (just for testing) in the first column. 我在第一列中放了一个按钮(仅用于测试)。

<toolkit:DataGridTemplateColumn>
    <toolkit:DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <Button x:Name="buttonDetails" Content="Hello" ButtonBase.Click="Details_Click" />
        </DataTemplate>
    </toolkit:DataGridTemplateColumn.CellTemplate>
</toolkit:DataGridTemplateColumn>

When the button is clicked, find the clicked row and toggle the property. 单击该按钮时,找到单击的行并切换属性。

   private void Details_Click(object sender, RoutedEventArgs e)
    {
      try
      {
        // the original source is what was clicked.  For example 
        // a button.
        DependencyObject dep = (DependencyObject)e.OriginalSource;

        // iteratively traverse the visual tree upwards looking for
        // the clicked row.
        while ((dep != null) && !(dep is DataGridRow))
        {
          dep = VisualTreeHelper.GetParent(dep);
        }

        // if we found the clicked row
        if (dep != null && dep is DataGridRow)
        {
          // get the row
          DataGridRow row = (DataGridRow)dep;

          // change the details visibility
          if (row.DetailsVisibility == Visibility.Collapsed)
          {
            row.DetailsVisibility = Visibility.Visible;
          }
          else
          {
            row.DetailsVisibility = Visibility.Collapsed;
          }
        }
      }
      catch (System.Exception)
      {
      }
    }

I have not explored doing this via databinding. 我没有通过数据绑定探索这样做。

Using pure XAML (+ a converter): 使用纯XAML(+转换器):

XAML: XAML:

<DataGrid.RowHeaderTemplate>
    <DataTemplate>
        <ToggleButton
            IsChecked="{Binding Path=DetailsVisibility,
                RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}},
                Converter={StaticResource _VisibilityToNullableBooleanConverter}}"
            />
    </DataTemplate>
</DataGrid.RowHeaderTemplate>

Converter: 转换器:

public class VisibilityToNullableBooleanConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is Visibility)
        {
            return (((Visibility)value) == Visibility.Visible);
        }
        else
        {
            return Binding.DoNothing;
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is bool?)
        {
            return (((bool?)value) == true ? Visibility.Visible : Visibility.Collapsed);
        }
        else if (value is bool)
        {
            return (((bool)value) == true ? Visibility.Visible : Visibility.Collapsed);
        }
        else
        {
            return Binding.DoNothing;
        }
    }
}

If you use the (excellent) Lambda Converters library you can save the extra class. 如果您使用(优秀)Lambda转换器库,您可以保存额外的类。 This converter uses 2 lambda expressions, the first for Convert, the second for ConvertBack, eg: 此转换器使用2个lambda表达式,第一个用于Convert,第二个用于ConvertBack,例如:

    public static readonly IValueConverter VisibilityToBoolean =
        ValueConverter.Create<Visibility, bool>(
        (e => e.Value == Visibility.Visible),
            (e => e.Value ? Visibility.Visible : Visibility.Collapsed));

Then the XAML is as follows (note there is no need for StaticResources when using this approach): 然后XAML如下(注意使用这种方法时不需要StaticResources):

     <DataGrid.RowHeaderTemplate>
            <DataTemplate>
                <ToggleButton>
                    <ToggleButton.IsChecked>
                        <Binding RelativeSource="{RelativeSource AncestorType={x:Type DataGridRow}}" Path="DetailsVisibility"
                                 Converter="{x:Static lc40:Converters.VisibilityToBoolean}"/>
                    </ToggleButton.IsChecked>
                </ToggleButton>
            </DataTemplate>
        </DataGrid.RowHeaderTemplate>

Lambda Converters are available here: Lambda转换器可在此处获得:

https://github.com/michael-damatov/lambda-converters https://github.com/michael-damatov/lambda-converters

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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