您的位置:首页 > 其它

WPF 附加属性的用法 (二)

2017-03-15 11:52 246 查看


无论是在验证啊,还是提示方面等一些右上角的角标之类的效果,我们会怎么做?

这里介绍一种稍微简单一些的方法,利用附加属性和Adorner来完成。

例如WPF自带的控件上要加这样的效果,首先继承自原控件然后重写是可以的,但是控件类型太多,重写不过来。这个时候我们唯一能添加的只有附加属性了。

利用附加属性的属性变更事件PropertyChangedCallBack,我们可以获取到宿主对象即Button,然后就可以往Button上加入我们自定义的Adorner了。再添加一个附加属性控制Adorner的显示/隐藏,那么就很完美了,这样每个控件只用设置两个附加属性就能拥有上面的效果。下面是核心代码,

附加属性

public class AdornerHelper
{
#region 是否有Adorner
public static bool GetHasAdorner(DependencyObject obj)
{
return (bool)obj.GetValue(HasAdornerProperty);
}

public static void SetHasAdorner(DependencyObject obj, bool value)
{
obj.SetValue(HasAdornerProperty, value);
}

// Using a DependencyProperty as the backing store for HasAdorner.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty HasAdornerProperty =
DependencyProperty.RegisterAttached("HasAdorner", typeof(bool), typeof(AdornerHelper), new PropertyMetadata(false, PropertyChangedCallBack));

private static void PropertyChangedCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if ((bool)e.NewValue)
{
var element = d as Visual;

if (element != null)
{
var adornerLayer = AdornerLayer.GetAdornerLayer(element);

if (adornerLayer!=null)
{
adornerLayer.Add(new NotifyAdorner(element as UIElement));
}
}
}
}
#endregion

#region 是否显示Adorner

public static bool GetIsShowAdorner(DependencyObject obj)
{
return (bool)obj.GetValue(IsShowAdornerProperty);
}

public static void SetIsShowAdorner(DependencyObject obj, bool value)
{
obj.SetValue(IsShowAdornerProperty, value);
}

// Using a DependencyProperty as the backing store for IsShowAdorner.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsShowAdornerProperty =
DependencyProperty.RegisterAttached("IsShowAdorner", typeof(bool), typeof(AdornerHelper), new PropertyMetadata(false,IsShowChangedCallBack));

private static void IsShowChangedCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var element = d as UIElement;

if (element != null)
{
var adornerLayer = AdornerLayer.GetAdornerLayer(element);
if (adornerLayer!=null)
{
var adorners = adornerLayer.GetAdorners(element);
if (adorners != null && adorners.Count() != 0)
{
var adorner = adorners.FirstOrDefault() as NotifyAdorner;

if (adorner == null)
{
return;
}

if ((bool)e.NewValue)
{
adorner.ShowAdorner();
}
else
{
adorner.HideAdorner();
}
}
}
}
}

#endregion
}


然后是我们自定义的Adorner效果

public class NotifyAdorner : Adorner
{
private VisualCollection _visuals;
private Canvas _grid;
private Image _image;

public NotifyAdorner(UIElement adornedElement)
: base(adornedElement)
{
_visuals = new VisualCollection(this);
_image=new Image()
{
Source = new BitmapImage(new Uri("Notify.png",UriKind.RelativeOrAbsolute)),
Width = 25,
Height = 25
};

_grid = new Canvas();
_grid.Children.Add(_image);

_visuals.Add(_grid);
}

public void ShowAdorner()
{
_image.Visibility = Visibility.Visible;
}

public void HideAdorner()
{
_image.Visibility = Visibility.Collapsed;
}

protected override int VisualChildrenCount
{
get
{
return _visuals.Count;
}
}

protected override Visual GetVisualChild(int index)
{
return _visuals[index];
}

protected override Size MeasureOverride(Size constraint)
{
return base.MeasureOverride(constraint);
}

protected override Size ArrangeOverride(Size finalSize)
{
_grid.Arrange(new Rect(finalSize));

_image.Margin=new Thickness(finalSize.Width-12.5,-12.5,0,0);

return base.ArrangeOverride(finalSize);
}

}


WPF Adorner+附加属性 实现控件友好提示 原文:http://www.cnblogs.com/HelloMyWorld/p/3965177.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: