之前做專案時,為了實現類似微信訊息數目的效果
![WPF Adorner](https://i.iter01.com/images/2556d62c58e69bf56798e36153599ce044c147b6084f0e530a32d285e38cbdb6.webp)
image.png
,我之前是修改的ControlTemplate。類似於將一個帶數字的控制元件,放在另一個控制元件的右上角,來實現的這個效果。
原來WPF有個Adorner,也可以實現這樣的效果。
WPF中很多控制元件,都帶Adorner層。這相當於一個控制元件的裝飾層。我們在這裡面可以做出很多蠻好的效果。比如錯誤提示等。
我們要實現上圖的那種效果,我們可以做一個附加屬性。
public static bool GetShowAdorner(DependencyObject obj) { return (bool)obj.GetValue(ShowAdornerProperty); } public static void SetShowAdorner(DependencyObject obj, bool value) { obj.SetValue(ShowAdornerProperty, value); } public static readonly DependencyProperty ShowAdornerProperty = DependencyProperty.RegisterAttached("ShowAdorner", typeof(bool), typeof(MainWindow), new PropertyMetadata(false, Method)); private static void Method(DependencyObject d, DependencyPropertyChangedEventArgs e) { var ele = d as Visual; var adolay = AdornerLayer.GetAdornerLayer(ele); if (adolay != null) { var ados = adolay.GetAdorners(ele as UIElement); if (ados == null) { adolay.Add(new KDAdorner(ele as UIElement)); } ados = adolay.GetAdorners(ele as UIElement); if (ados != null && ados.Count() != 0) { var ado = ados.FirstOrDefault() as KDAdorner; if ((bool)e.NewValue) { ado.ShowImage(); } else { ado.HideImage(); } } }
繼承Adorner,實現我們想要的Adorner效果
public class KDAdorner : Adorner { private VisualCollection _visuals; private Canvas _grid; private Border _br; public KDAdorner(UIElement ele) : base(ele) { _visuals = new VisualCollection(this); _br = new Border (); _br.CornerRadius= new CornerRadius (50); _br.Background = Brushes.Red; TextBlock _txt = new TextBlock(); _txt.Text = "4"; _txt.Width=_txt.Height = 20; _txt.Foreground = Brushes.White; _txt.TextAlignment = TextAlignment.Center; _br.Child = _txt; _grid = new Canvas(); _grid.Children.Add(_br); _visuals.Add(_grid); } protected override Visual GetVisualChild(int index) { return _visuals[index]; } public void ShowImage() { _grid.Visibility = System.Windows.Visibility.Visible; } public void HideImage() { _grid.Visibility = System.Windows.Visibility.Hidden; } protected override Size ArrangeOverride(Size finalSize) { _grid.Arrange(new Rect(finalSize)); _br.Margin = new Thickness(finalSize.Width - 12.5, -12.5, 0, 0); return base.ArrangeOverride(finalSize); } protected override int VisualChildrenCount { get { return _visuals.Count; } } }
VIew中給需要新增Adorner效果的控制元件,新增附加屬性
![WPF Adorner](https://i.iter01.com/images/584027975e05f5193abc02b7f6d75f977f34feb4ad4a25f7c5ce1f44a5f4ebdf.webp)
image.png
CheckBox繫結了Button的附加屬性,我們可以通過IsChecked,控制Adorner層的顯示,隱藏。
![WPF Adorner](https://i.iter01.com/images/84fc5420f8f2be7f84e12d0d2f20fd0530ec1e8b09f07ac19d63dd9abf4bb4fd.webp)
image.png