WPF Datagrid RowDetailsTemplate绑定到属性
我正在使用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只对数据网格中的行选择操作 - 是否可以以某种方式进行扩展以对我选择的属性进行操作?
由于提前, 请问
望着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)
{
}
}
我还没有探讨通过数据绑定做到这一点。
使用纯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;
}
}
}
+1,则此方法也适用于Silverlight,因为它更易于在多个位置应用,并且在移动DataGrid Xaml时更便于携带。 – 2013-05-31 15:35:44
当您将RowDetailsVisibilityMode设置为折叠时,此工作正常。 – user3260977 2017-03-27 15:38:59
如果使用(优秀)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>
拉姆达转换器,可浏览这里:
感谢罗里,很好的解决方案。这正是我想要的,我错误地认为绑定到ViewModel中的一个属性,因为这纯粹是View功能,所以在复选框的click事件上运行的方法是完美的。 – WillH 2009-09-25 07:48:31
如果您为初始DataGrid.RowDetailsVisibilityMode =“Collapsed” – 2010-01-30 05:39:36