当前位置: 代码网 > it编程>编程语言>C# > 基于WPF实现3D导航栏控件

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

2024年05月15日 C# 我要评论
wpf实现3d导航框架支持.net4 至 .net8;visual studio 2022;animationnavigationbar3d带有3d效果的导航栏控件的样式。包含多个animationn

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

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com