Как настроить форматирование данных в представлении данных во время привязки данных - PullRequest
15 голосов
/ 22 января 2010

Я ищу способ форматирования DataGridViewTextBoxColumn, чтобы при привязке данных форматировалось значение, которое будет связано с данными. Например, у меня есть свойство CompanyName, и мне нужно взять первые 5 букв из CompanyName, когда происходит привязка данных.

Я мог бы подключаться к различным событиям 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

Ответы [ 7 ]

21 голосов
/ 10 июня 2010

Я не знаю о IFormatProvider, но может ли событие DataGridViews CellFormatting помочь вам?

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

5 голосов
/ 03 февраля 2011

Вот что я сделал, чтобы заставить мою работать

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;  
}  
5 голосов
/ 22 января 2010

Добавьте в свой класс свойство, которое выполняет для вас подстроку, и привяжите к нему.

4 голосов
/ 12 июля 2010

Похоже, IFormatProvider это именно то, что вам нужно. Затем вы можете определить разные коды для разных форматов, которые вы хотите для разных представлений.

С Кодпроект .

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.
}
1 голос
/ 21 июня 2010

Это фрагмент кода, который я использую для примера реализации IFormattable и 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
0 голосов
/ 09 июля 2010

Я обычно использую ValueConverters для такого рода поведения.

что-то вроде:

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

В узле ресурсов элемента управления / страницы вам нужно добавить что-то вроде:

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

CompanyNameShortenerConverter должен реализовать IValueConverter, и вы можете добавить логику для «сокращения» названий компаний, переданных в методе «Преобразование».

Это позволяет отделить логику форматирования / пользовательского интерфейса от бизнес-логики (т. Е. Не нужно добавлять «вспомогательное свойство», которое сокращает имя).

0 голосов
/ 22 января 2010

Вы всегда можете вызвать функцию пользовательского формата, например, со своей страницы 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());}
...