tags:

views:

1304

answers:

4

I have a Grid with a Border around it. Upon mouse over on the Grid, I want to change the style on the Border. How would I go about doing this? This is what I've tried, without any success so far:

<Border Name="Border" BorderBrush="Transparent" BorderThickness="1" CornerRadius="2">
    <Grid>
        <Grid.Style>
            <Style TargetType="{x:Type Grid}">
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter TargetName="Border" Property="BorderBrush" Value="#FFB9D7FC" />
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Grid.Style>

        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>

        ...
    </Grid>
</Border>

Upon attempting to build this XAML, I get the error

TargetName property cannot be set on a Style Setter.

but I can't think of any other way to do this. Help would be much appreciated. Using any code-behind is out of the question.

A: 

Damn, that was tricky.

  1. Drop the transparent border brush. It seems to combine with the colored brush, preventing you from seeing the border.
  2. You can have the trigger directly on the border itself.
  3. If you want the trigger on just the grid, you can use PyBinding to attach to the correct control. (I don't know how to do this without PyBinding.)

    <Border Name="myBorder" Margin="4"  BorderThickness="4" CornerRadius="2">
        <Border.Style>
                    <Style TargetType="{x:Type Border}">
                    <Style.Triggers>
                     <!-- option 1 -->
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="BorderBrush" Value="#FFB9D7FC" />
                    </Trigger>
                     <!-- option 2 -->
                        <DataTrigger Binding="{p:PyBinding $[myBorder.IsMouseOver]}" Value="True">
                        <Setter Property="BorderBrush" Value="#FFB9D7FC" />
                    </DataTrigger>
                </Style.Triggers>
                </Style>
        </Border.Style>
        <Grid Name="myGrid">      
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <TextBlock Name="myText">sadasdsa</TextBlock>
        </Grid>
    </Border>
    
Jonathan Allen
+1  A: 

Set the triggers directly on the Border object. Also, don't set the BorderBrush on the Border object, but also set it with the trigger:

    <Border.Style>
        <Style TargetType="{x:Type Border}">
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Border.BorderBrush" Value="Yellow" />
                </Trigger>
                <Trigger Property="IsMouseOver" Value="False">
                    <Setter Property="Border.BorderBrush" Value="Black" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </Border.Style>

Also, if you're having trouble seeing what the triggers are up to, check out how to debug triggers here. Can be pretty helpful.
Hope this helps.

Roel
A: 

What about this?

    <Border BorderThickness="1" CornerRadius="2">
        <Border.Style>
            <Style TargetType="{x:Type Border}">
                <Setter Property="BorderBrush" Value="Transparent" />
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="BorderBrush" Value="#FFB9D7FC" />
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Border.Style>

        <Grid Background="Transparent">

            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>

            <TextBlock Name="myText">sadasdsa</TextBlock>
        </Grid>

    </Border>
paolot
+3  A: 

You need do the following:

  1. Remove the BorderBrush from the Border definition. Triggers can overwrite properties set by setters in styles, but not properties set directly within the tag.

  2. Put the Trigger into the Border rather than into the Grid (see the examples that the others provided).

  3. Regarding the hit test on the Grid: Put a transparent box behind the grid so that MouseOver is always captured:

Code example for point 3:

<Grid>
    <Rectangle Fill="Transparent" /><!-- make sure that the mouse is always over "something" --> 
    <Grid Name="myGrid">       
        <Grid.ColumnDefinitions> 
            <ColumnDefinition /> 
            <ColumnDefinition /> 
        </Grid.ColumnDefinitions> 
        <TextBlock Name="myText">sadasdsa</TextBlock> 
    </Grid> 
</Grid>
Heinzi