【发布时间】:2011-09-09 17:23:25
【问题描述】:
我尝试了几种方法来分解 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 单元格格式的最初问题,但使用控制模板会带来人体工程学和视觉问题。例如,由控件模板引起的双标签导航(在许多其他地方讨论过),以及编辑文本框的外观(我尝试通过边框粗细、填充和其他属性设置来修复。)
与此问题相关的具体问题是:
- 是否可以使用数据转换器来格式化字符串以进行显示并使用默认格式进行编辑?
- 是否可以排除 DataGridTextColumn 样式,同时仍然能够指定绑定源?
- 有没有一种方法可以使用 DataGridTemplateColumn 而只是让它看起来和感觉像 DataGridTextColumn?
【问题讨论】:
-
您是否尝试过获取和使用 DataGridTextColumn 的“默认”模板并且只更改您需要的位?您可能需要默认模板中内置的所有触发器。
-
我不确定如何处理这个问题。默认模板是否具体化为某些 XAML?我尝试了方便地显示默认模板的工具(在选择主题和特定控件时显示为 XAML),但 DataGridTextColumn 没有。或者你的意思是我应该在后面的代码中获取默认模板并将其动态应用于列?
标签: wpf datagrid datagridtemplatecolumn string-formatting datagridtextcolumn