Thi*_*ult 8 wpf datagrid string-formatting datagridtemplatecolumn datagridtextcolumn
我尝试了几种方法来分解WPF DataGrid中的单元格格式(.NET 4提供的格式):
我将描述我的尝试,因为它可能会帮助其他人,我希望有人可以给我建议,以改善这些解决方案.请注意,我对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>
Run Code Online (Sandbox Code Playgroud)
行为正是预期的.但是,由于绑定,我无法分解这种风格并多次使用它.为了解决分解问题,我使用了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>
Run Code Online (Sandbox Code Playgroud)
和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>
Run Code Online (Sandbox Code Playgroud)
使用数据模板解决了分解DataGrid单元格格式的初始问题,但使用控件模板会带来符合人体工程学和视觉的问题.例如,由控件模板(在许多其他地方讨论)引起的双标签导航,以及编辑文本框的外观(我尝试使用边框粗细,填充和其他属性设置进行修复).
与此问题相关的具体问题是:
创建您自己的自定义 DataGridTextColumn 并创建绑定以分配给 Element 和 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.");
}
}
Run Code Online (Sandbox Code Playgroud)
我不明白你发布的格式化字符串是如何工作的,所以我做了一个简单的,如果你想要更多的小数位,只需在转换器中对其进行排序即可。
现在您需要做的就是在 xaml 中放置对命名空间的引用,然后在数据网格中创建一个列。
那么一切都会好起来的
u_u
| 归档时间: |
|
| 查看次数: |
10954 次 |
| 最近记录: |