1
votes

I have a listview with some items. Also I have two buttons, add and delete. I have implemented drag and drop functionality in order to drag a single listviewitem from listview to the delete button and then on delete button drop, delete the listview item.

When listview item is dragged from listview to delete button and mouse is over the button (during drap and drop operation and before drop on button) I want to change the button image. It is working if I create a data trigger on button on IsMouseOver property, but I only want to change the button image when mouse is over the delete button during drag and drop operation (before drop). How can I do this?

<Button  AllowDrop="True" Drop="btnDrop_Drop" Height="64" Width="64" Margin="10" Click="Button_Click_Delete" Content="Delete">
    <Button.Template>
        <ControlTemplate>
            <StackPanel>
                <Image x:Name="image1" Visibility="Visible" Height="36" Width="36" Stretch="UniformToFill" Source="Resources/icons8-Trash Can-48.png"/>
                <Image x:Name="image2" Visibility="Collapsed" Height="36" Width="36" Stretch="UniformToFill" Source="Resources/icons8-Trash Can-48-3.png"/>
                <Label HorizontalAlignment="Center">Delete</Label>
            </StackPanel>

            <ControlTemplate.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter TargetName="image1" Property="Visibility" Value="Collapsed" />
                    <Setter TargetName="image2" Property="Visibility" Value="Visible" />
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
    </Button.Template>
</Button>   
1

1 Answers

1
votes

You could use EventTriggers to handle the Drop Target Events.

<ControlTemplate>
    <StackPanel>
        <Image x:Name="image1" Opacity="1" ... />
        <Image x:Name="image2" Opacity="0" ... />
        ...
    </StackPanel>
    <ControlTemplate.Resources>

        <Style TargetType="{x:Type Image}">
            <Style.Triggers>
                <Trigger Property="Opacity" Value="0">
                    <Setter Property="Visibility" Value="Collapsed"/>
                </Trigger>
            </Style.Triggers>
        </Style>

        <Storyboard x:Key="swapImages" TargetProperty="Opacity">
            <DoubleAnimation Storyboard.TargetName="image1" To="0" Duration="0" />
            <DoubleAnimation Storyboard.TargetName="image2" To="1" Duration="0"/>
        </Storyboard>

        <Storyboard x:Key="resetImages" TargetProperty="Opacity">
            <DoubleAnimation Storyboard.TargetName="image1" To="1" Duration="0" />
            <DoubleAnimation Storyboard.TargetName="image2" To="0" Duration="0"/>
        </Storyboard>

    </ControlTemplate.Resources>
    <ControlTemplate.Triggers>

        <EventTrigger RoutedEvent="DragOver">
            <BeginStoryboard Storyboard="{StaticResource swapImages}"/>
        </EventTrigger>

        <EventTrigger RoutedEvent="DragLeave">
            <BeginStoryboard Storyboard="{StaticResource resetImages}"/>
        </EventTrigger>

        <EventTrigger RoutedEvent="Drop">
            <BeginStoryboard Storyboard="{StaticResource resetImages}"/>
        </EventTrigger>

    </ControlTemplate.Triggers>
</ControlTemplate>
  • adressing Opacity instead of Visibility.

  • when defining Storyboards in Resources, their location in the xaml file is important. Resources should be defined first (before the Triggers using them) or initialization will fail.