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导航的资料请关注代码网其它相关文章!
发表评论