在行选择上更改DataGrid单元格内容/模板

时间:2016-10-27 18:07:53

标签: c# wpf datagrid

我的目标是:我有一个包含单列的数据网格。它被绑定到包含有关人的各种信息的项目列表。未选中时,该行只显示该人的姓名。当选择行(即点击)时,我将显示有关此人的更多信息。

我的第一次尝试是使用DataGridTemplateColumn,其中CellTemplate是ContentControl。 ContentControl的样式由所选行的状态决定。

我的风格:

<DataTemplate x:Key="NotSelectedTemplate">
    <TextBlock Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContentControl}, Path=DataContext.PatientName.FormattedName, Mode=OneWay, BindsDirectlyToSource=True, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>

<DataTemplate x:Key="SelectedTemplate">
    <TextBlock Height="60" Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContentControl}, Path=DataContext.PatientName.FormattedName, Mode=OneWay, BindsDirectlyToSource=True, UpdateSourceTrigger=PropertyChanged}" />
   </DataTemplate>

<Style x:Key="SelectableContentStyle" TargetType="{x:Type ContentControl}">
    <Style.Triggers>
        <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}, Path=IsSelected}" Value="False">
            <Setter Property="ContentTemplate" Value="{StaticResource NotSelectedTemplate}" />
        </DataTrigger>
        <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}, Path=IsSelected}" Value="True">
            <Setter Property="ContentTemplate" Value="{StaticResource SelectedTemplate}" />
        </DataTrigger>
    </Style.Triggers>
</Style>

我的datagrid列:

<DataGrid.Columns>
    <DataGridTemplateColumn Width="*">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <ContentControl Style="{StaticResource SelectableContentStyle}" />
             </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
</DataGrid.Columns>

此方法有效,但每个DataTemplate中的绑定非常难看。我对WPF相对缺乏经验,所以我确信必须有更好的方法来实现它。

基本上, 1)有没有更好的方法来实现这种行为? 2)有没有更好的方法绑定到DataTemplate所以我不想在访问属性时追逐RelativeSources?

1 个答案:

答案 0 :(得分:0)

您可以为ContentTemplateProperty实现一个模板选择器,它将两个模板作为属性,并有一个布尔属性可以在它们之间切换。

坏消息是基类(DataTemplateSelector)不是依赖项对象,因此不支持对您的flag属性进行绑定。在这些情况下,我通过添加一个Config属性来解决这个问题,该属性包含一个自定义类的实例,然后您可以创建一个DependencyObject的子类并在那里定义依赖项属性。 这当然会再次破坏您的代码,并且绑定将具有局限性,因为非正式地说,绑定范围会中断。

另一种选择可能是通过SelectableContentStyle引用DynamicResource中的两个模板,这样您只需要编写一次DataTrigger切换,只需在资源中定义两个模板在个人DataTemplates内。

有关示例,请参阅this answer