DataGridRow header 与 StringFormat 绑定

DataGridRow header binding with StringFormat

tl;dr 我有一个 DataGrid,我正在绑定行 headers。但是,我不能让它与绑定上的 StringFormat 属性 一起使用。

我有一个 WPF DataGrid 设置如下:

<DataGrid HeadersVisibility="All"
          ItemsSource="{Binding Data}">
    <DataGrid.RowStyle>
        <Style TargetType="{x:Type DataGridRow}">
            <Setter Property="Header" Value="{Binding Lane, StringFormat=Lane {0:0}}"/>
        </Style>
    </DataGrid.RowStyle>
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding Value1}" Header="Value 1" />
        <DataGridTextColumn Binding="{Binding Value2}" Header="Value 2" />
        <DataGridTextColumn Binding="{Binding Value3}" Header="Value 3" />
        <DataGridTextColumn Binding="{Binding Value4}" Header="Value 4" />
    </DataGrid.Columns>
</DataGrid>

但无论我做什么,我都无法让 StringFormat 属性 在 DataGridRow header 上正常工作。它只显示我绑定的数字,而不是格式文本。但是,如果我将相同的格式字符串放在 TextBlock 上,它会完美地工作。

<TextBlock Text="{Binding Lane, StringFormat=Lane {0:0}}"/>

有谁知道为什么 StringFormat 属性 没有正确使用?有什么方法可以获得我想要的行为吗?


编辑:这就是车道 属性 的样子。

public int Lane {
    get { return lane; }
    set {
        lane = value;
        NotifyPropertyChanged();
    }
}

我做了一个小测试项目,这对我有用。

如前所述,控件模板将覆盖样式。

<DataGrid.RowHeaderStyle>
    <Style TargetType="{x:Type DataGridRowHeader}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate>
                    <TextBlock Text="{Binding Lane, StringFormat=Lane {0:0}}"/>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</DataGrid.RowHeaderStyle>

为 ContentTemplate 使用数据模板并绑定到正确的源将保留样式。

<Style TargetType="{x:Type DataGridRowHeader}">
    <Setter Property="ContentTemplate">
        <Setter.Value>
            <DataTemplate>
                <TextBlock Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGridRow}, Path=Item.Lane, StringFormat=Lane {0:0}}"/>
            </DataTemplate>
        </Setter.Value>
    </Setter>
</Style>

我找到了答案。它与 Header 属性 是一个对象而不是字符串这一事实有关,因此 StringFormat 属性 未被使用(有关更多信息,请参阅 this question).为了解决这个问题,我需要为该行设置数据模板。下面的样式实现了我想要的。

<DataGrid.RowStyle>
    <Style TargetType="{x:Type DataGridRow}">
        <Setter Property="Header" Value="{Binding Lane}"/>
        <Setter Property="HeaderTemplate">
            <Setter.Value>
                <DataTemplate DataType="{x:Type sys:String}">
                    <TextBlock Text="{Binding StringFormat=Lane {0:0}}"/>
                </DataTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</DataGrid.RowStyle>

P.S。向 Marsh 大喊大叫,因为他建议设置控件模板,这让我看到了默认的控件模板,没有它,我 Google 的尝试将毫无结果。


编辑: 另一种处理方法是在 DataGridRowHeader 上使用 ContentStringFormat 属性。所以,保留头绑定在RowStyle,并添加下面的RowHeaderStyle.

<DataGrid.RowHeaderStyle>
    <Style TargetType="{x:Type DataGridRowHeader}">
        <Setter Property="ContentStringFormat" Value="Lane {0:0}"/>
    </Style>
</DataGrid.RowHeaderStyle>