首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WPF Adorner出现在鼠标上方动画-什么是最好的模式?

WPF Adorner出现在鼠标上方动画-什么是最好的模式?
EN

Stack Overflow用户
提问于 2012-12-12 21:52:47
回答 1查看 1.5K关注 0票数 2

Adorner定义在图像部件上。所需的行为如下:

  1. 当鼠标位于图像区域(包括Adorner区域)上时,Adorner就会出现。
  2. 当鼠标离开图像和Adorner区域时,Adorner就会消失。
  3. Adorner的出现和消失是通过淡入/退出动画,因此。
  4. 单击Adorner区域必须引发事件AdornerClicked
  5. 单击图像上的区域,而不是被装饰者隐藏,必须是rais ImageClicked。

--天真的实现

在图像的MouseEnter和MouseLeave事件的Adorner不透明度上附加一个动画,并为每个事件附加单击事件。然而,这将导致Adorner在鼠标直接位于其上方时消失(因为在下面的图像上触发了MouseLeave ),从而违反了第1号要求。

对简单实现的一个可能的修正是在Adorner上设置IsHitTestVisible=false。然而,Adorner没有捕捉到任何点击,这违反了需求4。

什么是正确的模式来满足需求?

EN

回答 1

Stack Overflow用户

发布于 2015-12-05 12:03:12

这个问题有点老,但我只是遇到了同样的问题,却找不到答案,下面是我想出的问题。

因此,问题是控件和它的装饰器是重叠的,将装饰器设置为visible将触发装饰控件上的MouseLeave,因为它现在由装饰器覆盖。

解决方案是在装饰控件及其装饰器上的每个MouseEnter和MouseLeave上做出反应,并手动进行命中测试。如果其中任何一个被击中,装饰品就应该是可见的,否则就会倒塌。

因此,您需要能够从装饰控件获得装饰者,反之亦然。从装饰器获取装饰控件没有问题(使用AdornedElement属性),但是框架(AFAIK)没有提供控件的装饰器,所以我使用了一个字典,将控件映射到其装饰器列表。

下面是我的Panel派生类中的代码(包含和排列我的控件及其装饰器):

代码语言:javascript
复制
private readonly Dictionary<Control, List<Adorner>> _controlToAdornersMap;

...

private void CreateMyControl()
{
    var control = new MyControl();
    control.MouseEnter += OnMyControlMouseEnterOrLeave;
    control.MouseLeave += OnMyControlMouseEnterOrLeave;
    Children.Add(control);
    AddAdorners(control);
}

private void AddAdorners(Control control)
{
    var myAdorner = new MyAdorner(control);
    myAdorner.MouseEnter += OnMyAdornerMouseEnterOrLeave;
    myAdorner.MouseLeave += OnMyAdornerMouseEnterOrLeave;

    var adornerLayer = AdornerLayer.GetAdornerLayer(control);
    adornerLayer.Add(myAdorner);

    _controlToAdornersMap[control] = new List<Adorner> {myAdorner};
}

private void OnMyControlMouseEnterOrLeave(object sender, MouseEventArgs e)
{
    HitTestAndSetAdornersVisibility((MyControl)sender, e);
}

private void OnMyAdornerMouseEnterOrLeave(object sender, MouseEventArgs e)
{
    var adorner = (Adorner)sender;
    HitTestAndSetAdornersVisibility((MyControl)adorner.AdornedElement, e);
}

private void HitTestAndSetAdornersVisibility(MyControl control, MouseEventArgs e)
{
    var adorners = _controlToAdornersMap[control];
    var hitTestSubjects = new List<UIElement> { control }.Concat(adorners);
    var hit = hitTestSubjects.Any(i => VisualTreeHelper.HitTest(i, e.GetPosition(i)) != null);

    SetAdornersVisibility(adorners, hit ? Visibility.Visible : Visibility.Collapsed);
}

private static void SetAdornersVisibility(IEnumerable<Adorner> adorners, Visibility visibility)
{
    if (adorners != null)
        foreach (var adorner in adorners)
            adorner.Visibility = visibility;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13849335

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档