WPF - 即使鼠标没有结束,IsMouseOver仍然是真的

时间:2015-08-10 22:43:28

标签: wpf xaml button

简单的问题,为什么它是真的,而它不应该。 我在这里谈论XAML,并控制属性IsMouseOver。 这可以通过创建这样的触发器(样式示例)进行测试:

<Style x:Key="ButtonStyle" TargetType="Button">
    <Setter Property="OverridesDefaultStyle" Value="True"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Border BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}">
                    <ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center"/>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Background" Value="#FFE5E5E5"/>
                    </Trigger>
                    <Trigger Property="IsPressed" Value="True">
                        <Setter Property="Background" Value="#FFCACACB"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

如果在离开控件(按钮)的情况下按下鼠标主按钮(左按钮 - 右手按钮),控件将具有IsMouseOver状态的背景颜色,直到按钮被释放(默认状态)或获得返回按钮(IsPressed状态)。

为什么会这样?有没有解决方法?

修改
终于找到了,为什么会发生这种情况。似乎它使用MouseLeave事件将属性设置为False,并且MouseLeave事件不会触发,直到鼠标按钮被释放(这就是 SledgeHammer 使用MouseMove事件的原因)。如果表单/窗口上只有一个按钮(任何控件),那么您可以使用接受答案中的代码,但如果您有一个独立控件(用户/自定义控件),就像我一样,那么您就可以了使用它(如果在它之外,MouseMove不会触发)。

如果有人能得到更好的答案,可以在用户/自定义控件上使用,那就做你应该做的... ... 我真的无法让它发挥作用 - 必须处理它:)

3 个答案:

答案 0 :(得分:1)

按设计工作。单击时,某些控件(如按钮)会捕获鼠标。因此,请将按钮视为具有以下状态:

with t1 as (
  select data.*, dense_rank() over (order by dob) grp from data
)
select t1.* from t1 order by grp;

当按下控件时,某些控件将在视觉上指示第4个状态,但鼠标未在其上方(但捕获了鼠标)。

您还会注意到,如果您按住鼠标按钮,则没有其他控件会对鼠标做出反应,因为该按钮已捕获鼠标。

有时候,我需要做你想做的事情,所以我只需要向控件添加一个IsMouseOverEx DP,并确保它在控件的范围内,同时忽略鼠标捕获。

答案 1 :(得分:1)

当您单击时捕获鼠标时,您可以使用MultiTrigger告诉控件仅在鼠标结束但未捕获时更改其背景。

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css" rel="stylesheet" />
<div id="app">

  <div class="favorite-wrapper">
    <favorite :store-id="3" :is-favorited="true">
    </favorite>
  </div>

</div>

当然,单击鼠标时背景更改会丢失,但IsPressed触发器会将其更改为其他颜色。我没有花太多时间玩这个,所以可能会有一些不必要的副作用,但它似乎做了这个工作。

答案 2 :(得分:0)

仅在XAML中不可能,因为IsMouseOver属性的行为与您期望的方式不同(尽管其运行正常)。解决方法很简单......只需添加以下代码并绑定到IsMouseOverEx而不是IsMouseOver。

    public static readonly DependencyProperty IsMouseOverExProperty = DependencyProperty.Register("IsMouseOverEx", typeof(bool),
        typeof(xxx), new FrameworkPropertyMetadata(false));

    public bool IsMouseOverEx
    {
        get
        {
            return (bool)GetValue(IsMouseOverExProperty);
        }

        set
        {
            SetValue(IsMouseOverExProperty, value);
        }
    }

    private void xxx_MouseLeave(object sender, MouseEventArgs e)
    {
        IsMouseOverEx = false;
    }

    private void xxx_PreviewMouseMove(object sender, MouseEventArgs e)
    {
        Point pt = e.GetPosition(this);

        if ((pt.X < 0.0) || (pt.Y < 0.0) || (pt.X >= ActualWidth) || (pt.Y >= ActualHeight))
            IsMouseOverEx = false;
        else
            IsMouseOverEx = true;
    }