One of two buttons using the same ControlTemplate does not animate

I have ListView

one that uses DataTemplate

to render each item, with each item having an Edit and Delete button. The two buttons are templates so they are used Path

to display an icon and a storyboard animation when the mouse is switched.

The animation changes Opacity

and the trigger is used to add a dropshadow effect on MouseOver

. The problem I have is that even though the two buttons use the same templates, only one of them has the desired animation behavior when the mouse is over, regardless of whether the ListViewItem is selected. The second one (the Edit button) won't animate unless I first select the ListViewItem.

Pictures for demonstration

Pristine ListView: Resetting may (delete) work correctly, and editing is fully selected. Moving the mouse over the edit button causes none of the animations to play.

In this state, the ListViewItem does not have a mouse over it, so there are no MouseOver effects (color change, etc.).

Initial state

Clicking the Delete button : The delete button continues to work as expected. Mouse selection with my effect.

In this state (and in all subsequent states) the ListViewItem has a MouseOver, which causes the style to reflect it.

Remove button working

Selecting a ListViewItem lets you start editing the animation: When I select a ListViewItem, the Edit button now goes forward and starts animating on the right.

Remove button working

Animation Working with the selected ListViewItem: Now you can see that the Edit button lights up when the mouse is over.

enter image description here

I'm not sure why two buttons using the same template would act differently.

ListView

It is a ListView using AdminQuantlistAttributeTemplate

, displaying the content you see in the above pictures.

<ListView DockPanel.Dock="Top"
            Margin="5 0 0 0"
            x:Name="AttributesListView"
            ItemsSource="{Binding Path=AttributesView}" 
            ItemTemplate="{StaticResource AdminQuantlistAttributeTemplate}"
            SelectedItem="{Binding Path=SelectedAttribute}"/>

      

ItemTemplate

This item template contains two specified buttons. I also tried reinstalling them so that the delete button is first. It doesn't matter what order I put the buttons in my XAML, the edit button keeps breaking until it's selected ListViewItem

.

<DataTemplate x:Key="AdminQuantlistAttributeTemplate"
              DataType="qlModels:QuantlistAttribute">
    <GroupBox>
        <GroupBox.Header>
            <TextBlock FontSize="14"
                       Foreground="{DynamicResource IdealForegroundColorBrush}">
                <Run Text="Attribute" />
                <Run Text="{Binding Path=SortOrder, Converter={StaticResource IncrementNumberConverter}, ConverterParameter=1}" />
            </TextBlock>
        </GroupBox.Header>

        <DockPanel LastChildFill="True">
            <StackPanel DockPanel.Dock="Left"
                        Margin="0 0 15 0">

<!-- The broken Edit Button -->
                <Button Command="{Binding ElementName=AttributesListView,
                        Path=DataContext.EditAttributeCommand}"
                        Margin="0 0 0 20"
                        Template="{DynamicResource ButtonIconTemplate}"
                        ToolTip="Edit Quantlist Attribute">
                    <Rectangle Width="20"
                               Height="20"
                               Fill="{Binding Path=Foreground,
                               RelativeSource={RelativeSource AncestorType=Button,
                               Mode=FindAncestor}}"
                               OpacityMask="{StaticResource EditIconBrush}" />
                </Button>

<!-- The working Remove Button -->
                <Button Command="{Binding ElementName=AttributesListView,
                        Path=DataContext.RemoveAttributeCommand}"
                        Template="{DynamicResource ButtonIconTemplate}"
                        ToolTip="Delete Quantlist Attribute">
                    <Rectangle Width="20"
                               Height="20"
                               Fill="{Binding Path=Foreground,
                               RelativeSource={RelativeSource AncestorType=Button,
                               Mode=FindAncestor}}"
                               OpacityMask="{StaticResource DeleteIconBrush}" />
                </Button>
            </StackPanel>

            <TextBlock DockPanel.Dock="Top">
                <Run Text="Weight"
                     FontWeight="Bold" />
                <Run Text="{Binding Path=AttributeWeight.Name}" />
            </TextBlock>
            <TextBlock Text="{Binding Path=Narrative}"
                       DockPanel.Dock="Top" />
            <ItemsControl ItemsSource="{Binding Path=References}"
                          DockPanel.Dock="Top">

                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <WrapPanel />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>

                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Margin="0 0 20 0">
                            <Run Text="Reference:"
                                 FontWeight="Bold"
                                 FontSize="13" />
                            <Run Text="{Binding Path=Reference}" />
                        </TextBlock>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>

            </ItemsControl>
        </DockPanel>
    </GroupBox>
</DataTemplate>

      

ButtonIconTemplate

This is the pattern that buttons actually use. Please note that I am using this template in multiple places through the app and it works great. It is used in GroupBox and Expander headers, DataGrid columns with multiple buttons, and as stand-alone controls. Just when used in this ListView (app only, I use it like this), doesn't it work.

<ControlTemplate x:Key="ButtonIconTemplate"
                 TargetType="Button">
    <Grid>
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="CommonStates">
                <VisualState x:Name="MouseOver">
                    <Storyboard>
                        <DoubleAnimation Storyboard.TargetProperty="Opacity"
                                    To="1"
                                    Duration="0:0:0.05" />
                    </Storyboard>
                </VisualState>
                <VisualState x:Name="Normal">
                    <Storyboard>
                        <DoubleAnimation Storyboard.TargetProperty="Opacity"
                                    To="0.5"
                                    Duration="0:0:0.05" />
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>

        <Rectangle x:Name="ButtonRect"
                   Fill="Transparent" />
        <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                          Content="{TemplateBinding Content}"
                          VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
        </ContentPresenter>
    </Grid>

    <ControlTemplate.Triggers>
        <Trigger Property="IsMouseOver"
                 Value="True">
            <Setter Property="Effect">
                <Setter.Value>
                    <DropShadowEffect ShadowDepth="-5"
                                      Color="{DynamicResource BlackColor}"
                                      Opacity="1"
                                      BlurRadius="15" />
                </Setter.Value>
            </Setter>
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

      

Visual brushes used by buttons

<VisualBrush x:Key="DeleteIconBrush"
             Stretch="Uniform">
    <VisualBrush.Visual>
        <Canvas Width="24"
                Height="24">
            <Path Fill="#FF000000"
                  Data="F1 M 25.3333,23.75L 50.6667,23.75C 51.5411,23.75 51.8541,27.3125 51.8541,27.3125L 24.1458,27.3125C 24.1458,27.3125 24.4589,23.75 25.3333,23.75 Z M 35.625,19.7917L 40.375,19.7917C 40.8122,19.7917 41.9583,20.9378 41.9583,21.375C 41.9583,21.8122 40.8122,22.9584 40.375,22.9584L 35.625,22.9584C 35.1878,22.9584 34.0416,21.8122 34.0416,21.375C 34.0416,20.9378 35.1878,19.7917 35.625,19.7917 Z M 27.7083,28.5L 48.2916,28.5C 49.1661,28.5 49.875,29.2089 49.875,30.0834L 48.2916,53.8334C 48.2916,54.7078 47.5828,55.4167 46.7083,55.4167L 29.2917,55.4167C 28.4172,55.4167 27.7083,54.7078 27.7083,53.8334L 26.125,30.0834C 26.125,29.2089 26.8339,28.5 27.7083,28.5 Z M 30.0833,31.6667L 30.4792,52.25L 33.25,52.25L 32.8542,31.6667L 30.0833,31.6667 Z M 36.4167,31.6667L 36.4167,52.25L 39.5833,52.25L 39.5833,31.6667L 36.4167,31.6667 Z M 43.1458,31.6667L 42.75,52.25L 45.5208,52.25L 45.9167,31.6667L 43.1458,31.6667 Z " />
        </Canvas>
    </VisualBrush.Visual>
</VisualBrush>

<VisualBrush x:Key="EditIconBrush" 
             Stretch="Uniform">
    <VisualBrush.Visual>
        <Canvas Width="24" 
                Height="24">
            <Path Fill="{DynamicResource BlackBrush}" 
                  Data="M20.71,4.04C21.1,3.65 21.1,3 20.71,2.63L18.37,0.29C18,-0.1 17.35,-0.1 16.96,0.29L15,2.25L18.75,6M17.75,7L14,3.25L4,13.25V17H7.75L17.75,7Z" />
        </Canvas>
    </VisualBrush.Visual>
</VisualBrush>

      

Any help with troubleshooting would be terrible.

Edit

It turns out that the Edit button had a CanExecute method returning false (which is expected). When I have CanExecute return true always, the animation is working properly.

So now the question is, how do I let the storyboard work when the button is disabled?

+3


source to share


1 answer


I think the problem is that it EditAttributeCommand.CanExecute

returns false and prevents animation. This is the only thing different from these two buttons, so I guess.



+1


source