WPF Adorner的應用,裝飾ListBoxItem選中後的樣式
阿新 • • 發佈:2020-12-20
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>