2
votes

I have a DataGrid where I'm trying to set the background of each element depending on what text is being displayed in that grid cell. The grid cells are defined as follows and accessing them works correctly:

<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>

The part that doesn't work is that I can't set the a style for the DataGridTextColumn, none of my setters below are doing anything. The DataGrid itself is being displayed corrrectly.

        <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>

Thanks in advance for any help.

EDIT 1 Updated with Answers to NETscape's questions. 1) My DataGrid is showing correctly, I'm even clicking on items in the grid and modifying the data behind it. However, I don't have a DataSource set in my XAML, just a simple DataContext in my view that points to the DataGrid.

2) I don't think that the problem is with my variable names since the setter property below that doesn't have a trigger also isn't showing:

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

EDIT 2 Again in response to NETscape's questions/comments. I didn't post my code-behind originally because, since all my objects were displaying correctly, I wasn't looking for the problem there. But I think I was mistaken. The data binding for my grid and for the columns in the grid are different. The DataContext for my grid is an array of RowObjects. The datacontext for each DataGridTextColumn is one entry in my RowObject tied to a particular day of the week.

    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);

EDIT 3 For completeness sake, adding the working solution derived fron NETscape's answer. 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>

And the code in my view model for setting up the first 2 days/columns:

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
I updated my original post again, your comments got me looking in a different direction. The DataContext for my DataGrid is different from the DataContext of the columns in the grid. Which might explain why I can modify the properties having to do with the Rows but now with the columns. I'll see if I can create a stand-alone project for this part and post it, I don't want to post my entire project.Frank E

1 Answers

2
votes

Frank E, your Edit 2 might have given away your issue; it's always helpful to know when you're doing things programmatically!

Setting the Style inside of Windows.Resources is saying, "hey, for any DataGridCell in this control, apply this style to it." That is why it's working properly, because after all the information is added, the styles still get applied; which is why it seems to be working.

Now notice you are defining a DataGridTextColumn and it's ElementStyle. That isn't being applied to all the DataGridTextColumn's which may be what you were thinking. Instead, that is being applied to that single DataGridTextColumn! Because you're not defining anything for that DataGridTextColumn it's actually being drawn in the DataGrid, but since there is no content for that column, it's Width = 0.

Since you're creating the other columns programmatically, you need to apply the Style programmatically. So you should have something like this:

<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>

Then when you're creating your columns in code behind, do something like this:

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

for each column that you are creating.

From what I understand, not assigning a x:Key will apply the style to all elements that are of type TargetType, so since we assign a x:Key to the 2nd style, not all TextBlock will be assigned that style, only the ones we specify.

Let me know if this helps.