设置DataGrid列的样式

时间:2014-06-02 15:27:50

标签: 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设置样式,下面的任何设置器都没有做任何事情。 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的问题/评论。我最初没有发布我的代码隐藏因为,因为我的所有对象都正确显示,所以我没有在那里寻找问题。但我觉得我错了。我的网格和网格中的列的数据绑定是不同的。我的网格的DataContext是一个RowObject数组。每个DataGridTextColumn的datacontext是我的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>

我的视图模型中的代码用于设置前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;

1 个答案:

答案 0 :(得分:2)

Frank E,你的编辑2可能已经放弃了你的问题;知道你何时以编程方式做事总是有帮助的!

Style内设置Windows.Resources说,“嘿,对于此控件中的任何DataGridCell,请将此样式应用于它。”这就是它正常工作的原因,因为在添加了所有信息后,样式仍然会得到应用;这就是它似乎有效的原因。

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

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

<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将被分配该样式,仅指定我们指定的样式。

如果有帮助,请告诉我。