WPF Adorner的应用,装饰ListBoxItem选中后的样式

1.效果图:

2.参考资料:

https://www.cnblogs.com/HelloMyWorld/p/3965177.html

3.代码实例

    /// <summary>
    /// 装饰附加属性
    /// https://www.cnblogs.com/HelloMyWorld/p/3965177.html
    /// </summary>
    public class AdornerAttachProperty
    {
        /// <summary>
        /// 获取有装饰器
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static bool GetHasAdorner(DependencyObject obj)
        {
            return (bool)obj.GetValue(HasAdornerProperty);
        }

        /// <summary>
        /// 设置有装饰器
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="value"></param>
        public static void SetHasAdorner(DependencyObject obj, bool value)
        {
            obj.SetValue(HasAdornerProperty, value);
        }

        /// <summary>
        /// 有装饰器
        /// </summary>
        public static readonly DependencyProperty HasAdornerProperty =
            DependencyProperty.RegisterAttached("HasAdorner", typeof(bool), typeof(AdornerAttachProperty), new PropertyMetadata(false, PropertyChangedCallBack));

        /// <summary>
        /// 属性改变回调函数
        /// </summary>
        /// <param name="d"></param>
        /// <param name="e"></param>
        private static void PropertyChangedCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if ((bool)e.NewValue == false)
            {
                return;
            }

            var element = d as Visual;
            if (element == null)
            {
                return;
            }

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

            var adorners = adornerLayer.GetAdorners(element as UIElement);
            if (adorners == null || adorners.Length < 1)
            {
                adornerLayer.Add(new ListBoxItemAdorner(element as UIElement));
            }
        }

        /// <summary>
        /// 获取是否显示装饰器
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static bool GetIsShowAdorner(DependencyObject obj)
        {
            return (bool)obj.GetValue(IsShowAdornerProperty);
        }

        /// <summary>
        /// 设置是否显示装饰器
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="value"></param>
        public static void SetIsShowAdorner(DependencyObject obj, bool value)
        {
            obj.SetValue(IsShowAdornerProperty, value);
        }

        /// <summary>
        /// 是否显示装饰器
        /// </summary>
        public static readonly DependencyProperty IsShowAdornerProperty =
            DependencyProperty.RegisterAttached("IsShowAdorner", typeof(bool), typeof(AdornerAttachProperty), new PropertyMetadata(false, IsShowChangedCallBack));

        /// <summary>
        /// 是否显示改变回调函数
        /// </summary>
        /// <param name="d"></param>
        /// <param name="e"></param>
        private static void IsShowChangedCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var element = d as UIElement;
            if (element == null)
            {
                return;
            }

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

            var adorners = adornerLayer.GetAdorners(element);
            if (adorners == null || adorners.Length < 1)
            {
                return;
            }

            var adorner = adorners[0] as ListBoxItemAdorner;
            if (adorner == null)
            {
                return;
            }

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

    }
    /// <summary>
    /// 列表项装饰器
    /// </summary>
    public class ListBoxItemAdorner:Adorner
    {
        private VisualCollection _visuals;
        private Canvas _grid;
        private Image _image;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="adornedElement"></param>
        public ListBoxItemAdorner(UIElement adornedElement) : base(adornedElement)
        {
            _visuals = new VisualCollection(this);
            _image = new Image() { Source = new BitmapImage(new Uri("pack://application:,,,/Resources/duihao.png", UriKind.RelativeOrAbsolute)), Width = 19, Height = 19 };
            _grid = new Canvas();
            _grid.Children.Add(_image);

            _visuals.Add(_grid);
        }

        /// <summary>
        /// 显示装饰
        /// </summary>
        public void ShowAdorner()
        {
            _image.Visibility = Visibility.Visible;
        }

        /// <summary>
        /// 隐藏装饰
        /// </summary>
        public void HideAdorner()
        {
            _image.Visibility = Visibility.Collapsed;
        }

        /// <summary>
        /// 可视化子元素数量
        /// </summary>
        protected override int VisualChildrenCount => _visuals.Count;

        /// <summary>
        /// 获取可视化子元素
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        protected override Visual GetVisualChild(int index)
        {
            return _visuals[index];
        }

        /// <summary>
        /// 测量大小
        /// </summary>
        /// <param name="constraint"></param>
        /// <returns></returns>
        protected override Size MeasureOverride(Size constraint)
        {
            return base.MeasureOverride(constraint);
        }

        /// <summary>
        /// 定位子元素并确定大小
        /// </summary>
        /// <param name="finalSize"></param>
        /// <returns></returns>
        protected override Size ArrangeOverride(Size finalSize)
        {
            _grid.Arrange(new Rect(finalSize));
            _image.Margin = new Thickness(finalSize.Width - 21, 0, 0, 0);//_image.Margin = new Thickness(finalSize.Width - 12.5, -12.5, 0, 0);

            return base.ArrangeOverride(finalSize);
        }

    }

4.xaml ListBox模板样式

<Style x:Key="ListBoxItemCustomer" TargetType="ListBoxItem">
        <Setter Property="OverridesDefaultStyle" Value="True" />
        <Setter Property="SnapsToDevicePixels" Value="True" />
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="Foreground" Value="{DynamicResource ItemText}" />
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="BorderBrush" Value="{DynamicResource ItemBorder}"/>
        <Setter Property="HorizontalContentAlignment" Value="Left"/>
        <Setter Property="VerticalContentAlignment" Value="Center"/>
        <Setter Property="Margin" Value="5"/>
        <Setter Property="Padding" Value="2"/>
        <!--<Setter Property="FocusVisualStyle" Value="{x:Null}" />-->
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBoxItem">
                    <Border Name="Bd"
                            Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}"
                            Padding="{TemplateBinding Padding}"
                            CornerRadius="2"
                            local:AdornerAttachProperty.HasAdorner="False"
                            local:AdornerAttachProperty.IsShowAdorner="False"
                            SnapsToDevicePixels="true">
                        
                            <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                          VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                          SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="true">
                            <Setter TargetName="Bd" Property="Background" Value="{DynamicResource ItemBackgroundHover}"/>
                            <Setter Property="Foreground" Value="{DynamicResource ItemTextHover}" />
                        </Trigger>
                        <Trigger Property="IsSelected" Value="true">
                            <Setter TargetName="Bd" Property="BorderBrush" Value="{DynamicResource ItemSelectedBackground}"/>
                            <Setter TargetName="Bd" Property="BorderThickness" Value="2"/>
                            <Setter TargetName="Bd" Property="CornerRadius" Value="5"/>
                            <Setter TargetName="Bd" Property="local:AdornerAttachProperty.HasAdorner" Value="True"/>
                            <Setter TargetName="Bd" Property="local:AdornerAttachProperty.IsShowAdorner" Value="True"/>
                        </Trigger>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Foreground" Value="{DynamicResource ItemTextDisabled}"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

5.ListBox 列表UIxaml代码

<UserControl x:Class="FirstFloor.ModernUI.App.Content.ControlsStylesAdornerItemsControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:mui="http://firstfloorsoftware.com/ModernUI"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    
    <Grid Style="{StaticResource ContentRoot}">
        <ListBox x:Name="iconList" Grid.Row="0" Grid.Column="0" ItemsSource="{Binding Path=Users}" 
                     SelectionMode="Multiple"
                     ItemContainerStyle="{DynamicResource ListBoxItemCustomer}" >
            <ListBox.Template>
                <ControlTemplate TargetType="{x:Type ListBox}">
                    <ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
                        <WrapPanel Orientation="Horizontal" IsItemsHost="True" ScrollViewer.CanContentScroll="True" Margin="5" />
                    </ScrollViewer>
                </ControlTemplate>
            </ListBox.Template>
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <Border BorderBrush="#cccccc" BorderThickness="1" Margin="0">
                            <StackPanel Width="50" Height="50"  Background="#EBEBEB" Margin="0"   >
                                <Image Source="pack://application:,,,/Resources/UserCard01.png" Width="40" Height="40" Margin="2"   />
                            </StackPanel>
                        </Border>
                        <StackPanel Orientation="Vertical" Margin="5,0" VerticalAlignment="Center" >
                            <StackPanel Orientation="Horizontal" Margin="0,0,0,0">
                                <TextBlock Text="账户:" />
                                <TextBlock Text="{Binding Account}" Margin="0,0,10,0" />
                            </StackPanel>
                            <StackPanel Orientation="Horizontal" Margin="0,0,0,0">
                                <TextBlock Text="姓名:" />
                                <TextBlock Text="{Binding RealName}" Margin="0,0,10,0" />
                            </StackPanel>
                            <StackPanel Orientation="Horizontal" Margin="0,0,0,0">
                                <TextBlock Text="部门:" />
                                <TextBlock Text="{Binding DepartmentName}" Margin="0,0,10,0"/>
                            </StackPanel>
                        </StackPanel>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</UserControl>
原文地址:https://www.cnblogs.com/wgx0428/p/14164088.html