基于WPF實現(xiàn)3D導(dǎo)航欄控件
WPF實現(xiàn)3D導(dǎo)航
框架支持.NET4 至 .NET8;
Visual Studio 2022;
AnimationNavigationBar3D 帶有 3D 效果的導(dǎo)航欄控件的樣式。包含多個 AnimationNavigationBar3DItem ,通過 UniformGrid 進(jìn)行排列,超出顯示區(qū)域的項可以滾動查看。
AnimationNavigationBar3DItem 繼承 ListBboxItem 是 3D 導(dǎo)航欄中的每個項。使用 Viewport3D 來創(chuàng)建一個具有 3D 效果的容器,當(dāng)鼠標(biāo)移入或移出時,旋轉(zhuǎn)動畫來改變項的外觀。它包含一個正面 Background 和一個背面 ContentBack ,可以顯示不同的內(nèi)容。使用可以根據(jù)需要自定義內(nèi)容,如果在每個項中只設(shè)置了正面內(nèi)容而沒有設(shè)置背面內(nèi)容,那么背面會自動克隆 GetXmlReader 并顯示與正面相同的內(nèi)容。
GetXmlReader 用于通過將 UIElement 對象轉(zhuǎn)換為 XML 字符串,再將其轉(zhuǎn)換回 UIElement 對象,實現(xiàn)對 UIElement 對象的克隆。
實現(xiàn)代碼
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實現(xiàn)3D導(dǎo)航欄控件的詳細(xì)內(nèi)容,更多關(guān)于WPF導(dǎo)航的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C#無法打開計算機(jī)“.”上的 IISADMIN 服務(wù)的解決方法
在使用c#進(jìn)行控制IIS服務(wù)啟動停止的時候,提示:無法打開計算機(jī)“.”上的 IISADMIN 服務(wù)2015-01-01
DevExpress根據(jù)條件設(shè)置GridControl RepositoryItem是否可編輯
這篇文章主要介紹了DevExpress根據(jù)條件設(shè)置GridControl RepositoryItem是否可編輯,需要的朋友可以參考下2014-08-08
c# List find()方法返回值的問題說明(返回結(jié)果為對象的指針)
本篇文章主要介紹了c#中List find()方法返回值的問題說明(返回結(jié)果為對象的指針) 需要的朋友可以過來參考下,希望對大家有所幫助2014-01-01
C#使用OpenCvSharp4實現(xiàn)讀取本地視頻
OpenCvSharp4庫是一個基于.Net封裝的OpenCV庫,這篇文章主要介紹了C#使用OpenCvSharp4實現(xiàn)讀取本地視頻的詳細(xì)教程,有需要的小伙伴可以參考下2024-01-01

