Как данные пользовательского формата в datagridview во время привязки данных
Я ищу способ форматирования 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
Ответы
Ответ 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
Ответ 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
Это фрагмент кода, который я использую для примера реализации 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
Ответ 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());}
Ответ 7
Я обычно использую ValueConverters для такого поведения.
что-то вроде:
<DataGridTextColumn Binding={Binding CompanyName, Converter={StaticResource CompanyNameShortenerConverter}} />
В ресурсах управления/страниц node вам нужно добавить что-то вроде:
<local:CompanyNameConverter x:Key="CompanyNameShortenerConverter" />
CompanyNameShortenerConverter должен внедрить IValueConverter, и вы можете добавить логику для "сокращения" имен компаний, прошедших в методе "Преобразовать".
Это отделяет логику форматирования/пользовательского интерфейса от бизнес-логики (т.е. не нужно добавлять "вспомогательное свойство", которое сокращает имя).