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>
作者:江宁织造
博客:http://www.cnblogs.com/wgx0428/
博客:http://www.cnblogs.com/wgx0428/