【问题标题】:How to set the StringFormat for specific columns in a WPF Datagrid whose values are populated via ItemsSource method如何为 WPF Datagrid 中的特定列设置 StringFormat,其值通过 ItemsSource 方法填充
【发布时间】:2018-01-25 20:21:15
【问题描述】:

我有一个 WPF Datagrid,其值通过 ItemsSource 方法填充。

我将如何进行类似于下面的代码的操作,以使其格式正确?还有一种方法可以简单地从 Source 表中继承 StringFormat 吗?

<DataGridTextColumn Binding="{Binding Path=Date, StringFormat=d}" Header="Date" />
<DataGridTextColumn Binding="{Binding Path=Amount, StringFormat=C}" Header="Amount"/>

表格是通过这段代码生成的:

<DataGrid x:Name="datatable" ItemsSource="{Binding SubVwr.Tables[0].Tbl}"/>

【问题讨论】:

  • 当您说“填充了谁的值”时,您的意思是 正在自动填充吗?
  • 列和行。一切。我将发布生成表格的代码

标签: c# wpf mvvm datagrid


【解决方案1】:

你要做的就是使用 AutoGeneratingColumn

private void datagrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
    DataGridTextColumn col = e.Column as DataGridTextColumn;
    if (col != null && e.PropertyType == typeof(double))
    {
        if (!col.Header.ToString() == "Amount")
            col.Binding = new Binding(e.PropertyName) { StringFormat = "N0" };
        else
            col.Binding = new Binding(e.PropertyName) { StringFormat = "N2" };
    }
}

您还可以通过检查 col.Header.ToString() 为每个 col 定义所需的格式

【讨论】:

    【解决方案2】:

    假设 是自动填充的,我建议创建一个附加行为来订阅 AutoGeneratingColumn 事件、检查被绑定的属性并分配默认格式。

    您可以查找 [DataType] 属性以获取提示,如果找不到,请根据列的数据类型选择一个合理的默认值:

    // #using System.ComponentModel.DataAnnotations.dll
    // #using System.Windows.Interactivity.dll
    
    public class AutoColumnFormatBehavior : Behavior<DataGrid>
    {
        protected override void OnAttached()
        {
            base.OnAttached();
            this.AssociatedObject.AutoGeneratingColumn += OnAutoGeneratingColumn;
        }
    
        protected override void OnDetaching()
        {
            base.OnDetaching();
            this.AssociatedObject.AutoGeneratingColumn -= OnAutoGeneratingColumn;
        }
    
        private void OnAutoGeneratingColumn(
            object sender,
            DataGridAutoGeneratingColumnEventArgs e)
        {
            var binding = (e.Column as DataGridBoundColumn)?.Binding;
            if (binding != null && binding.StringFormat == null)
                binding.StringFormat = GetFormat(e.PropertyType, e.PropertyDescriptor);
        }
    
        private static string GetFormat(Type type, object descriptor)
        {
            var attribute = default(DataTypeAttribute);
    
            if (descriptor is MemberInfo mi)
                attribute = mi.GetCustomAttribute<DataTypeAttribute>();
            else if (descriptor is MemberDescriptor md)
                attribute = md.Attributes[typeof(DataTypeAttribute)] as DataTypeAttribute;
    
            var typeCode = GetTypeCode(type);
            var isNumericType = typeCode >= TypeCode.SByte && typeCode <= TypeCode.Decimal;
            var isIntegerType = isNumericType && typeCode < TypeCode.Single;
    
            if (attribute?.DataType == DataType.Currency)
                return isIntegerType ? "C0" : "C";
    
            var formatFromAttribute = attribute?.DisplayFormat?.DataFormatString;
            if (formatFromAttribute != null)
                return formatFromAttribute;
    
            if (isNumericType)
                return isIntegerType ? "N0" : "N";
    
            return null;
        }
    
        private static TypeCode GetTypeCode(Type type)
        {
            if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
                type = type.GetGenericArguments()[0];
            if (type.IsEnum)
                return TypeCode.Object;
            return Type.GetTypeCode(type);
        }
    }
    

    这是附加到 DataGrid 的行为以及一些示例数据:

    <DataGrid xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
              xmlns:l="clr-namespace:WpfTest">
    
      <!-- Attach the behavior: -->
      <i:Interaction.Behaviors>
        <l:AutoColumnFormatBehavior />
      </i:Interaction.Behaviors>
    
      <!-- Add some sample data: -->
      <DataGrid.ItemsSource>
        <x:Array Type="l:SampleItem">
          <l:SampleItem RealMoney="1234.5678"
                        RealValue="1234.5678"
                        IntMoney="1234"
                        IntValue="1234"
                        Date="{x:Static s:DateTime.Now}"
                        Time="{x:Static s:DateTime.Now}"
                        DateTime="{x:Static s:DateTime.Now}" />
        </x:Array>
      </DataGrid.ItemsSource>
    
    </DataGrid>
    

    这是我用于行项目的类:

    public class SampleItem
    {
        [DataType(DataType.Currency)]
        public double RealMoney { get; set; }
    
        public double RealValue { get; set; }
    
        [DataType(DataType.Currency)]
        public int IntMoney { get; set; }
    
        public int IntValue { get; set; }
    
        [DataType(DataType.Date)]
        public DateTime Date { get; set; }
    
        [DataType(DataType.Time)]
        public DateTime Time { get; set; }
    
        [DataType(DataType.DateTime)]
        public DateTime DateTime { get; set; }
    }
    

    这是显示结果的屏幕截图:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-14
      • 2019-12-08
      • 2011-08-23
      • 1970-01-01
      • 2011-12-26
      相关资源
      最近更新 更多