How to custom format data in datagridview during databinding
Asked Answered
W

7

15

I'm looking for a way to format DataGridViewTextBoxColumn so that the value to be databinded is formatted during databinding. For example I have a CompanyName property and I need to take first 5 letters from the CompanyName when databinding happens.

I could hook on different DataGridView events (e.g. RowsAdded) and loop through all the rows and do the trick, but I'd like to find more sophisticated way to do this. Since I have decided to use databinding, looping through data and modifying it is a bit against the databinding concept.

What I'm after, is how to do the same as below, but add custom formatting logic:

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

I think I should implement IFormatProvider, but I don't quite understand how I should implement it.

dataGridView1.Columns[companyName.Index].DataPropertyName = "CompanyName";
companyName.DefaultCellStyle.FormatProvider = new ShortText(); // ShortText should implement IFormatProvider
Workhouse answered 22/1, 2010 at 12:40 Comment(0)
O
22

I don't know about the IFormatProvider, but can the DataGridViews CellFormatting-event help you?

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

Oratory answered 10/6, 2010 at 9:30 Comment(1)
Also, if you specify additional formatting (e.g. that numbers should be shown as "N4") through the designer, don't do e.FormattingApplied=true or such additional formatting won't be applied. #gotchaAnschluss
C
5

Add a property to your class that does the substringing for you, and bind to that.

Concavoconcave answered 22/1, 2010 at 12:43 Comment(1)
Well, yes but if you have several different views with a different datalayouts then you have to implement this formatting for each different purpose (means you are having several properties). I'd like to keep formatting out from the actual business entity.Workhouse
H
5

Here is what I did to get mine to work

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

This is what i then put in my cell formatting handler

//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;  
}  
Handily answered 3/2, 2011 at 15:57 Comment(0)
S
4

It sounds like IFormatProvider is exactly what you need. Then you can define different codes for the different formats you want for the different views.

From 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.
}
Spectrohelioscope answered 11/7, 2010 at 20:17 Comment(0)
T
1

This is a code snippet I use for an example of implementing IFormattable and ICustomFormatter.

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
Talkie answered 21/6, 2010 at 17:46 Comment(0)
V
-1

You could always call a custom format function like so from your aspx page:

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

And then in your code behind for that page:

protected string GetImagePath(object abbr){
return string.Format("{0}{1}.gif", Constants.URLs.PLATFORM_LOGOS, abbr.ToString());}
Voyeur answered 22/1, 2010 at 14:11 Comment(2)
I'm working with Windows Forms, so ASP.NET style solution doesn't work.Workhouse
It goes to show you that for a man with an asp.net hammer, everything looks like a web page.Jeanninejeans
C
-1

I generally use ValueConverters for this sort of behavior.

something like:

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

In the control/page's resources node, you'll need to add something like:

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

CompanyNameShortenerConverter should implement IValueConverter, and you can add the logic to "shorten" the company names passed in in the "Convert" method.

This keeps the formatting/UI logic separate from the business logic (i.e. no need to add a "helper property" that shortens the name).

Clywd answered 9/7, 2010 at 3:26 Comment(1)
@lc. is right and unless you have an example of a ValueConverter using in WinForms, this answer is less than helpful.Anschluss

© 2022 - 2024 — McMap. All rights reserved.