与StringFormat

时间:2018-03-05 22:32:05

标签: c# wpf wpfdatagrid

tl; dr我有一个DataGrid,我正在绑定行标题。但是,我无法使用绑定的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标题上正常工作。它显示的是我绑定的数字,而不是格式文本。但是,如果我在TextBlock上放置相同的格式字符串,它就能完美运行。

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

有谁知道StringFormat属性未正确使用的原因?有没有办法可以得到我想要的行为?

编辑:这是Lane属性的样子。

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

2 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:0)

我找到了答案。它与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喊出建议设置控制模板,这让我看看默认的控制模板,没有这个模板,我对谷歌的尝试将毫无结果。

修改:处理此问题的另一种方法是使用ContentStringFormat上的DataGridRowHeader属性。因此,请在RowStyle中保留标题绑定,并添加以下RowHeaderStyle

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