3

Goal:
I'm trying to create an accordion-style Grid, using only a couple of columns (ColumnDefinition).

Expected behavior:
The ColumnDefinition Width should increase to 2* when the mouse cursor is above the column. It should return to 1* when it's not.

Expected behaviour, e.g. for the cursor above the red column.

Actual results:
The columns do not react to the cursor above them. The widths remain fixed, i.e. 1*.


What I've tried:

  • Testing the exact same Style for the Grid element itself (only switching the Grid Background property in place of the ColumnDefinition Width, but still being triggered by the same IsMouseOver, it works fine.) (Added something related to this in the 1st edit below.)
  • Adding the Background="Transparent" property to the Grid element, in case that the cursor has nothing to "stick" to. (Of course there is no Background property for the ColumnDefinition to try the same.)
  • Limiting the height of the Rectangles to see if the trigger happens over them or in the same column but above/below them. Removing the Rectangles alltoghether (however then it's impossible to even see the triggering effect).
  • Adding/removing the initial Setter Property="Width" Value="1*" (above the Style.Triggers tag)
  • Explicitly referring to the Style with its x:Key property.
  • Tried on WPF Core .NET 5.0. and WPF .NET Framework 4.7.2.

I know that there are other ways to make this work (leaving the Column width as Auto and working with the Widths of Rectangles, or maybe changing the Column Widths through events in the code-behind). But using the row/column star unit of width and a single style seems to be the perfect way, eliminating the need to write any additional logic. And I really can't see why this would not work. I'm guessing that right now the cursor is not recognized at all over the column area, but I'm having trouble understanding why.


    <Window.Resources>
        <Style TargetType="ColumnDefinition" x:Key="ColumnAccordionStyle">
            <Setter Property="Width" Value="1*"></Setter>
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="False">
                    <Setter Property="Width" Value="1*"></Setter>
                </Trigger>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Width" Value="2*"></Setter>
                </Trigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    
    <Grid Background="Transparent">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Style="{StaticResource ColumnAccordionStyle}"/>
            <ColumnDefinition Style="{StaticResource ColumnAccordionStyle}"/>
            <ColumnDefinition Style="{StaticResource ColumnAccordionStyle}"/>
            <ColumnDefinition Style="{StaticResource ColumnAccordionStyle}"/>
        </Grid.ColumnDefinitions>
    
        <Rectangle Fill="Blue" Grid.Column="0"/>
        <Rectangle Fill="Red" Grid.Column="1"/>
        <Rectangle Fill="Green" Grid.Column="2"/>
        <Rectangle Fill="Yellow" Grid.Column="3"/>
    </Grid>

EDIT:

burneech
  • 31
  • 1
  • 7
  • 1
    `IsMouseOver` is a property of class `UIElement`. `ColumnDefinition` is not a `UIElement`. In fact it's not in the UI at all, technically. You need to pick something in the actual user interface, apply a style to that.. LIke some UI control that lives in the Grid column – Joe Nov 19 '21 at 02:59
  • @Joe you are correct. However, if you look at the [MS Docs](https://learn.microsoft.com/en-us/dotnet/api/system.windows.controls.columndefinition?view=windowsdesktop-5.0) for `ColumnDefinition` you can see that it has a `IsMouseOver` property, and, as you say, it does not inherit it from `UIElement`, but it does from `ContentElement`. And reading about the differences between the two, MS says that "_they share many of the same members and APIs_" and even that "_ContentElement is typically not as restrictive about content as UIElement_". – burneech Nov 19 '21 at 11:16

0 Answers0