当鼠标进入WPF中的椭圆时,设置椭圆描边(边框颜色)。

3

椭圆有一个属性叫做IsMouseOver,我们可以使用它来设置椭圆的颜色,就像这篇文章所做的那样。

但在实践中,当鼠标悬停在椭圆上时,描边会改变(将椭圆绘制成圆形),当鼠标在椭圆内(圆形)时,颜色会恢复原值。

我知道椭圆有一个名为MouseEnter的事件,我们可以使用EventTrigger,但只能在StoryBoard中设置。

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="10*" />
        <ColumnDefinition Width="90*" />
    </Grid.ColumnDefinitions>
    <Ellipse x:Name="checkButton" Grid.Column="0" Stroke="Black"></Ellipse>
    <TextBlock x:Name="txtContent" Grid.Column="1" FontWeight="Bold" VerticalAlignment="Center" FontSize="14" HorizontalAlignment="Center" TextAlignment="Center">
        <ContentPresenter />
    </TextBlock>
</Grid>
<ControlTemplate.Triggers>
    <EventTrigger RoutedEvent="MouseEnter">
        <BeginStoryboard></BeginStoryboard>
        // something like <Setter Property="Stroke" Value="Red" /> here
    </EventTrigger>
</ControlTemplate.Triggers>

我只希望当鼠标移入时,设置椭圆的描边;当鼠标移出时,将其恢复。有人有什么想法吗?
提前感谢!

看看我的答案,告诉我为什么它是错误的? - AnjumSKhan
@AnjumSKhan,实际上你的答案是正确的,也是那些答案中最优雅的答案之一,它可以工作,不需要Blend SDK,而且有点小技巧~ :) P.S. 实际上结果与我预期的有点不同,但我修改了代码使其正确,我已在你的答案下发表了评论,请检查。 :) - user1108069
4个回答

2

试试这个:

<ControlTemplate.Triggers>
    <Trigger Property="IsMouseOver" Value="True">
        <Setter Property="Stroke" Value="Red" TargetName="checkButton"/>
    </Trigger>
</ControlTemplate.Triggers>

希望能帮到您:)

实际上这并没有帮助,这个方法与我在问题描述中提到的链接完全相同,我需要的是当鼠标椭圆内时,颜色会改变,而不是悬停。所以,抱歉,我要给你点个踩。 - user1108069

2

自定义复选框的完整解决方案:

<Window x:Class="WpfControlTemplates.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">

    <Window.Resources>
        <ControlTemplate x:Key="CustomChkBox" TargetType="CheckBox">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="10*" />
                    <ColumnDefinition Width="90*" />
                </Grid.ColumnDefinitions>
                <Ellipse x:Name="checkButton" Grid.Column="0" Stroke="{TemplateBinding Property=BorderBrush}"></Ellipse>
                <TextBlock x:Name="txtContent" Grid.Column="1" FontWeight="Bold" Foreground="{TemplateBinding Property=Foreground}" VerticalAlignment="Center" FontSize="14" HorizontalAlignment="Center" TextAlignment="Center">
                    <ContentPresenter />
                </TextBlock>
            </Grid>
            <ControlTemplate.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter TargetName="checkButton" Property="Stroke" Value="Blue"/>
                    <Setter TargetName="checkButton" Property="Fill" Value="Gray"/>
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>

    </Window.Resources>

    <Grid>
        <CheckBox Template="{StaticResource CustomChkBox}" Width="100" Height="25" Foreground="Red" Content="Newsletters " Background="#FF16CF38" BorderBrush="#FF14C9C9"/>
    </Grid>
</Window>

使用Storyboard更改椭圆形描边属性的方法:

关键是设置不同的描边属性,以便我们可以从Storyboard中访问它。Storyboard没有任何有关Brush的动画,但是有一个与Color相关的动画。

<Ellipse x:Name="checkButton" Grid.Column="1" StrokeThickness="5" Margin="82,0,61,0">

    <Ellipse.Stroke>
        <SolidColorBrush x:Name="StrokeColor" Color="Red"/>
    </Ellipse.Stroke>

    <Ellipse.Triggers>
         <EventTrigger RoutedEvent="MouseEnter">
         <BeginStoryboard  x:Name="EllipseSB">
           <Storyboard>
            <DoubleAnimation Storyboard.TargetProperty="StrokeThickness" To="10"/>
            <ColorAnimation Storyboard.TargetName="StrokeColor" Storyboard.TargetProperty="Color" To="Blue"/>
           </Storyboard>
         </BeginStoryboard>
         </EventTrigger>
         <EventTrigger RoutedEvent="MouseLeave">
             <StopStoryboard BeginStoryboardName="EllipseSB"/>
         </EventTrigger>

    </Ellipse.Triggers>
</Ellipse>

2
谁给这个答案点了踩?不要没有适当的评论就点踩。 - AnjumSKhan
你的方法是正确的,而且使用了一个技巧,非常感谢!但结果是,当鼠标进入椭圆时,描边会改变;但如果鼠标在椭圆内部,描边会改回去。我需要当鼠标在内部时,描边保持不变。解决方案很简单,只需将属性Fill="White"添加到椭圆中,使其成为一个_完整的_圆,而不是一个边框描边会改变的圆盘。无论如何,感谢您的答案! - user1108069
@user1108069,Fill="Transparent" 更适合于 StoryBoard 动画场景。 - AnjumSKhan
我明白了,非常感谢,我有个问题..你是从哪里得到这些知识的?只有 MSDN 吗?还是一些书籍或网站? - user1108069
2
@user1108069 MSDN对于WPF来说非常糟糕。以前很好,但现在已经失去了它的光彩。但是,对于文档,您仍然需要查找MSDN。自2012年以来,我一直在苦苦思索WPF,并每次都因挫败而放弃。WPF是一种超前于其时代的技术,但文档质量很差。因此,我的建议是专注于概念及其相互关系,不要深入细节。例如,我们为什么在哪里使用Trigger/Command/Dep-Property/INotifyPropertyChanged/Binding/Templates等。至于调试方面,在调试器中查找堆栈跟踪,仔细查看异常... - AnjumSKhan
尝试应用自己的逻辑。从该网站中随机选择一个问题,并构建您的WPF项目以演示此问题,然后将您的答案与其他人进行比较。10天的练习将带来巨大的知识变化。广泛使用ILSpy工具并查看代码内部。这将指数级地提高您的信心。学习Expression BLEND是充分探索WPF的必要条件,它很有趣。非常好的书籍有“逐步学习Expression Blend电子书”、“Expression Blend Unleashed”、“MCTS自学培训套件(考试70-511):使用Microsoft .NET Framework 4开发Windows应用程序”。 - AnjumSKhan

0
我想要的是,当MouseEnter发生时,设置椭圆形笔画;当MouseLeave发生时,将其设置回来。
有几种方法可以做到这一点:使用简单的样式触发器和setter。
  <Ellipse Fill="White" StrokeThickness="10">
    <Ellipse.Style>
       <Style TargetType="{x:Type Ellipse}">
         <Setter Property="Stroke" Value="Red" />
           <Style.Triggers>
              <Trigger Property="IsMouseOver" Value="True">
                 <Setter Property="Stroke" Value="Green"/>
              </Trigger>
           </Style.Triggers>
       </Style>
   </Ellipse.Style>
</Ellipse>

使用混合行为(使用混合 SDK)

 <Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" 
    Title="MainWindow" Height="350" Width="525">

<Grid x:Name="grid">
    <Ellipse x:Name="ellipse" HorizontalAlignment="Left" Height="100" Margin="109,116,0,0" Stroke="Black" VerticalAlignment="Top" Width="100">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="MouseEnter">
                <ei:ChangePropertyAction PropertyName="Stroke">
                    <ei:ChangePropertyAction.Value>
                        <SolidColorBrush Color="Red"/>
                    </ei:ChangePropertyAction.Value>
                </ei:ChangePropertyAction>
            </i:EventTrigger>
            <i:EventTrigger EventName="MouseLeave">
                <ei:ChangePropertyAction PropertyName="Stroke">
                    <ei:ChangePropertyAction.Value>
                        <SolidColorBrush Color="Black"/>
                    </ei:ChangePropertyAction.Value>
                </ei:ChangePropertyAction>
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </Ellipse>
</Grid>

不要忘记添加对 Microsoft.Expressions.InteractionsSystem.Windows.Interactivity 的引用。

如果您在 Visual Studio 中执行此操作,会非常冗长。但是,如果您使用 Expression Blend,相信我,只需要几个点击即可完成。


1
这需要 Blend SDK。 - AnjumSKhan
如果用户正在设置描边,而你不知道它的初始值。 - AnjumSKhan

0

这里有另一种解决方案

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="10*" />
        <ColumnDefinition Width="90*" />
    </Grid.ColumnDefinitions>
    <Ellipse x:Name="checkButton" Grid.Column="0" Stroke="Black" Fill="AliceBlue">
        <Ellipse.Style>
            <Style TargetType="{x:Type Ellipse}">
                <Style.Triggers>
                    <EventTrigger RoutedEvent="MouseEnter">
                        <EventTrigger.Actions>
                            <BeginStoryboard>
                                <Storyboard>
                                    <ColorAnimation Duration="0:0:0" 
                                                    Storyboard.TargetProperty="(Ellipse.Stroke).(SolidColorBrush.Color)" 
                                                    To="Red" AutoReverse="False"/>
                                </Storyboard>
                            </BeginStoryboard>
                        </EventTrigger.Actions>
                    </EventTrigger>
                    <EventTrigger RoutedEvent="MouseLeave">
                        <EventTrigger.Actions>
                            <BeginStoryboard>
                                <Storyboard >
                                    <ColorAnimation Duration="0:0:0"
                                                    Storyboard.TargetProperty="(Ellipse.Stroke).(SolidColorBrush.Color)"
                                                    To="Black"/>
                                </Storyboard>
                            </BeginStoryboard>
                        </EventTrigger.Actions>
                    </EventTrigger>
                </Style.Triggers>
            </Style>
        </Ellipse.Style>
    </Ellipse>
    <TextBlock x:Name="txtContent" Grid.Column="1" FontWeight="Bold" VerticalAlignment="Center" FontSize="14" HorizontalAlignment="Center" TextAlignment="Center">
    <ContentPresenter />
    </TextBlock>
</Grid>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接