Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
WPF装饰器出现在鼠标悬停动画上-什么';什么样的款式最好?_Wpf_Adorner - Fatal编程技术网

WPF装饰器出现在鼠标悬停动画上-什么';什么样的款式最好?

WPF装饰器出现在鼠标悬停动画上-什么';什么样的款式最好?,wpf,adorner,Wpf,Adorner,装饰符是在图像的部分上定义的。所需的行为如下所示: 当鼠标位于图像区域(包括装饰器区域)上时,装饰器将出现 当鼠标离开图像和装饰器区域时,装饰器消失 装饰物的出现和消失将相应地通过淡入/淡出动画进行 单击装饰器区域必须引发事件AdornerClicked 单击图像上未被装饰条隐藏的区域,必须将ImageClicked唤醒 一个幼稚的实现 在图像的MouseEnter和MouseLeave事件的装饰器不透明度上附加动画,并为每个事件附加单击事件。但是,当鼠标直接位于装饰条上方时,这会导致装饰条消失

装饰符是在图像的部分上定义的。所需的行为如下所示:

  • 当鼠标位于图像区域(包括装饰器区域)上时,装饰器将出现
  • 当鼠标离开图像和装饰器区域时,装饰器消失
  • 装饰物的出现和消失将相应地通过淡入/淡出动画进行
  • 单击装饰器区域必须引发事件AdornerClicked
  • 单击图像上未被装饰条隐藏的区域,必须将ImageClicked唤醒 一个幼稚的实现

    在图像的MouseEnter和MouseLeave事件的装饰器不透明度上附加动画,并为每个事件附加单击事件。但是,当鼠标直接位于装饰条上方时,这会导致装饰条消失(因为在下图中会触发鼠标删除),这违反了第1条要求

    对naive实现的一个可能的修改是在装饰器上设置ishitestvisible=false。但是,装饰器不会捕获任何点击,这违反了第4条要求


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

    一个有点老的问题,但我刚刚遇到了同样的问题,找不到答案,所以这里是我想到的

    因此,问题是控件及其装饰器重叠,将装饰器设置为可见会触发装饰控件上的鼠标删除,因为它现在已被装饰器覆盖

    解决方案是对修饰控件及其修饰器上的每个MouseEnter和MouseLeave进行反应,并手动执行命中测试。如果其中任何一个被击中,则装饰条应可见,否则会折叠

    因此,您需要能够从装饰控件获取装饰器,反之亦然。从装饰器获取装饰控件没有问题(使用AdorneElement属性),但是框架(AFAIK)不提供为控件获取装饰器,因此我使用字典将控件映射到它们的装饰器列表

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

    private readonly Dictionary\u controlToAdornersMap;
    ...
    私有void CreateMyControl()
    {
    var control=new MyControl();
    control.MouseEnter+=onmycontrolmouseenterLeave;
    control.MouseLeave+=onmycontrolmouseenterrorve;
    添加(对照组);
    地址装饰器(控制);
    }
    专用void addarendors(控件)
    {
    var myAdorner=新的myAdorner(控件);
    myAdorner.MouseEnter+=OnMyAdornerMouseEnterOrLeave;
    myAdorner.MouseLeave+=OnMyAdornerMouseEnterOrLeave;
    var adornerLayer=adornerLayer.GetAdornerLayer(控件);
    添加(myAdorner);
    _controlToAdornersMap[control]=新列表{myAdorner};
    }
    MyControl MouseenterOrleave上的私有void(对象发送方,MouseEventArgs e)
    {
    HitTestAndSetAdornerVisibility((MyControl)发送方,e);
    }
    MyadornerMouseenterOrLeave上的私有void(对象发送方,MouseEventArgs e)
    {
    var adorner=(adorner)发送方;
    HitTestAndSetAdornerVisibility((MyControl)adorner.AdornedElement,e);
    }
    私有void HitTestAndSetAdornerVisibility(MyControl控件,MouseEventArgs e)
    {
    变量装饰器=_controlToAdornersMap[control];
    var hitTestSubjects=新列表{control}.Concat(装饰器);
    var hit=hitTestSubjects.Any(i=>visualtreeheloper.HitTest(i,e.GetPosition(i))!=null);
    SetAdornerVisibility(装饰器,点击?可见性。可见:可见性。折叠);
    }
    私有静态void SetAdornerVisibility(IEnumerable adorners,可见性)
    {
    if(装饰条!=null)
    foreach(装饰器中的var装饰器)
    可见性=可见性;
    }
    
    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;
    }