基于WPF实现面包屑控件的示例代码
作者:WPF开发者
这篇文章主要为大家详细介绍了如何基于WPF实现简单的面包屑控件,文中的示例代码讲解详细,对我们学习或工作有一定帮助,感兴趣的小伙伴可以了解一下
WPF 实现面包屑控件
- 框架使用
.NET4 至 .NET6
Visual Studio 2022
- 创建
BreadCrumbBar.xaml
设置VirtualizingStackPanel
为水平方向显示Orientation="Horizontal"
。 - 创建
BreadCrumbBarItem.xaml
设置ContentPresenter
前显示符号>
,通过BreadCrumbBarConvertr
转换器判断如果是当前是第0
个则隐藏显示符>
。 - 创建
BreadCrumbBar.cs
继承ListBox
当选中时获取当前的SelectedIndex
大于当前的设置IsEnabled
设置false
反之则为true
。
实现代码
1)创建 BreadCrumbBar.cs
代码如下:
using System.Collections; using System.Collections.Specialized; using System.Windows; using System.Windows.Controls; namespace WPFDevelopers.Controls { public class BreadCrumbBar : ListBox { static BreadCrumbBar() { DefaultStyleKeyProperty.OverrideMetadata(typeof(BreadCrumbBar), new FrameworkPropertyMetadata(typeof(BreadCrumbBar))); } public override void OnApplyTemplate() { base.OnApplyTemplate(); } protected override void OnSelectionChanged(SelectionChangedEventArgs e) { base.OnSelectionChanged(e); for (int i = 0; i <= SelectedIndex; i++) { var item = (ListBoxItem)ItemContainerGenerator.ContainerFromIndex(i); if (item == null) continue; if (!item.IsEnabled) item.IsEnabled = true; } for (int i = Items.Count - 1; i > SelectedIndex; i--) { var item = (ListBoxItem)ItemContainerGenerator.ContainerFromIndex(i); if (item == null) continue; if(item.IsEnabled) item.IsEnabled = false; } } protected override bool IsItemItsOwnContainerOverride(object item) { return item is BreadCrumbBarItem; } protected override DependencyObject GetContainerForItemOverride() { return new BreadCrumbBarItem(); } } }
2)创建 BreadCrumbBarItem.cs
代码如下:
using System; using System.Windows; using System.Windows.Controls; namespace WPFDevelopers.Controls { public class BreadCrumbBarItem : ListBoxItem { private static readonly Type _typeofSelf = typeof(BreadCrumbBarItem); static BreadCrumbBarItem() { DefaultStyleKeyProperty.OverrideMetadata(_typeofSelf, new FrameworkPropertyMetadata(_typeofSelf)); } } }
3)创建 BreadCrumbBar.xaml
代码如下:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:controls="clr-namespace:WPFDevelopers.Controls" xmlns:converts="clr-namespace:WPFDevelopers.Converts"> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="Basic/ControlBasic.xaml" /> </ResourceDictionary.MergedDictionaries> <converts:BreadCrumbBarConvertr x:Key="WD.BreadCrumbBarConvertr" /> <Style x:Key="WD.BreadCrumbBarItem" BasedOn="{StaticResource WD.ControlBasicStyle}" TargetType="{x:Type controls:BreadCrumbBarItem}"> <Setter Property="VerticalContentAlignment" Value="Center" /> <Setter Property="Padding" Value="6,0" /> <Setter Property="FontWeight" Value="SemiBold" /> <Setter Property="FontSize" Value="{StaticResource WD.TitleFontSize}" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type controls:BreadCrumbBarItem}"> <StackPanel Orientation="Horizontal"> <Path Name="PART_PathSymbol" Width="9" Height="9" Data="{StaticResource WD.BreadCrumbBarGeometry}" Fill="{DynamicResource WD.PlaceholderTextSolidColorBrush}" IsHitTestVisible="False" Stretch="Uniform"> <Path.Visibility> <MultiBinding Converter="{StaticResource WD.BreadCrumbBarConvertr}"> <Binding RelativeSource="{RelativeSource AncestorType=ListBoxItem}" /> <Binding Path="SelectedIndex" RelativeSource="{RelativeSource AncestorType=ListBox}" /> </MultiBinding> </Path.Visibility> </Path> <ContentPresenter x:Name="PART_ContentPresenter" Margin="{TemplateBinding Padding}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" TextElement.Foreground="{TemplateBinding Foreground}" /> </StackPanel> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Foreground" Value="{DynamicResource WD.PrimaryMouseOverSolidColorBrush}" /> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> <Style x:Key="WD.BreadCrumbBar" BasedOn="{StaticResource WD.ControlBasicStyle}" TargetType="{x:Type controls:BreadCrumbBar}"> <Setter Property="Height" Value="40" /> <Setter Property="Margin" Value="5" /> <Setter Property="ItemsPanel"> <Setter.Value> <ItemsPanelTemplate> <VirtualizingStackPanel Orientation="Horizontal" /> </ItemsPanelTemplate> </Setter.Value> </Setter> <Setter Property="ItemContainerStyle" Value="{StaticResource WD.BreadCrumbBarItem}" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type controls:BreadCrumbBar}"> <Border Margin="{TemplateBinding Margin}" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> <ScrollViewer Grid.Column="1" HorizontalScrollBarVisibility="Auto"> <ItemsPresenter x:Name="ItemsHost" /> </ScrollViewer> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> <Style BasedOn="{StaticResource WD.BreadCrumbBar}" TargetType="{x:Type controls:BreadCrumbBar}" /> </ResourceDictionary>
4)创建 BreadCrumbBarConverter.cs
代码如下:
using System; using System.Globalization; using System.Windows; using System.Windows.Controls; using System.Windows.Data; namespace WPFDevelopers.Converts { public class BreadCrumbBarConvertr : IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { var item = values[0] as ListBoxItem; var listBox = ItemsControl.ItemsControlFromItemContainer(item) as ListBox; if (listBox == null) return Visibility.Collapsed; var arrayIndex = listBox.ItemContainerGenerator.IndexFromContainer(item); if (arrayIndex == 0) return Visibility.Collapsed; return Visibility.Visible; } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) { throw new NotImplementedException(); } } }
5)创建 BreadCrumbBarExample.xaml
代码如下:
<Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <wd:BreadCrumbBar DisplayMemberPath="Text" ItemsSource="{Binding BreadcrumbItems, RelativeSource={RelativeSource AncestorType=UserControl}}" SelectedItem="{Binding BreadcrumbItem, RelativeSource={RelativeSource AncestorType=UserControl}}" SelectionChanged="BreadCrumbBar_SelectionChanged" /> <Frame Name="myFrame" Grid.Row="1" NavigationUIVisibility="Hidden" /> <Button Grid.Row="2" Width="80" Click="btnNext_Click" Content="Next" Style="{StaticResource WD.SuccessPrimaryButton}" /> </Grid>
6) BreadCrumbBarExample.xaml.cs
代码如下:
using System.Collections.Generic; using System; using System.Windows.Controls; using System.Collections.ObjectModel; using System.Windows; using System.Reflection; namespace WPFDevelopers.Samples.ExampleViews { /// <summary> /// StepExample.xaml 的交互逻辑 /// </summary> public partial class BreadCrumbBarExample : UserControl { private int index = 0; private List<BreadcrumbItem> Breadcrumbs = new List<BreadcrumbItem>(); public ObservableCollection<BreadcrumbItem> BreadcrumbItems { get { return (ObservableCollection<BreadcrumbItem>)GetValue(BreadcrumbItemsProperty); } set { SetValue(BreadcrumbItemsProperty, value); } } public static readonly DependencyProperty BreadcrumbItemsProperty = DependencyProperty.Register("BreadcrumbItems", typeof(ObservableCollection<BreadcrumbItem>), typeof(BreadCrumbBarExample), new PropertyMetadata(null)); public BreadcrumbItem BreadcrumbItem { get { return (BreadcrumbItem)GetValue(BreadcrumbItemProperty); } set { SetValue(BreadcrumbItemProperty, value); } } public static readonly DependencyProperty BreadcrumbItemProperty = DependencyProperty.Register("BreadcrumbItem", typeof(BreadcrumbItem), typeof(BreadCrumbBarExample), new PropertyMetadata(null)); public BreadCrumbBarExample() { InitializeComponent(); Loaded += BreadCrumbBarExample_Loaded; } private void BreadCrumbBarExample_Loaded(object sender, RoutedEventArgs e) { var breadcrumbItems = new List<BreadcrumbItem>() { new BreadcrumbItem() { Text = "主页" , Uri=new Uri("pack://application:,,,/WPFDevelopers.Samples;component/ExampleViews/DrawerMenu/HomePage.xaml",UriKind.Absolute ) }, new BreadcrumbItem() { Text = "Edge", Uri=new Uri("pack://application:,,,/WPFDevelopers.Samples;component/ExampleViews/DrawerMenu/EdgePage.xaml" ,UriKind.Absolute ) }, new BreadcrumbItem() { Text = "邮件", Uri=new Uri("pack://application:,,,/WPFDevelopers.Samples;component/ExampleViews/DrawerMenu/EmailPage.xaml" ,UriKind.Absolute ) }, }; Breadcrumbs = breadcrumbItems; myFrame.Navigate(Breadcrumbs[index].Uri); BreadcrumbItems = new ObservableCollection<BreadcrumbItem>() { Breadcrumbs[index] }; } private void BreadCrumbBar_SelectionChanged(object sender, SelectionChangedEventArgs e) { myFrame.Navigate(BreadcrumbItem.Uri); index = BreadcrumbItems.IndexOf(BreadcrumbItem); } private void btnNext_Click(object sender, RoutedEventArgs e) { index += 1; if (index >= Breadcrumbs.Count) return; var model = Breadcrumbs[index]; if (BreadcrumbItems.Contains(model)) { BreadcrumbItem = model; return; } BreadcrumbItems.Add(model); BreadcrumbItem = model; } } public class BreadcrumbItem { public string Text { get; set; } public Uri Uri { get; set; } } }
效果图
到此这篇关于基于WPF实现面包屑控件的示例代码的文章就介绍到这了,更多相关WPF面包屑控件内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!