在多个GridViewColumns中使用的通用数据模板

本文关键字:数据 GridViewColumns | 更新日期: 2023-09-27 18:16:08

我有一个GridView显示一些值:

<ListView ItemsSource="{Binding MyDataSource}">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Date1" DisplayMemberBinding="{Binding Date1}" />
            <GridViewColumn Header="Date2" DisplayMemberBinding="{Binding Date2}" />
            ...other Columns, not necessarily containing dates...
        </GridView>
    </ListView.View>
</ListView>

这很好。现在我想创建一个数据模板,以特定的方式格式化日期:

<DataTemplate x:Key="MySpecialDate">
    <TextBlock Text="{Binding StringFormat={}{0:yyyy.MM.dd}}" />
</DataTemplate>

只要指定了DisplayMemberBinding,添加CellTemplate将不起作用。因此,我必须删除DisplayMemberBinding属性:

<GridViewColumn Header="Date1" CellTemplate="{StaticResource MySpecialDate}" />
<GridViewColumn Header="Date2" CellTemplate="{StaticResource MySpecialDate}" />

这里的问题:现在,DisplayMemberBinding是走了,我如何告诉GridView哪个属性显示?GridViewColumn没有DataContext属性

当然,我可以把属性的名称( Date1resp)。Date2)放入DataTemplate中,但是这样我就需要为每个属性创建一个模板,这将破坏使用模板的整个目的。

<!-- I don't want that -->
<DataTemplate x:Key="MySpecialDate1">
    <TextBlock Text="{Binding Date1, StringFormat={}{0:yyyy.MM.dd}}" />
</DataTemplate>
<DataTemplate x:Key="MySpecialDate2">
    <TextBlock Text="{Binding Date2, StringFormat={}{0:yyyy.MM.dd}}" />
</DataTemplate>

在多个GridViewColumns中使用的通用数据模板

与您的问题相关的是我的问题:将多个资源传递到我最终找到解决方案的DataTemplate中。我认为您无法绕过每个这样的日期的模板定义。但是,根据显示模板的复杂性,此解决方案将额外的DataTemplate代码保持在最低限度:

<DataTemplate x:Key="DateX">
  <ContentPresenter ContentTemplate="{StaticResource MySpecialDate}" local:YourClass.AttachedDate="DateX"/>
</DataTemplate>

这些额外的DataTemplate使用附加的属性,然后可以由转换器在DataTemplate"MySpecialDate"中使用。附加的属性必须在后面的代码中定义。我自己的问题的答案包含一个完整的例子。

如果该格式确实被广泛使用,那么您可以使用以下

In DateTimeColumn.cs

public class DateTimeColumn : GridViewColumn
{
    protected override void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        base.OnPropertyChanged(e);
        if (Equals(e.PropertyName, "DisplayMemberBinding") && DisplayMemberBinding != null)
        {
            DisplayMemberBinding.StringFormat = "{0:yyyy.MM.dd}";
        }
    }
}

XAML code...

<local:DateTimeColumn DisplayMemberBinding="{Binding Date1}" />

(我不喜欢格式为魔法字符串,但代码可以根据需要修改)