【问题标题】:DataGridTextColum binding StringFormatDataGridTextColum 绑定 StringFormat
【发布时间】:2017-03-04 20:53:35
【问题描述】:

我正在尝试将视图模型中的字符串绑定到 DataGridTextColumn 的 StringFormat 属性。但是,我下面的内容不起作用。有没有办法在不使用转换器或资源的情况下做到这一点?如果没有,最简单的方法是什么?

<DataGridTextColumn Binding="{Binding Date, StringFormat={Binding DateFormat}}" />

【问题讨论】:

    标签: wpf data-binding


    【解决方案1】:

    您不能将任何内容绑定到Binding 的属性,因为Binding 类不继承自DependencyObject

    ContentControl 派生的控件(例如Label)具有可以绑定的ContentStringFormat 属性。在这种情况下,如果 DataGridTextColumn 是从 ContentControl 派生的,那将解决您的问题,但事实并非如此。

    您可以使用包含LabelDataTemplate 将其设为DataGridTemplateColumn,并将Label.ContentStringFormat 绑定到您的DateFormat 属性:

    <DataGridTemplateColumn Header="Date Template">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <Label
                    Content="{Binding Date}"
                    ContentStringFormat="{Binding DataContext.DateFormat, 
                        RelativeSource={RelativeSource AncestorType=DataGrid}}"
                    />
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
    

    但是当我更改视图模型的 DateFormat 属性时,它不会更新。我不知道为什么不,可能我做错了什么。

    这给我们留下了一个多值转换器。当我更改视图模型的 DateFormat 属性时,它确实会更新(两个相邻的列,一个更新,另一个没有 - 所以不要有人告诉我我没有提出 PropertyChanged)。

    <Window.Resources>
        <local:StringFormatConverter x:Key="StringFormatConverter" />
    </Window.Resources>
    

    ……呜呜呜……

    <DataGridTextColumn
        Header="Date Text" 
        >
        <DataGridTextColumn.Binding>
            <MultiBinding Converter="{StaticResource StringFormatConverter}">
                <Binding Path="Date" />
                <Binding 
                    Path="DataContext.DateFormat" 
                    RelativeSource="{RelativeSource AncestorType=DataGrid}" />
            </MultiBinding>
        </DataGridTextColumn.Binding>
    </DataGridTextColumn>
    

    C#:

    这会将任何字符串格式应用于任何值,而不仅仅是DateTime。我的DateFormat 属性正在返回"{0:yyyy-MM-dd}"

    此转换器上的第一个绑定是您要格式化的值。

    第二个绑定是format string parameter for String.Format()。上面的格式字符串在格式字符串之后采用“zeroth”参数——即{0}——如果该值为DateTime,则将其格式化为四位数的年份、破折号、两位数的月份、a破折号和两位数的一天。 DateTime 格式字符串本身就是一个主题; here's the MSDN page on the subject

    我给你的是写这个的最简单的方法,并且在很大程度上是最强大的。你可以传入一个双精度并给它一个格式字符串,如"My cast has {0:c} toes",如果双精度是3.00999,它会告诉你它的猫有$3.01 脚趾。

    但是,在为您提供String.Format() 的所有功能时,我使编写格式字符串的工作变得有些复杂。这是一个权衡。

    public class StringFormatConverter : IMultiValueConverter
    {
        public object Convert(object[] values, 
            Type targetType, object parameter, CultureInfo culture)
        {
            return String.Format((String)values[1], values[0]);
        }
    
        public object[] ConvertBack(object value, 
            Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    

    【讨论】:

    • 你的回答很完美。我删除了我的。谢谢。
    • 格式化行有问题吗?它的格式不正确。为您的格式字符串提供“3/6/2017 2:28:26 AM”。其余的答案虽然完美。
    • @TerryAnderson 我不明白。如果如您所说,它没有根据格式字符串格式化日期,那么它并没有完美地做任何事情——实际上它什么也没做。代码是从我的工作测试用例中复制和粘贴的。让我仔细检查一下格式字符串。
    • @TerryAnderson 该格式字符串适用于我的转换器和日期时间。我刚刚确认它也适用于可为空的 DateTime。
    • @TerryAnderson 对答案添加了更新,我认为应该澄清这个东西是如何使用的,以及它可以用来做什么。
    猜你喜欢
    • 2011-08-17
    • 2016-04-15
    • 2013-09-02
    • 2011-03-11
    • 2011-03-28
    • 2014-10-04
    • 2018-08-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多