基于WPF实现3D导航栏控件
wpF实现3D导航
框架支持.NET4 至 .NET8;
Visual Studio 2022;
AnimationNavigationBar3D 带有 3D 效果的导航栏控件的样式。包含多个 AnimationNavigationBar3DItem ,通过 UniformGrid 进行排列,超出显示区域的项可以滚动查看。
AnimationNavigationBar3DItem 继承 ListBboxItem 是&nbpythonsp;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://FTkwBpKschemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:WPFDevelopers.Controls">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Basic/ControlBasic.xaml" />
<ResourceDictionary Source="Basic/Animations.xaml" />
</ResourceDictio编程nary.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"
HorandroidizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
SnapsToDeviceP编程ixels="{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导航的资料请关注编程客栈(www.devze.com)其它相关文章!
加载中,请稍侯......
精彩评论