2009-09-24 106 views
10

我正在使用RowDetails面板的RowDetailsVisibilityMode设置为“VisibleWhenSelected”和SelectionMode =“Extended”的WPF Datagrid,以便可以选择多行并因此显示RowDetails为如下:WPF Datagrid RowDetailsTemplate绑定到属性

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

不幸的是,这个应用程序是不直观上的“选择”行显示行详细信息,客户想点击一个行数的复选框以显示RowDetails窗格中,也滚动选择其他行的网格。换句话说,无论DataGrid发生什么,修复显示RowDetails的行。

因此,当前滚动关闭它们已打开的RowDetailsPanes。我想要做的是在其中一个列中添加一个复选框,并将RowDetails面板可见性绑定到此属性,但我无法弄清楚如何执行此操作。问题很简单,RowDetailsPane只对数据网格中的行选择操作 - 是否可以以某种方式进行扩展以对我选择的属性进行操作?

由于提前, 请问

回答

14

望着WPF工具源代码,每个DataGridRow有DetailsVisibility属性。

我在第一列中放了一个按钮(仅用于测试)。

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

当按钮被点击时,找到点击的行并切换属性。

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) 
     { 
     } 
    } 

我还没有探讨通过数据绑定做到这一点。

+0

感谢罗里,很好的解决方案。这正是我想要的,我错误地认为绑定到ViewModel中的一个属性,因为这纯粹是View功能,所以在复选框的click事件上运行的方法是完美的。 – WillH 2009-09-25 07:48:31

+2

如果您为初始DataGrid.RowDetailsVisibilityMode =“Collapsed” – 2010-01-30 05:39:36

9

使用纯XAML(+转换器):

XAML:

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

转换器:

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; 
     } 
    } 
} 
+3

+1,则此方法也适用于Silverlight,因为它更易于在多个位置应用,并且在移动DataGrid Xaml时更便于携带。 – 2013-05-31 15:35:44

+0

当您将RowDetailsVisibilityMode设置为折叠时,此工作正常。 – user3260977 2017-03-27 15:38:59

0

如果使用(优秀)LAMBDA转换器库,您可以节省额外购买类。该转换器采用2个lambda表达式,先进行转换,第二次为ConvertBack,如:

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

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

拉姆达转换器,可浏览这里:

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