我有一个标准(WPF工具包)数据网格.某些列(显式定义)必须显示为百分比.如果值低于0,则某些列必须以红色显示.(两组列不相同).我试图分别使用StringFormat
和实现这些要求Style
.我的XAML:
<Window xmlns:local="clr-namespace:myNamespace"
xmlns:tk="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit">
<Window.Resources>
<local:ValueConverter x:Key="valueToForeground" />
<Style TargetType="{x:Type tk:DataGridCell}">
<Setter Property="Foreground"
Value="{Binding RelativeSource={RelativeSource Self}, Path=Content.Text, Converter={StaticResource valueToForeground}}" />
</Style>
</Window.Resources>
<Grid>
<tk:DataGrid AutoGenerateColumns="False"
ItemsSource="{Binding Path=myClass/myProperty}">
<tk:DataGrid.Columns>
<tk:DataGridTextColumn Header="A"
Binding="{Binding colA}" />
<tk:DataGridTextColumn Header="B"
Binding="{Binding colB, StringFormat=\{0:P\}}" />
<tk:DataGridTextColumn Header="C"
Binding="{Binding colC, StringFormat=\{0:P\}}" />
<tk:DataGridTextColumn Header="D"
Binding="{Binding colD, StringFormat=\{0:P\}}" />
</tk:DataGrid.Columns>
</tk:DataGrid>
</Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)
和相关的转换器:
namespace myNamespace
{
public class ValueConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
SolidColorBrush brush = new SolidColorBrush(Colors.Black);
Double doubleValue = 0.0;
if (value != null)
{
if (Double.TryParse(value.ToString(), out doubleValue))
{
if (doubleValue < 0)
brush = new SolidColorBrush(Colors.Red);
}
}
return brush;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我认为这一切都非常标准,但问题是转换器在Text
经过它之后获得了值StringFormat
,并且在那时很难正确地解析它(因为实际上并非所有列都具有相同的格式).如果我取出StringFormats
,转换器工作正常,文本显示为红色.我错过了一些明显的东西吗 有一种简单的方法可以解决这个问题吗?我现在唯一能想到的就是将格式转移到另一个转换器中,我不相信它会起作用.
我们有类似的情况,我们需要一个不同的Path
属性,Binding
但CellStyle
每个都相似DataGridColumn
.我们用定制解决了这个问题MarkupExtension
.在你的情况下,它看起来像这样
<tk:DataGrid AutoGenerateColumns="False"
ItemsSource="{Binding MyItems}">
<tk:DataGrid.Columns>
<tk:DataGridTextColumn Header="A"
Binding="{Binding colA}" />
<tk:DataGridTextColumn Header="B"
Binding="{Binding colB, StringFormat=\{0:P\}}"
CellStyle="{markup:ForegroundCellStyle PropertyName=colB}"/>
<tk:DataGridTextColumn Header="C"
Binding="{Binding colC, StringFormat=\{0:P\}}"
CellStyle="{markup:ForegroundCellStyle PropertyName=colC}"/>
<tk:DataGridTextColumn Header="D"
Binding="{Binding colD, StringFormat=\{0:P\}}"
CellStyle="{markup:ForegroundCellStyle PropertyName=colD}"/>
</tk:DataGrid.Columns>
</tk:DataGrid>
Run Code Online (Sandbox Code Playgroud)
然后依赖于ForegroundCellStyleExtension
创建Style
forDataGridCell
PropertyName
ForegroundCellStyleExtension
public class ForegroundCellStyleExtension : MarkupExtension
{
public ForegroundCellStyleExtension() { }
public ForegroundCellStyleExtension(string propertyName)
{
PropertyName = propertyName;
}
public string PropertyName
{
get;
set;
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
IProvideValueTarget service = (IProvideValueTarget)serviceProvider.GetService(typeof(IProvideValueTarget));
DependencyObject targetObject = service.TargetObject as DependencyObject;
if (targetObject == null)
{
return null;
}
Binding foregroundBinding = new Binding
{
Path = new PropertyPath(PropertyName),
Converter = new ValueConverter()
};
Style foregroundCellStyle = new Style(typeof(DataGridCell));
foregroundCellStyle.Setters.Add(new Setter(DataGridCell.ForegroundProperty, foregroundBinding));
return foregroundCellStyle;
}
}
Run Code Online (Sandbox Code Playgroud)
此外,如果您有其他Setters
想要使用的等等,那么它们可以被另一个参数包括在内MarkupExtension
.
<Window.Resources>
<Style x:Key="dataGridCellStyle" TargetType="{x:Type tk:DataGridCell}">
<Setter Property="Background" Value="Blue"/>
</Style>
</Window.Resources>
<!-- ... -->
<tk:DataGridTextColumn Header="B"
Binding="{Binding colB, StringFormat=\{0:P\}}"
CellStyle="{markup:ForegroundCellStyle colB, {StaticResource dataGridCellStyle}}"/>
Run Code Online (Sandbox Code Playgroud)
而ForegroundCellStyleExtension
随后将使用第二个参数BasedOn
为DataGridCell
Style
ForegroundCellStyleExtension with BasedOn
public class ForegroundCellStyleExtension : MarkupExtension
{
public ForegroundCellStyleExtension() { }
public ForegroundCellStyleExtension(string propertyName, Style basedOnCellStyle)
{
PropertyName = propertyName;
BasedOnCellStyle = basedOnCellStyle;
}
public string PropertyName
{
get;
set;
}
public Style BasedOnCellStyle
{
get;
set;
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
IProvideValueTarget service = (IProvideValueTarget)serviceProvider.GetService(typeof(IProvideValueTarget));
DependencyObject targetObject = service.TargetObject as DependencyObject;
if (targetObject == null)
{
return null;
}
Binding foregroundBinding = new Binding
{
Path = new PropertyPath(PropertyName),
Converter = new ValueConverter()
};
Style foregroundCellStyle = new Style(typeof(DataGridCell), BasedOnCellStyle);
foregroundCellStyle.Setters.Add(new Setter(DataGridCell.ForegroundProperty, foregroundBinding));
return foregroundCellStyle;
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
14561 次 |
最近记录: |