基于WPF实现3D导航栏控件

 更新时间:2024年03月26日 10:00:31   作者:WPF开发者  
这篇文章主要介绍了如何基于WPF实现简单的3D导航栏控件效果,文中的示例代码讲解详细,对我们的学习或工作有一定帮助,需要的小伙伴可以参考一下

WPF实现3D导航

框架支持.NET4 至 .NET8

Visual Studio 2022;

AnimationNavigationBar3D 带有 3D 效果的导航栏控件的样式。包含多个 AnimationNavigationBar3DItem ,通过 UniformGrid 进行排列,超出显示区域的项可以滚动查看。

AnimationNavigationBar3DItem 继承 ListBboxItem 是 3D 导航栏中的每个项。使用 Viewport3D 来创建一个具有 3D 效果的容器,当鼠标移入或移出时,旋转动画来改变项的外观。它包含一个正面 Background 和一个背面 ContentBack ,可以显示不同的内容。使用可以根据需要自定义内容,如果在每个项中只设置了正面内容而没有设置背面内容,那么背面会自动克隆 GetXmlReader 并显示与正面相同的内容。

GetXmlReader 用于通过将 UIElement 对象转换为 XML 字符串,再将其转换回 UIElement 对象,实现对 UIElement 对象的克隆。

实现代码

1)新增 AnimationNavigationBar3D.cs 代码如下:

    public class AnimationNavigationBar3D : ListBox
    {
        static AnimationNavigationBar3D()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(AnimationNavigationBar3D),
                new FrameworkPropertyMetadata(typeof(AnimationNavigationBar3D)));
        }
        protected override bool IsItemItsOwnContainerOverride(object item)
        {
            return item is AnimationNavigationBar3DItem;
        }
        protected override DependencyObject GetContainerForItemOverride()
        {
            return new AnimationNavigationBar3DItem();
        }
    }

2)新增 AnimationNavigationBar3DItem.cs 代码如下:

    public class AnimationNavigationBar3DItem : ListBoxItem
    {
        public static readonly DependencyProperty FillProperty =
            DependencyProperty.Register("Fill", typeof(Brush), typeof(AnimationNavigationBar3DItem),
                new PropertyMetadata(null));

        public static readonly DependencyProperty ContentBackProperty =
            DependencyProperty.Register("ContentBack", typeof(object), typeof(AnimationNavigationBar3DItem),
                new PropertyMetadata(null));

        static AnimationNavigationBar3DItem()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(AnimationNavigationBar3DItem),
                new FrameworkPropertyMetadata(typeof(AnimationNavigationBar3DItem)));
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            if (ContentBack == null) 
                ContentBack = ControlsHelper.GetXmlReader(Content);
        }

        /// <summary>
        ///  Color fore
        /// </summary>
        public Brush Fill
        {
            get => (Brush)GetValue(FillProperty);
            set => SetValue(FillProperty, value);
        }

        /// <summary>
        ///  The content after the mouse is moved in
        /// </summary>
        public object ContentBack
        {
            get => (object)GetValue(ContentBackProperty);
            set => SetValue(ContentBackProperty, value);
        }
    }

3)新增 AnimationNavigationBar3D.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">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="Basic/ControlBasic.xaml" />
        <ResourceDictionary Source="Basic/Animations.xaml" />
    </ResourceDictionary.MergedDictionaries>
    <Style
        x:Key="WD.AnimationNavigationBar3DItem"
        BasedOn="{StaticResource WD.ControlBasicStyle}"
        TargetType="{x:Type controls:AnimationNavigationBar3DItem}">
        <Setter Property="Width" Value="80" />
        <Setter Property="Height" Value="80" />
        <Setter Property="HorizontalContentAlignment" Value="Center" />
        <Setter Property="VerticalContentAlignment" Value="Center" />
        <Setter Property="Foreground" Value="{DynamicResource WD.WindowForegroundColorBrush}" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type controls:AnimationNavigationBar3DItem}">
                    <Viewport3D Width="{TemplateBinding Height}" Height="{TemplateBinding Width}">
                        <Viewport3D.Triggers>
                            <EventTrigger RoutedEvent="MouseEnter">
                                <BeginStoryboard>
                                    <Storyboard Storyboard.TargetName="axis3d" Storyboard.TargetProperty="Angle">
                                        <DoubleAnimation
                                            EasingFunction="{StaticResource WD.CubicEaseInOut}"
                                            To="90"
                                            Duration="00:00:1" />
                                    </Storyboard>
                                </BeginStoryboard>
                            </EventTrigger>
                            <EventTrigger RoutedEvent="MouseLeave">
                                <BeginStoryboard>
                                    <Storyboard Storyboard.TargetName="axis3d" Storyboard.TargetProperty="Angle">
                                        <DoubleAnimation
                                            EasingFunction="{StaticResource WD.CubicEaseInOut}"
                                            To="0"
                                            Duration="00:00:1" />
                                    </Storyboard>
                                </BeginStoryboard>
                            </EventTrigger>
                        </Viewport3D.Triggers>
                        <Viewport3D.Camera>
                            <OrthographicCamera
                                LookDirection="0,0,-100"
                                Position="0,0,100"
                                UpDirection="0,1,0" />
                        </Viewport3D.Camera>
                        <Viewport3D.Children>
                            <ModelVisual3D>
                                <ModelVisual3D.Content>
                                    <AmbientLight Color="{DynamicResource WD.BackgroundColor}" />
                                </ModelVisual3D.Content>
                            </ModelVisual3D>
                            <ContainerUIElement3D>
                                <ContainerUIElement3D.Transform>
                                    <RotateTransform3D>
                                        <RotateTransform3D.Rotation>
                                            <AxisAngleRotation3D
                                                x:Name="axis3d"
                                                Angle="0"
                                                Axis="1 0 0" />
                                        </RotateTransform3D.Rotation>
                                    </RotateTransform3D>
                                </ContainerUIElement3D.Transform>
                                <Viewport2DVisual3D>
                                    <Viewport2DVisual3D.Material>
                                        <DiffuseMaterial Viewport2DVisual3D.IsVisualHostMaterial="True" />
                                    </Viewport2DVisual3D.Material>
                                    <Viewport2DVisual3D.Geometry>
                                        <MeshGeometry3D
                                            Positions="-1,1,1    -1,-1,1   1,-1,1    1,1,1"
                                            TextureCoordinates="0,0   0,1     1,1  1,0"
                                            TriangleIndices="0 1 2 0 2 3" />
                                    </Viewport2DVisual3D.Geometry>
                                    <Border
                                        Width="110"
                                        Height="110"
                                        Background="{TemplateBinding Background}"
                                        CornerRadius="0,0,0,0">
                                        <ContentPresenter
                                            x:Name="PART_ContentPresenter"
                                            HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                            VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                            SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                            TextElement.Foreground="{TemplateBinding Foreground}" />
                                    </Border>
                                </Viewport2DVisual3D>
                                <Viewport2DVisual3D>
                                    <Viewport2DVisual3D.Material>
                                        <DiffuseMaterial Viewport2DVisual3D.IsVisualHostMaterial="True" />
                                    </Viewport2DVisual3D.Material>
                                    <Viewport2DVisual3D.Geometry>
                                        <MeshGeometry3D
                                            Positions="-1,1,1  1,1,1   1,1,-1   -1,1,-1"
                                            TextureCoordinates="0,0   0,1   1,1  1,0"
                                            TriangleIndices="0 1 2 0 2 3" />
                                    </Viewport2DVisual3D.Geometry>
                                    <Border
                                        Width="110"
                                        Height="110"
                                        Background="{TemplateBinding Fill}"
                                        CornerRadius="0,0,0,0"
                                        RenderTransformOrigin="0.5,0.5">
                                        <Border.RenderTransform>
                                            <TransformGroup>
                                                <RotateTransform Angle="90" />
                                            </TransformGroup>
                                        </Border.RenderTransform>
                                        <ContentPresenter
                                            HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                            VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                            Content="{Binding ContentBack, RelativeSource={RelativeSource AncestorType={x:Type controls:AnimationNavigationBar3DItem}}}"
                                            SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                            TextElement.Foreground="{TemplateBinding Foreground}" />
                                    </Border>
                                </Viewport2DVisual3D>
                            </ContainerUIElement3D>
                        </Viewport3D.Children>
                    </Viewport3D>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <Style
        x:Key="WD.AnimationNavigationBar3D"
        BasedOn="{StaticResource WD.ControlBasicStyle}"
        TargetType="{x:Type controls:AnimationNavigationBar3D}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type controls:AnimationNavigationBar3D}">
                    <Border
                        Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}"
                        SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                        UseLayoutRounding="{TemplateBinding UseLayoutRounding}">
                        <ScrollViewer VerticalScrollBarVisibility="Auto">
                            <ItemsPresenter />
                        </ScrollViewer>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Setter Property="ItemsPanel">
            <Setter.Value>
                <ItemsPanelTemplate>
                    <UniformGrid Columns="{Binding Items.Count, RelativeSource={RelativeSource AncestorType={x:Type controls:AnimationNavigationBar3D}}}" />
                </ItemsPanelTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <Style BasedOn="{StaticResource WD.AnimationNavigationBar3DItem}" TargetType="{x:Type controls:AnimationNavigationBar3DItem}" />
    <Style BasedOn="{StaticResource WD.AnimationNavigationBar3D}" TargetType="{x:Type controls:AnimationNavigationBar3D}" />
</ResourceDictionary>

4)新增 GetXmlReader.cs 代码如下:

 public static object GetXmlReader(object Content)
 {
     var originalContent = Content as UIElement;
     string contentXaml = XamlWriter.Save(originalContent);
     using (StringReader stringReader = new StringReader(contentXaml))
     {
         using (XmlReader xmlReader = XmlReader.Create(stringReader))
         {
             object clonedContent = XamlReader.Load(xmlReader);

             if (clonedContent is UIElement clonedElement)
             {
                 return clonedElement;
             }
         }
     }
     return null;
 }

5)新增 AnimationNavigationBar3D.xaml 示例代码如下:

<wd:AnimationNavigationBar3D VerticalAlignment="Bottom">
    <wd:AnimationNavigationBar3DItem Background="#E21854" Fill="#FD3574">
        <StackPanel VerticalAlignment="Center">
            <Path
                Width="40"
                Height="40"
                Data="{StaticResource WD.SmileyOutlineGeometry}"
                Fill="{DynamicResource WD.WindowForegroundColorBrush}"
                Stretch="Uniform" />
            <TextBlock HorizontalAlignment="Center" Text="Emoji" />
        </StackPanel>
    </wd:AnimationNavigationBar3DItem>
    <wd:AnimationNavigationBar3DItem Background="#41A545" Fill="#5EECA6">
        <StackPanel VerticalAlignment="Center">
            <Path
                Width="40"
                Height="40"
                Data="{StaticResource WD.BusGeometry}"
                Fill="{DynamicResource WD.WindowForegroundColorBrush}"
                Stretch="Uniform" />
            <TextBlock HorizontalAlignment="Center" Text="Bus" />
        </StackPanel>
    </wd:AnimationNavigationBar3DItem>
    <wd:AnimationNavigationBar3DItem Background="#0A58F0" Fill="#3A7DFE">
        <StackPanel VerticalAlignment="Center">
            <Path
                Width="40"
                Height="40"
                Data="{StaticResource WD.FriendGeometry}"
                Fill="{DynamicResource WD.WindowForegroundColorBrush}"
                Stretch="Uniform" />
            <TextBlock HorizontalAlignment="Center" Text="Friend" />
        </StackPanel>
    </wd:AnimationNavigationBar3DItem>
    <wd:AnimationNavigationBar3DItem Background="#5F0574" Fill="#8E1FA4">
        <StackPanel VerticalAlignment="Center">
            <Path
                Width="40"
                Height="40"
                Data="{StaticResource WD.AlarmClockGeometry}"
                Fill="{DynamicResource WD.WindowForegroundColorBrush}"
                Stretch="Uniform" />
            <TextBlock HorizontalAlignment="Center" Text="Clock" />
        </StackPanel>
    </wd:AnimationNavigationBar3DItem>
    <wd:AnimationNavigationBar3DItem Background="#1F0355" Fill="#5B31AD">
        <wd:AnimationNavigationBar3DItem.Content>
            <StackPanel VerticalAlignment="Center">
                <Path
                    Width="40"
                    Height="40"
                    Data="{StaticResource WD.BuildingRegularGeometry}"
                    Fill="{DynamicResource WD.WindowForegroundColorBrush}"
                    Stretch="Uniform" />
                <TextBlock HorizontalAlignment="Center" Text="Regular" />
            </StackPanel>
        </wd:AnimationNavigationBar3DItem.Content>
        <wd:AnimationNavigationBar3DItem.ContentBack>
            <StackPanel VerticalAlignment="Center">
                <Path
                    Width="40"
                    Height="40"
                    Data="{StaticResource WD.BuildingRegularGeometry}"
                    Fill="{DynamicResource WD.WindowForegroundColorBrush}"
                    Stretch="Uniform" />
                <TextBlock HorizontalAlignment="Center" Text="建筑" />
            </StackPanel>
        </wd:AnimationNavigationBar3DItem.ContentBack>
    </wd:AnimationNavigationBar3DItem>
</wd:AnimationNavigationBar3D>

效果图

以上就是基于WPF实现3D导航栏控件的详细内容,更多关于WPF导航的资料请关注脚本之家其它相关文章!

相关文章

  • C#无法打开计算机“.”上的 IISADMIN 服务的解决方法

    C#无法打开计算机“.”上的 IISADMIN 服务的解决方法

    在使用c#进行控制IIS服务启动停止的时候,提示:无法打开计算机“.”上的 IISADMIN 服务
    2015-01-01
  • C#版Tesseract库的使用技巧

    C#版Tesseract库的使用技巧

    本文给大家分享C#版Tesseract库的使用技巧,在这里大家需要注意一下tesseract的识别语言包要自己下载后包含到项目里面,并设置为始终复制,或者直接把这个文件包放到运行程序目录(bin\debug)下的,具体实现代码跟随小编一起学习下吧
    2021-05-05
  • RabbitMQ的配置与安装教程全纪录

    RabbitMQ的配置与安装教程全纪录

    这篇文章主要给大家介绍了关于RabbitMQ的配置与安装的相关资料,文中通过示例代码以及图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-07-07
  • C#中逆变的实际应用场景详解

    C#中逆变的实际应用场景详解

    在好多的.net的书籍中都看到过逆变和协变的概念,也在网上搜了一些关于这两个概念的解释,但是一直感觉似懂非懂的,直到最近在项目中实际遇到了一个问题,恰好用到了逆变,下面这篇文章主要给大家介绍了关于C#中逆变的实际应用场景,需要的朋友可以参考下
    2022-01-01
  • Untiy Shader实现纹理贴图滚动

    Untiy Shader实现纹理贴图滚动

    这篇文章主要为大家详细介绍了Untiy Shader实现纹理贴图滚动,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-03-03
  • DevExpress根据条件设置GridControl RepositoryItem是否可编辑

    DevExpress根据条件设置GridControl RepositoryItem是否可编辑

    这篇文章主要介绍了DevExpress根据条件设置GridControl RepositoryItem是否可编辑,需要的朋友可以参考下
    2014-08-08
  • c# List find()方法返回值的问题说明(返回结果为对象的指针)

    c# List find()方法返回值的问题说明(返回结果为对象的指针)

    本篇文章主要介绍了c#中List find()方法返回值的问题说明(返回结果为对象的指针) 需要的朋友可以过来参考下,希望对大家有所帮助
    2014-01-01
  • C#使用OpenCvSharp4实现读取本地视频

    C#使用OpenCvSharp4实现读取本地视频

    OpenCvSharp4库是一个基于.Net封装的OpenCV库,这篇文章主要介绍了C#使用OpenCvSharp4实现读取本地视频的详细教程,有需要的小伙伴可以参考下
    2024-01-01
  • 使用winapi安装Windows服务示例程序

    使用winapi安装Windows服务示例程序

    这篇文章主要介绍了使用winapi安装Windows服务示例,大家参考使用吧
    2014-01-01
  • Unity多语言转换工具的实现

    Unity多语言转换工具的实现

    这篇文章主要为大家详细介绍了Unity多语言转换工具的实现,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-06-06

最新评论