【问题标题】:How to custom format data in datagridview during databinding数据绑定期间如何在datagridview中自定义格式数据
【发布时间】:2011-01-08 04:49:39
【问题描述】:

我正在寻找一种格式化 DataGridViewTextBoxColumn 的方法,以便在数据绑定期间格式化要数据绑定的值。例如,我有一个 CompanyName 属性,当数据绑定发生时,我需要从 CompanyName 中获取前 5 个字母。

我可以挂钩不同的 DataGridView 事件(例如 RowsAdded)并遍历所有行并完成此操作,但我想找到更复杂的方法来做到这一点。由于我决定使用数据绑定,因此循环访问数据并对其进行修改有点违反数据绑定的概念。

我所追求的是如何做与下面相同的事情,但添加自定义格式化逻辑:

dataGridView1.Columns[colSomeDate.Index].DataPropertyName = "SomeDate";
colSomeDate.DefaultCellStyle.Format = "yyyy";

我认为我应该实现 IFormatProvider,但我不太明白我应该如何实现它。

dataGridView1.Columns[companyName.Index].DataPropertyName = "CompanyName";
companyName.DefaultCellStyle.FormatProvider = new ShortText(); // ShortText should implement IFormatProvider

【问题讨论】:

    标签: c# winforms data-binding datagridview format


    【解决方案1】:

    我不知道 IFormatProvider,但是 DataGridViews CellFormatting-event 能帮到你吗?

    private void dataGridView1_CellFormatting(object sender,
        DataGridViewCellFormattingEventArgs e)
    {
        if (e.ColumnIndex == 0)
        {
            e.Value = e.Value.ToString().Substring(0, 5); // apply formating here
            e.FormattingApplied = true;
        }
    }
    

    http://msdn.microsoft.com/en-us/library/z1cc356h.aspx?ppud=4

    【讨论】:

    • 另外,如果您通过设计器指定其他格式(例如数字应显示为“N4”),请不要使用e.FormattingApplied=true,否则不会应用此类其他格式。 #gotcha
    【解决方案2】:

    向您的类添加一个属性,为您执行子字符串,并绑定到它。

    【讨论】:

    • 嗯,是的,但是如果你有几个不同的视图和不同的数据布局,那么你必须为每个不同的目的实现这种格式(意味着你有几个属性)。我想保持与实际业务实体无关的格式。
    【解决方案3】:

    这是我的工作让我的工作

    public class MyFormatProvider : IFormatProvider, ICustomFormatter  
    {  
       public object GetFormat(Type formatType)  
       {  
         if (formatType == typeof(ICustomFormatter))  
            return this;  
         else  
            return null;  
       }  
    
       public string Format(string format, object arg, IFormatProvider formatProvider)  
       {  
         // Check whether this is an appropriate callback               
         if (!this.Equals(formatProvider))  
            return null;  
    
         //if argument/ value is null we return empty string  
         if (arg == null)  
            return null;  
    
         string resultString = arg.ToString();  
    
         //transform resultString any way you want (could do operations based on given format parameter)  
    
         //return the resultant string  
         return resultString;  
       }  
    }  
    

    这就是我随后放入单元格格式处理程序的内容

    //In your datagridview, handle the cell formatting event in required cell as  
    if (e.ColumnIndex == dgvPayments.Columns["amount"].Index)  
    {  
      e.Value = String.Format(new MyFormatProvider (), "{0:U}", e.Value);  
      e.FormattingApplied = true;  
    }  
    

    【讨论】:

      【解决方案4】:

      听起来 IFormatProvider 正是您所需要的。然后,您可以为不同的视图定义不同的代码。

      来自Codeproject

      public override string ToString()
      {
          return ToString("g", null); // Always support "g" as default format.
      }
      
      public string ToString(string format)
      {
        return ToString(format, null);
      }
      
      public string ToString(IFormatProvider formatProvider)
      {
        return ToString(null, formatProvider);
      }
      
      public string ToString(string format, IFormatProvider formatProvider)
      {
        if (format == null) format = "g"; // Set default format, which is always "g".
        // Continue formatting by checking format specifiers and options.
      }
      

      【讨论】:

        【解决方案5】:

        这是我用于实现IFormattableICustomFormatter 的示例的代码sn-p。

        Implements IFormattable
        Implements ICustomFormatter
        
        Public Function Format(ByVal formatExpression As String, ByVal arg As Object, ByVal formatProvider As System.IFormatProvider) As String Implements System.ICustomFormatter.Format
            'type is currently ignored
            '   if type is international then "USPS" should result in international address
            '   if type is international then "US" should result in international address
            '   and so on
            '
        
            '.NET Framework Class Library
            'IFormattable Interface
            'Remarks - A class that implements IFormattable must support the "G" (general) formatting code. Besides the "G" code, the class can define the list of formatting codes that it supports.
        
            'is G and g the same?
            '   yes for numeric
            '   no for date/time
        
            'Standard Numeric Format Strings
            '   G or g - both are the same
            'Standard DateTime Format Strings
            '   g - General date/time pattern (short time)
            '   G - General date/time pattern (long time)
        
        
            If Len(formatExpression) = 0 Then
                Return String.Format("{0}", arg)
            End If
        
            'usps - standardized
            'us - address less country
            'international - all address lines
        
            If formatExpression.Equals("g") Then
                'general formatting code
                '   as per documentation
                Return GatherAddress(_line1, _line2, _city, _state, _zip, _country, _type, AddressFormat.StandardUS)
        
            ElseIf formatExpression.Equals("G") Then
                'general formatting code
                '   as per documentation
                Return GatherAddress(_line1, _line2, _city, _state, _zip, _country, _type, AddressFormat.Standardized)
        
            ElseIf formatExpression.ToUpper.Equals("USPS") Then
                Return GatherAddress(_line1, _line2, _city, _state, _zip, _country, _type, AddressFormat.Standardized)
        
            ElseIf formatExpression.ToUpper.Equals("US") Then
                Return GatherAddress(_line1, _line2, _city, _state, _zip, _country, _type, AddressFormat.StandardUS)
        
            ElseIf formatExpression.ToUpper.Equals("INTERNATIONAL") Then
                Return GatherAddress(_line1, _line2, _city, _state, _zip, _country, _type, AddressFormat.International)
        
            Else
                Return MyBase.ToString()
        
            End If
        
        End Function
        
        Public Overloads Function ToString(ByVal format As String, ByVal formatProvider As System.IFormatProvider) As String Implements System.IFormattable.ToString
            Return Me.Format(format, Nothing, formatProvider)
        End Function
        

        【讨论】:

          【解决方案6】:

          您总是可以像这样从您的 aspx 页面调用自定义格式函数:

          <asp:GridView ID="gvPlatforms" runat="server" AutoGenerateColumns="false"
                    GridLines="None">
          <Columns>
              <asp:TemplateField HeaderText="Icon">
                  <ItemTemplate>
                      <asp:Image ID="imgPlatformLogo" runat="server" ImageUrl='<%#GetImagePath(Eval("Abbr")) %>' />
                  </ItemTemplate>
              </asp:TemplateField>
          </Columns>
          

          然后在该页面后面的代码中:

          protected string GetImagePath(object abbr){
          return string.Format("{0}{1}.gif", Constants.URLs.PLATFORM_LOGOS, abbr.ToString());}
          

          【讨论】:

          • 我正在使用 Windows 窗体,因此 ASP.NET 样式的解决方案不起作用。
          • 它会告诉你,对于一个拿着 asp.net 锤子的人来说,一切看起来都像一个网页。
          【解决方案7】:

          我通常将 ValueConverters 用于此类行为。

          类似:

          <DataGridTextColumn Binding={Binding CompanyName, Converter={StaticResource CompanyNameShortenerConverter}} />
          

          在控件/页面的资源节点中,您需要添加如下内容:

          <local:CompanyNameConverter x:Key="CompanyNameShortenerConverter" />
          

          CompanyNameShortenerConverter 应该实现 IValueConverter,您可以添加逻辑来“缩短”在“Convert”方法中传入的公司名称。

          这使格式化/UI 逻辑与业务逻辑分开(即无需添加缩短名称的“辅助属性”)。

          【讨论】:

          • @lc。是正确的,除非你有一个在 WinForms 中使用的 ValueConverter 的例子,否则这个答案是没有帮助的。
          猜你喜欢
          • 2017-12-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多