2010-01-22 10 views
14

Estoy buscando una forma de formatear DataGridViewTextBoxColumn para que el valor que se va a empaquetar de datos se formatee durante la vinculación de datos. Por ejemplo, tengo una propiedad CompanyName y necesito tomar las primeras 5 letras de CompanyName cuando ocurre el enlace de datos.Cómo personalizar datos de formato en datagridview durante la vinculación de datos

Pude unirme a diferentes eventos de DataGridView (por ejemplo, RowsAdded) y recorrer todas las filas y hacer el truco, pero me gustaría encontrar una forma más sofisticada de hacerlo. Desde que decidí utilizar el enlace de datos, el bucle de datos y su modificación son un poco contrarios al concepto de enlace de datos.

lo que busco, es la forma de hacer lo mismo que a continuación, además de añadir la lógica formato personalizado:

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

creo que debería poner en práctica IFormatProvider, pero yo no entiendo muy bien cómo debo poner en práctica eso.

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

Respuesta

5

Agregue una propiedad a su clase que haga la subserie por usted, y vincule a eso.

+3

Bueno, sí, pero si tiene varios diferentes vistas con una presentación de datos diferente, entonces tiene que implementar este formato para cada propósito diferente (significa que tiene varias propiedades). Me gustaría seguir formateando desde la entidad comercial real. – Clack

0

Siempre se puede llamar a una función de formato personalizado al igual que de su página 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> 

Y luego en su código detrás de esa página:

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

Estoy trabajando con Windows Forms, por lo que la solución de estilo ASP.NET no funciona. – Clack

+1

Te muestra que para un hombre con un martillo asp.net, todo parece una página web. –

20

I don' Conozco IFormatProvider, pero ¿puede el DataGridViews CellFormatting-event ayudarlo?

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

+2

Además, si especifica un formato adicional (por ejemplo, los números deben mostrarse como "N4") a través del diseñador, no haga 'e.FormattingApplied = true' o dicho formato adicional no se aplicará. #gotcha – Pat

1

Este es un fragmento de código que utilizo para un ejemplo de implementación IFormattable y 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 
-1

Generalmente uso ValueConverters para este tipo de comportamiento.

algo como:

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

En nodo de recursos del control/de la página, tendrá que añadir algo como:

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

CompanyNameShortenerConverter debe aplicar IValueConverter, y se puede añadir la lógica de "acortar" los nombres de compañías que se pasaron en el método "Convertir".

Esto mantiene la lógica de formateo/UI separada de la lógica de negocios (es decir, no es necesario agregar una "propiedad auxiliar" que acorta el nombre).

+2

Buena sugerencia, pero la pregunta original está etiquetada winforms ... –

+0

@lc. es correcto y, a menos que tenga un ejemplo de un ValueConverter en WinForms, esta respuesta no es útil. – Pat

4

Parece que IFormatProvider es exactamente lo que necesita. Luego puede definir diferentes códigos para los diferentes formatos que desea para las diferentes vistas.

De 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

Esto es lo que hice para conseguir la mina para trabajar

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

Esto es lo que a continuación, poner en mi celular manejador formato

//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; 
} 
Cuestiones relacionadas