Формат строки ячейки WPF DataGrid как стиль или шаблон
я попробовал несколько способов, чтобы разложить формат ячейки в WPF DataGrid (тот, который поставляется с .NET 4):
- преобразователь данных,
- свойство привязки "StringFormat" в стиле,
- свойство привязки "StringFormat" в шаблоне данных.
я опишу свои попытки, как это может помочь кому-то еще, и я надеюсь, что кто-то может дать мне совет по улучшению этих решений. Обратите внимание, что я довольно новичок в В WPF...
ожидаемое поведение заключается в том, что строка ячейки форматируется на что-то конкретное, например "1,234,567" для отображения, но она должна быть отформатирована как "1234567" (форматирование по умолчанию) при редактировании ячейки. Когда я пытался использовать преобразователь данных, я не нашел способа использовать форматирование по умолчанию при редактировании, поэтому я сосредоточил свою энергию на стилях и шаблонах.
со стилем определение DataGridTextColumn выглядит следующим образом:
<DataGridTextColumn Header="Price (Style)" SortMemberPath="BILL_PRICE">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Text" Value="{Binding Path=BILL_PRICE, StringFormat={}{0:N0}}"/>
</Style>
</DataGridTextColumn.ElementStyle>
<DataGridTextColumn.EditingElementStyle>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Text" Value="{Binding Path=BILL_PRICE}"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="BorderThickness" Value="0"/>
</Style>
</DataGridTextColumn.EditingElementStyle>
</DataGridTextColumn>
В поведение-это именно то, что ожидается. Однако я не могу исключить этот стиль и использовать его несколько раз из-за привязки. Чтобы решить проблему факторинга, я использовал DataGridTemplateColumn и шаблоны данных. Вот мое определение DataGridTemplateColumn:
<DataGridTemplateColumn Header="Price (Template)" SortMemberPath="BILL_PRICE">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ContentControl Content="{Binding BILL_PRICE}" Template="{StaticResource CurrencyCellControlTemplate}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ContentControl Content="{Binding BILL_PRICE, Mode=TwoWay}" Template="{StaticResource CurrencyCellEditingControlTemplate}"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
и определение ControlTemplate:
<ControlTemplate x:Key="CurrencyCellControlTemplate" TargetType="ContentControl">
<TextBlock Margin="2,0,2,0" Padding="0" TextAlignment="Right">
<TextBlock.Text>
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Content" StringFormat="{}{0:N0}"/>
</TextBlock.Text>
</TextBlock>
</ControlTemplate>
<ControlTemplate x:Key="CurrencyCellEditingControlTemplate" TargetType="ContentControl">
<TextBox Padding="0" BorderThickness="0" TextAlignment="Right">
<TextBox.Text>
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Content"/>
</TextBox.Text>
</TextBox>
</ControlTemplate>
использование шаблонов данных решает начальную проблему факторинга форматирования ячеек DataGrid, но Использование шаблона управления вызывает эргономичность и визуальные проблемы. Например, навигация с двойной вкладкой, вызванная шаблоном элемента управления (обсуждается во многих других местах), и внешний вид текстового поля редактирования (который я пытаюсь исправить с помощью толщины границы, заполнения и других параметров свойств.)
конкретные вопросы, связанные с данной проблемой :
- можно ли использовать конвертер данных для форматирования строки для отображения и использовать форматирование по умолчанию для edition?
- можно ли вынесем Стиль DataGridTextColumn при сохранении возможности указать источник привязки?
- есть ли способ использовать DataGridTemplateColumn, но просто сделать его похожим на DataGridTextColumn?
1 ответов
создайте свой собственный DataGridTextColumn и создает привязки для назначения элементу и EditingElement (один из них с преобразователем один из них без).
конвертер форматирует строку, чтобы она выглядела как десятичная с запятыми.
public class MyDataGridTextColumn : DataGridTextColumn
{
Binding formattedBinding;
Binding unformattedBinding;
FormatConverter formatConverter = new FormatConverter();
protected override FrameworkElement
GenerateElement(DataGridCell cell, object dataItem)
{
var element = base.GenerateElement(cell, dataItem) as TextBlock;
element.SetBinding(TextBlock.TextProperty, GetFormattedTextBinding());
return element;
}
protected override FrameworkElement
GenerateEditingElement (DataGridCell cell, object dataItem)
{
var element = base.GenerateEditingElement(cell, dataItem) as TextBox;
element.SetBinding(TextBox.TextProperty, GetTextBinding());
return element;
}
Binding
GetTextBinding()
{
var binding = (Binding)Binding;
if (binding == null) return new Binding();
unformattedBinding = new Binding
{
Path = binding.Path,
Mode=BindingMode.TwoWay
};
return unformattedBinding;
}
Binding
GetFormattedTextBinding()
{
var binding = (Binding)Binding;
if (binding == null) return new Binding();
formattedBinding = new Binding
{
Path = binding.Path,
Converter = Formatter,
};
return formattedBinding;
}
public FormatConverter
Formatter
{
get { return formatConverter; }
set { formatConverter = value; }
}
}
public class FormatConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string textvalue = value as string;
if (!string.IsNullOrEmpty(textvalue))
{
decimal decimalvalue = decimal.Parse(textvalue);
var test = String.Format("{0:0,0.00}", decimalvalue);
return test;
}
else
return "";
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new InvalidOperationException("FormatConverter can only be used OneWay.");
}
}
Я не понял, как работает строка форматирования, которую вы опубликовали, поэтому я сделал простой, если вы хотите больше десятичных знаков, просто разберитесь в конвертере.
все, что вам нужно сделать сейчас, это место ссылка на пространство имен в xaml, а затем создайте столбец в datagrid.
тогда все должно быть хорошо
u_u