2010-01-22 7 views
14

Sto cercando un modo per formattare DataGridViewTextBoxColumn in modo che il valore da database sia formattato durante l'associazione dei dati. Ad esempio, ho una proprietà CompanyName e ho bisogno di prendere le prime 5 lettere da CompanyName quando avviene l'associazione dei dati.Come formattare i dati personalizzati in datagridview durante l'associazione dei dati

Potrei collegarmi a diversi eventi DataGridView (ad esempio RowsAdded) e scorrere tutte le righe e fare il trucco, ma mi piacerebbe trovare un modo più sofisticato per farlo. Dal momento che ho deciso di utilizzare il databinding, il looping dei dati e la modifica sono un po 'contrari al concetto di database.

quello che sto cercando, è come fare lo stesso come sotto, ma aggiungere la logica formattazione personalizzata:

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

penso che dovrei implementare IFormatProvider, ma io non capisco come dovrei implementare esso.

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

risposta

5

Aggiungi una proprietà alla classe che esegue la sottostringa per te e abbinala.

+3

Beh, sì, ma se si dispone di diversi diversi viste con un diverso datalayout allora devi implementare questa formattazione per ogni scopo diverso (significa che hai diverse proprietà). Mi piacerebbe mantenere la formattazione dall'entità aziendale reale. – Clack

0

Si può sempre chiamare una funzione formato personalizzato in questo modo dalla pagina 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> 

E poi nel codice dietro per quella pagina:

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

Sto lavorando con Windows Forms, quindi la soluzione in stile ASP.NET non funziona. – Clack

+1

Ti mostrerò che per un uomo con un martello asp.net, tutto sembra una pagina web. –

20

I don' so di IFormatProvider, ma l'evento CellFormatting di DataGridView può aiutarti?

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

Inoltre, se si specifica una formattazione aggiuntiva (ad es. Che i numeri devono essere mostrati come "N4") tramite il designer, non eseguire 'e.FormattingApplied = true' o tale formattazione aggiuntiva non verrà applicata. #gotcha – Pat

1

Questo è un frammento di codice che uso per un esempio di attuazione IFormattable e 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 utilizzo ValueConverters per questo tipo di comportamento.

qualcosa di simile:

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

Nel nodo di risorse del controllo/della pagina, è necessario aggiungere qualcosa come:

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

CompanyNameShortenerConverter dovrebbe implementare IValueConverter, ed è possibile aggiungere la logica per "abbreviare" i nomi delle società trasmessi nel metodo "Converti".

Ciò mantiene separata la logica di formattazione/interfaccia utente dalla logica aziendale (ovvero non è necessario aggiungere una "proprietà helper" che accorcia il nome).

+2

Buon suggerimento, ma la domanda originale è contrassegnata da winforms ... –

+0

@lc. ha ragione e a meno che tu non abbia un esempio di ValueConverter che usa in WinForms, questa risposta è meno che utile. – Pat

4

Sembra che IFormatProvider sia esattamente ciò di cui hai bisogno. Quindi puoi definire codici diversi per i diversi formati che desideri per le diverse viste.

Da 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

Ecco quello che ho fatto per ottenere la mia a lavorare

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

Questo è quello che ho poi messo nel mio gestore di formattazione delle celle

//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; 
} 
Problemi correlati