xamlbuttonuwpvisualstatemanagercontenttemplate

VisualStateManager not working inside Button.ContentTemplate UWP


I have been struggling with this for a few days now unable to find solution after lot of effort. This is the code where I'm facing the issue. SO I have a ItemsControl where each element is Button and each Button has an Image and TextBlock. On hovering over Button I could see the Background of Button being changed to Red as expected. But I'm unable to change the Foreground of TextBlock to Green. Any help in this regard is highly appreciated

        <ControlTemplate x:Key="ButtonTemplate" TargetType="ContentControl">
            <Grid Background="Transparent" x:Name="Mini">
                <VisualStateManager.VisualStateGroups>
                    <VisualStateGroup x:Name="CommonStates">
                        <VisualState x:Name="PointerOver">
                            <VisualState.Setters>
                                <Setter Target="Mini.Background" Value="Red" />
                            </VisualState.Setters>
                        </VisualState>
                    </VisualStateGroup>
                </VisualStateManager.VisualStateGroups>
                <ContentPresenter x:Name="MiniContent" />
            </Grid>
        </ControlTemplate>

            <DataTemplate x:Key="ListItemTemplate" x:DataType="local:DataModel">
            <Button
                Template="{StaticResource ButtonTemplate}">
                <Button.ContentTemplate>
                    <DataTemplate x:DataType="local:DataModel">
                      <UserControl>
                        <Grid >
                           <VisualStateManager.VisualStateGroups>
                              <VisualStateGroup x:Name="CommonStates">
                                <VisualState x:Name="PointerOver">
                                    <VisualState.Setters>
                                      <Setter Target="Value.Foreground" Value="Green" />
                                    </VisualState.Setters>
                               </VisualState>
                             </VisualStateGroup>
                          </VisualStateManager.VisualStateGroups>
                            <TextBlock x:Name="Value"
                                Foreground="Yellow" 
                                Text="{x:Bind DisplayName, Mode=OneWay}"/>
                            <Image
                                Width="16"
                                Source="{x:Bind ImageBitmap, Mode=OneWay}"/>
                        </Grid>
                       </UserControl>

                    </DataTemplate>
                </Button.ContentTemplate>
            </Button>
        </DataTemplate>

       
        <ItemsControl
        ItemTemplate="{StaticResource ListItemTemplate}"
        ItemsSource="{x:Bind DataModelVector, Mode=OneWay}" />

Solution

  • You need something to actually transition between the VisualStates, the PointerOver state isn't triggered automatically. The easiest way would be to factor the content of your DataTemplate into its own file (UserControl with markup and code-behind) and handle pointer events in code to transition between visual states using VisualStateManager.GoToState.

    You could also create a reusable "StateTrigger" for transitioning any control into a "PointerOver" visual state, but often some code-behind is simpler.