【问题标题】:Change button image on mouse over during drag and drop operation在拖放操作期间更改鼠标悬停的按钮图像
【发布时间】:2017-06-23 23:46:25
【问题描述】:

我有一个包含一些项目的列表视图。我还有两个按钮,添加和删除。我已经实现了拖放功能,以便将单个 listviewitem 从 listview 拖到删除按钮,然后在删除按钮拖放时,删除 listview 项目。

当 listview 项目从 listview 拖动到删除按钮并且鼠标悬停在按钮上时(在拖放操作期间以及在按钮上放置之前)我想更改按钮图像。如果我在 IsMouseOver 属性上的按钮上创建数据触发器,它就可以工作,但我只想在拖放操作期间(在拖放之前)鼠标悬停在删除按钮上时更改按钮图像。我该怎么做?

<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>   

【问题讨论】:

    标签: wpf xaml listview button drag-and-drop


    【解决方案1】:

    您可以使用 EventTriggers 来处理 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>
    
    • 寻址 Opacity 而不是 Visibility

    • Resources 中定义Storyboards 时,它们在xaml 文件中的位置很重要。 Resources 应该先定义(在Triggers 使用它们之前)否则初始化将失败。

    【讨论】:

    • 您的解决方案部分有效。我的意思是,图标可以正确交换,但是由于您使用的是 opacity 而不是 visibility 属性,这会导致以下问题:我的按钮下的标签不可见,因为然后使用 opacity 不透明度设置为 0 的图像虽然不可见,但仍占用空间,所以 image1+image2+label 的总高度大于我的按钮高度 64。第二个问题是:在鼠标悬停在按钮上时,它会切换新图标,但这个图标没有放在旧图标的相同位置,而是放在 image1 下。
    • 当在winforms中交换图像或某种等效的图像列表并选择要显示的图像时,可能还需要交换图像位置。怎么做?
    • @user1624552 将Style 添加到Resources 以解决这些问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-23
    • 1970-01-01
    • 1970-01-01
    • 2017-12-18
    相关资源
    最近更新 更多