基于WPF实现面包屑控件的示例代码

 更新时间:2023年05月17日 10:08:16   作者: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面包屑控件内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C# AttributeUsage使用案例详解

    C# AttributeUsage使用案例详解

    这篇文章主要介绍了C# AttributeUsage使用案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • 新手小白用C# winform 读取Excel表的实现

    新手小白用C# winform 读取Excel表的实现

    这篇文章主要介绍了新手小白用C# winform 读取Excel表的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • DevExpress之ChartControl的SeriesTemplate实例

    DevExpress之ChartControl的SeriesTemplate实例

    这篇文章主要介绍了DevExpress之ChartControl的SeriesTemplate用法实例,实现了饼状Series百分比显示的效果,具有一定的参考借鉴价值,需要的朋友可以参考下
    2014-10-10
  • C#程序连接数据库及读取数据库中字段的简单方法总结

    C#程序连接数据库及读取数据库中字段的简单方法总结

    包括C#连接Access、Oracle或者SQL Server,这里整理了一些C#连接数据库及从读取数据库中字段的简单方法总结,需要的朋友可以参考下
    2016-05-05
  • 探秘C# 6.0 的新特性

    探秘C# 6.0 的新特性

    本文的内容包括引入C#6.0中的新的语言特性有哪些. 还有已经被引入的代码名称为 “Roslyn”新编译器. 编译器是开放源码的,并且可以从 codeplex 网站的这个地址下载到源代码:https://roslyn.codeplex.com/.
    2015-03-03
  • C#修改及重置电脑密码DirectoryEntry实现方法

    C#修改及重置电脑密码DirectoryEntry实现方法

    这篇文章主要介绍了C#修改及重置电脑密码DirectoryEntry实现方法,实例分析了C#修改及重置电脑密码的相关技巧,需要的朋友可以参考下
    2015-05-05
  • Unity实现鼠标拖动3D物体

    Unity实现鼠标拖动3D物体

    这篇文章主要为大家详细介绍了Unity实现鼠标拖动3D物体,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-10-10
  • Unity实现截图功能

    Unity实现截图功能

    这篇文章主要为大家详细介绍了Unity实现截图功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-04-04
  • C#语言MVC框架Aspose.Cells控件导出Excel表数据

    C#语言MVC框架Aspose.Cells控件导出Excel表数据

    这篇文章主要为大家详细介绍了C#语言MVC框架Aspose.Cells控件导出Excel表数据,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-12-12
  • C#枚举中的位运算权限分配浅谈

    C#枚举中的位运算权限分配浅谈

    本文介绍C#位运算的处理方法,第一步, 先建立一个枚举表示所有的权限管理操作,接下来是权限的运算等。
    2013-05-05

最新评论