【问题标题】:set ellipse stroke(border color) when mouse enters it in wpf当鼠标在wpf中进入时设置椭圆描边(边框颜色)
【发布时间】:2015-09-20 04:30:27
【问题描述】:

Ellipse 有一个叫做 IsMouseOver 的属性,我们可以用它来设置椭圆的颜色,就像this post 一样。 但在实际操作中,当鼠标在椭圆上时,笔画会发生变化(我们把椭圆画成圆形),当鼠标在内椭圆(圆) ,颜色恢复到原来的值。 我知道ellipse有个叫MouseEnter的事件,我们可以使用EventTrigger,但是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>

我想要的是当 MouseEnter 发生时,设置椭圆描边;当 MouseLeave 发生时,将其设置回来。 有谁有想法吗?

提前致谢!

【问题讨论】:

  • 看看我的回答,告诉我为什么错了?
  • @AnjumSKhan 实际上你的答案是正确的,它是这些答案中最优雅的答案,它有效,它不需要 Blend SDK,而且有点 hacky~ :)实际上结果与我的预期有点不同,但我修改了代码以使其正确,我已经在你的答案下发表了评论,请检查。 :)

标签: c# wpf eventtrigger


【解决方案1】:

自定义 CheckBox 的完整解决方案:

<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 更改 Ellipse Stroke 属性:

技巧是设置不同的 Stroke 属性,以便我们可以从 StoryBoard 访问它。 StoryBoard 没有任何画笔动画,但它有一个颜色动画。

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

【讨论】:

  • 谁对这个答案投了反对票。不要在没有给出适当评论的情况下投反对票。
  • 你的方法是正确的,它使用了一个技巧,在此先感谢!但结果是,当鼠标进入椭圆时,Stroke 发生了变化;但如果鼠标在椭圆 INSIDE 内,则 Stroke 会变回。当鼠标在其中时,我需要笔画保持不变。解决方法很简单,给椭圆添加属性Fill="White",让它像一个完整的圆,而不是一个边框笔画变化的圆盘。无论如何,谢谢你的回答!
  • @user1108069 Fill="Transparent" 更适合 StoryBoard 动画场景。
  • 我知道了,非常感谢,我有一个问题..您从哪里获得这些知识?只是 MSDN?或一些书籍或网站?
  • @user1108069 MSDN 对于 WPF 来说非常糟糕。以前很好,但现在已经失去了光泽。但是对于文档,您仍然必须查找 MSDN。自 2012 年以来,我一直在用 WPF 挠头,每次都在沮丧中放弃。 WPF 是一项超前于时代的技术,但文档很少。所以,我从我的经验中得到的建议是关注概念,以及它们如何相互关联。不要深入内心。例如,我们为什么以及在哪里使用 Trigger/Command/Dep-Property/INotifyPropertyChanged/Binding/Templates 等等。而关于调试,请在调试器中查找堆栈跟踪,仔细查看异常...
【解决方案2】:

试试这个:

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

希望对你有帮助:)

【讨论】:

  • 其实没用,这个方法和我在问题描述中提到的链接一模一样,我需要的是当鼠标INSIDE椭圆时,颜色更改,而不是 HOVER。所以,对不起,投反对票。
【解决方案3】:

这里还有一个解决方案

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

【讨论】:

    【解决方案4】:

    我想要的是当 MouseEnter 发生时,设置椭圆描边;当 MouseLeave 发生时,将其设置回来。

    有几种方法可以做到这一点

    使用简单的样式触发器和设置器

      <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.Interactions 和System.Windows.Interaactivity 的引用

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

    【讨论】:

    • 这需要 Blend SDK。
    • 如果用户设置了Stroke,你没有设置它的初始值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-05
    • 1970-01-01
    • 2010-10-21
    • 2013-04-30
    • 2015-07-25
    • 1970-01-01
    • 2012-01-21
    相关资源
    最近更新 更多