c# - 设置 DataGrid 列的样式

标签 c# wpf datagrid

我有一个 DataGrid,我试图根据该网格单元中显示的文本来设置每个元素的背景。网格单元定义如下,并且访问它们可以正常工作:

<Window.Resources>
    <Style TargetType="{x:Type DataGridCell}">
        <EventSetter Event="MouseDown" Handler="Clicked" />
        <Style.Triggers>
            <Trigger Property="IsSelected" Value="True">
                <Setter Property="Background" Value="Transparent"/>
                <Setter Property="Foreground" Value="Black"/>
                <Setter Property="BorderBrush" Value="Transparent"/>
                <Setter Property="BorderThickness" Value="1"/>
            </Trigger>
        </Style.Triggers>
    </Style>
</Window.Resources>

不起作用的部分是我无法设置 DataGridTextColumn 的样式,下面的 setter 都没有执行任何操作。 DataGrid 本身显示正确。

        <DataGrid Name="dataGrid1" AutoGenerateColumns="False" IsReadOnly="true">
            <DataGridTextColumn>
                <DataGridTextColumn.ElementStyle>
                    <Style TargetType="{x:Type TextBlock}">
                        <Setter Property="HorizontalAlignment" Value="Center" />
                        <Setter Property="Background" Value="Black"/>
                        <Style.Triggers>
                            <Trigger Property="Text" Value="None">
                                <Setter Property="Background" Value="Aquamarine"/>
                            </Trigger>
                            <Trigger Property="Text" Value="First">
                                    <Setter Property="Background" Value="Blue"/>
                            </Trigger>
                        </Style.Triggers>
                    </Style>
                </DataGridTextColumn.ElementStyle>
            </DataGridTextColumn>
        </DataGrid>

预先感谢您的帮助。

编辑 1 更新了 NETscape 问题的答案。 1)我的DataGrid显示正确,我什至单击网格中的项目并修改其后面的数据。但是,我的 XAML 中没有设置 DataSource,在我看来只是一个指向 DataGrid 的简单 DataContext。

2)我不认为问题出在我的变量名上,因为下面没有触发器的 setter 属性也没有显示:

 <Setter Property="HorizontalAlignment" Value="Center" />

编辑2 再次回应 NETscape 的问题/评论。我最初没有发布我的隐藏代码,因为由于我的所有对象都正确显示,所以我并没有在那里寻找问题。但我想我错了。我的网格和网格中的列的数据绑定(bind)是不同的。我的网格的 DataContext 是一个 RowObject 数组。每个 DataGridTextColumn 的数据上下文是我的 RowObject 中与一周中的特定一天相关的一个条目。

    DataGridTextColumn cSunday = new DataGridTextColumn();
    DataGridTextColumn cMonday = new DataGridTextColumn();
    public TimeSlice[] TimeArray = new TimeSlice[48];

        MyWnd.dataGrid1.DataContext = TimeArray; //sets DataContext for the DataGrid
        CultureInfo cu = new CultureInfo(App.CultureID);


        //creates one column
        cSunday.Header = cu.DateTimeFormat.GetDayName(DayOfWeek.Sunday);
        cSunday.Binding = new Binding("StatusSunday");
        Wnd.dataGrid1.Columns.Add(cSunday);

        cMonday.Header = cu.DateTimeFormat.GetDayName(DayOfWeek.Monday);
        cMonday.Binding = new Binding("StatusMonday");
        Wnd.dataGrid1.Columns.Add(cMonday);

编辑3 为了完整起见,添加从 NETscape 的答案派生的工作解决方案。 XAML:

<Window
<Window.Resources>
    <Style TargetType="{x:Type DataGridCell}">
        <EventSetter Event="MouseDown" Handler="Clicked" />
        <Style.Triggers>
            <Trigger Property="IsSelected" Value="True">
                <Setter Property="Background" Value="Transparent"/>
                <Setter Property="Foreground" Value="Black"/>
                <Setter Property="BorderBrush" Value="Transparent"/>
                <Setter Property="BorderThickness" Value="1"/>
            </Trigger>
        </Style.Triggers>
    </Style>
    <Style x:Key="MyDataGridTextColumnElementStyle" 
       TargetType="{x:Type TextBlock}">
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="Background" Value="Black"/>
        <Style.Triggers>
            <Trigger Property="Text" Value="None">
                <Setter Property="Background" Value="Aquamarine"/>
            </Trigger>
            <Trigger Property="Text" Value="First">
                <Setter Property="Background" Value="Blue"/>
            </Trigger>
        </Style.Triggers>
    </Style>
</Window.Resources>
<Grid Name="MainView"  HorizontalAlignment="Stretch" VerticalAlignment="Stretch" >
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <Border Grid.Row ="0">
    </Border>
    <Border Grid.Row="1">
        <DataGrid Name="dataGrid1" AutoGenerateColumns="False" IsReadOnly="true"/>
    </Border>
</Grid>
</Window>

我的 View 模型中用于设置前 2 天/列的代码:

public TimeSlice[] TimeArray = new TimeSlice[48];
public ViewModelr(WndCalendar Wnd)
    {


        MyWnd = Wnd;
        MyWnd.DataContext = this;
        MyWnd.dataGrid1.DataContext = TimeArray;

        cTime.Header = "";
        cTime.Binding = new Binding("TimeofDay");
        Wnd.dataGrid1.Columns.Add(cTime);

        CultureInfo cu = new CultureInfo(App.CultureID);

        cSunday.Header = cu.DateTimeFormat.GetDayName(DayOfWeek.Sunday);
        cSunday.Binding = new Binding("StatusSunday");
        Wnd.dataGrid1.Columns.Add(cSunday);
        cSunday.ElementStyle = MyWnd.FindResource("MyDataGridTextColumnElementStyle") as Style;

        cMonday.Header = cu.DateTimeFormat.GetDayName(DayOfWeek.Monday);
        cMonday.Binding = new Binding("StatusMonday");
        Wnd.dataGrid1.Columns.Add(cMonday);
        cMonday.ElementStyle = MyWnd.FindResource("MyDataGridTextColumnElementStyle") as Style;

最佳答案

Frank E,您的编辑 2 可能已经泄露了您的问题;了解何时以编程方式执行操作总是很有帮助的!

Windows.Resources 中设置 Style 的意思是:“嘿,对于此控件中的任何 DataGridCell,应用此样式”。这就是为什么它可以正常工作,因为添加所有信息后,样式仍然会应用;这就是为什么它似乎有效。

现在请注意,您正在定义一个DataGridTextColumn,它是ElementStyle。这并没有应用于所有 DataGridTextColumn,这可能是您所想的。相反,它被应用于单个 DataGridTextColumn!因为您没有为该 DataGridTextColumn 定义任何内容,所以它实际上是在 DataGrid 中绘制的,但由于该列没有内容,因此它的 Width = 0

由于您是以编程方式创建其他列,因此您需要以编程方式应用样式。所以你应该有这样的东西:

<Window.Resources>
    <Style TargetType="{x:Type DataGridCell}">
        <EventSetter Event="MouseDown" Handler="Clicked" />
        <Style.Triggers>
            <Trigger Property="IsSelected" Value="True">
                <Setter Property="Background" Value="Transparent"/>
                <Setter Property="Foreground" Value="Black"/>
                <Setter Property="BorderBrush" Value="Transparent"/>
                <Setter Property="BorderThickness" Value="1"/>
            </Trigger>
        </Style.Triggers>
    </Style>
    <Style x:Key="MyDataGridTextColumnElementStyle" 
           TargetType="{x:Type TextBlock}">
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="Background" Value="Black"/>
        <Style.Triggers>
            <Trigger Property="Text" Value="None">
                <Setter Property="Background" Value="Aquamarine"/>
            </Trigger>
            <Trigger Property="Text" Value="First">
                    <Setter Property="Background" Value="Blue"/>
            </Trigger>
        </Style.Triggers>
    </Style>
</Window.Resources>

然后,当您在代码隐藏中创建列时,请执行以下操作:

cSunday.ElementStyle = MyWnd.FindResource("MyDataGridTextColumnElementStyle") as Style;

对于您正在创建的每一列。

据我了解,不分配 x:Key 会将样式应用于 TargetType 类型的所有元素,因此,由于我们分配了 x :Key 为第二种样式,并非所有 TextBlock 都会分配该样式,只有我们指定的样式。

请告诉我这是否有帮助。

关于c# - 设置 DataGrid 列的样式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23998136/

相关文章:

c# - 如何使用 Linq 检查 JSON 中的标签

c# - 电子邮件支持部分,用户地址为 "From address"

c# - 如何获取 DataGridRow 单元格的值?

.net - WindowsFormsHost 控件 - 异常处理

wpf - 来自 PresentationFramework.dll 的 NullReferenceException

c# - 从 WPF 中的按钮继承的用户控件

c# - 如何使用 Entity Framework 使用序列在 Oracle 中插入标识值

c#/wpf ResourceDictionary.DeferrableContent 异常

c# - 如何指定列表中的列以显示在 DataSource GridView 中? C#

datagrid - 如何在 Adaptable 中创建枢轴布局