C# 使用转换器设置WPF单元样式

C# 使用转换器设置WPF单元样式,c#,wpf,xaml,datagrid,C#,Wpf,Xaml,Datagrid,我有两个WPF单元样式,我想基于转换器应用它们。 下面是我的示例,我正在尝试更改背景颜色(在实际应用中,我将更改更多,但这不是问题的重点,所以我只是简化) 那么,我如何将其称为单元格样式 XAML: ... 也许答案是这是不可能的,我需要走另一条路?绑定在DataGridColumn的CellStyle中不起作用,因此请尝试为TextBox目标类型而不是DataGridCell创建样式,并编写一个DataGridTemplateColumn,如下所示: <DataGrid.Resour

我有两个WPF单元样式,我想基于转换器应用它们。 下面是我的示例,我正在尝试更改背景颜色(在实际应用中,我将更改更多,但这不是问题的重点,所以我只是简化)

那么,我如何将其称为单元格样式

XAML:


...

也许答案是这是不可能的,我需要走另一条路?

绑定在DataGridColumn的
CellStyle
中不起作用,因此请尝试为
TextBox
目标类型而不是
DataGridCell
创建样式,并编写一个
DataGridTemplateColumn
,如下所示:

<DataGrid.Resources>
    <local:AmountToCellStyleConverter x:Key="StyleConverter" /> 
</DataGrid.Resources>

...

<DataGridTemplateColumn Width="1.5*" 
                        Header="SimpleHeader"
                        IsReadOnly="False">

    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>                           
            <TextBox Style="{Binding Path=NumberValue, Converter={StaticResource StyleConverter}}"
                     Text="{Binding Path=NumberValue}" />                            
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
public class AmountToCellStyleConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var valueAsDecimal = (int)value;

        if (valueAsDecimal > 0)
        {
            return Application.Current.FindResource("WinCellStyle") as Style;
        }

        return Application.Current.FindResource("LossCellStyle") as Style;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
TextBox
的样式位于
App.xaml

<Application.Resources>
    <Style x:Key="WinCellStyle" TargetType="{x:Type TextBox}">
        <Setter Property="SnapsToDevicePixels" Value="True" />

        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type TextBoxBase}">
                    <Border Background="LightGreen"
                            BorderThickness="1">

                        <ScrollViewer x:Name="PART_ContentHost" 
                                      SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <Style x:Key="LossCellStyle" TargetType="{x:Type TextBox}">
        <Setter Property="SnapsToDevicePixels" Value="True" />

        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type TextBox}">
                    <Border Background="LightSalmon"
                            BorderThickness="1">

                        <ScrollViewer x:Name="PART_ContentHost" 
                                      SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Application.Resources>
或者您可以这样做:将转换器的逻辑更改为返回
True
False
,您可以在CellStyle中编写以下内容:

<DataGridTextColumn Header="SimpleHeader"                                    
                    Width="1.5*" 
                    Binding="{Binding Path=NumberValue}">

    <DataGridTextColumn.CellStyle>
        <Style TargetType="{x:Type DataGridCell}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=NumberValue, Converter={StaticResource MyConverter}}" Value="True">
                    <Setter Property="Background" Value="Yellow" />
                    <Setter Property="BorderThickness" Value="1" />
                </DataTrigger>

                <DataTrigger Binding="{Binding Path=NumberValue, Converter={StaticResource MyConverter}}" Value="False">
                    <Setter Property="Background" Value="Red" />
                    <Setter Property="BorderThickness" Value="1" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </DataGridTextColumn.CellStyle>
</DataGridTextColumn>


这是一种享受,只是想知道是否有什么原因使单元格样式不能采用更方便的绑定?@DermFrench:这是因为
DataGridColumns
与DataGrid位于不同的
VisualTree
中。因此,默认情况下,它不会继承DataGrid的
DataContext
,并且
绑定也不起作用。除了我的回答之外,您还可以使用代理来继承所讨论的DataContext。
<DataGridTemplateColumn.CellTemplate>
    <DataTemplate>                           
        <TextBox Style="{Binding Path=Text,
                                 RelativeSource={RelativeSource Mode=Self}, 
                                 Converter={StaticResource StyleConverter}}"
                 Text="{Binding Path=NumberValue}" />                            
    </DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<Application.Resources>
    <Style x:Key="WinCellStyle" TargetType="{x:Type TextBox}">
        <Setter Property="SnapsToDevicePixels" Value="True" />

        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type TextBoxBase}">
                    <Border Background="LightGreen"
                            BorderThickness="1">

                        <ScrollViewer x:Name="PART_ContentHost" 
                                      SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <Style x:Key="LossCellStyle" TargetType="{x:Type TextBox}">
        <Setter Property="SnapsToDevicePixels" Value="True" />

        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type TextBox}">
                    <Border Background="LightSalmon"
                            BorderThickness="1">

                        <ScrollViewer x:Name="PART_ContentHost" 
                                      SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Application.Resources>
public class AmountToCellStyleConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var valueAsDecimal = (int)value;

        if (valueAsDecimal > 0)
        {
            return Application.Current.FindResource("WinCellStyle") as Style;
        }

        return Application.Current.FindResource("LossCellStyle") as Style;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
<DataGridTextColumn Header="SimpleHeader"                                    
                    Width="1.5*" 
                    Binding="{Binding Path=NumberValue}">

    <DataGridTextColumn.CellStyle>
        <Style TargetType="{x:Type DataGridCell}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=NumberValue, Converter={StaticResource MyConverter}}" Value="True">
                    <Setter Property="Background" Value="Yellow" />
                    <Setter Property="BorderThickness" Value="1" />
                </DataTrigger>

                <DataTrigger Binding="{Binding Path=NumberValue, Converter={StaticResource MyConverter}}" Value="False">
                    <Setter Property="Background" Value="Red" />
                    <Setter Property="BorderThickness" Value="1" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </DataGridTextColumn.CellStyle>
</DataGridTextColumn>