it编程 > App开发 > Windows Phone

WPF仿Tabcontrol实现切换多个不同View

221人参与 2024-12-01 Windows Phone

在同一块区域显示不同的视图内容,直接使用tabcontrol,可能要重写tabitem的控件模板,最直接的方法通过按钮的切换,控制一个contentcontrol的content值,实现切换不同的视图view。以下是一个简单的实现demo。注:如果用prism的框架实现,只要设置region的区域块显示,会更简单一些,至少不用自己实现。

1、viewa:

<usercontrol x:class="test.viewa"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:test"
             mc:ignorable="d" 
             d:designheight="450" d:designwidth="800">
    <usercontrol.resources>
        <solidcolorbrush x:key="tabcontrolnormalborderbrush" color="#8c8e94"/>
        <style x:key="tabcontrolstyle1" targettype="{x:type tabcontrol}">
            <setter property="foreground" value="{dynamicresource {x:static systemcolors.controltextbrushkey}}"/>
            <setter property="padding" value="4,4,4,4"/>
            <setter property="borderthickness" value="1"/>
            <setter property="borderbrush" value="{staticresource tabcontrolnormalborderbrush}"/>
            <setter property="background" value="#f9f9f9"/>
            <setter property="horizontalcontentalignment" value="center"/>
            <setter property="verticalcontentalignment" value="center"/>
            <setter property="template">
                <setter.value>
                    <controltemplate targettype="{x:type tabcontrol}">
                        <grid cliptobounds="true" snapstodevicepixels="true" keyboardnavigation.tabnavigation="local">
                            <grid.columndefinitions>
                                <columndefinition x:name="columndefinition0"/>
                                <columndefinition x:name="columndefinition1" width="0"/>
                            </grid.columndefinitions>
                            <grid.rowdefinitions>
                                <rowdefinition x:name="rowdefinition0" height="auto"/>
                                <rowdefinition x:name="rowdefinition1" height="*"/>
                            </grid.rowdefinitions>
                            <tabpanel x:name="headerpanel" grid.column="0" isitemshost="true" margin="2,2,2,0" grid.row="0" keyboardnavigation.tabindex="1" panel.zindex="1"/>
                            <border x:name="contentpanel" borderbrush="{templatebinding borderbrush}" borderthickness="{templatebinding borderthickness}" background="{templatebinding background}" grid.column="0" keyboardnavigation.directionalnavigation="contained" grid.row="1" keyboardnavigation.tabindex="2" keyboardnavigation.tabnavigation="local">
                                <contentpresenter x:name="part_selectedcontenthost" contentsource="selectedcontent" margin="{templatebinding padding}" snapstodevicepixels="{templatebinding snapstodevicepixels}"/>
                            </border>
                        </grid>
                        <controltemplate.triggers>
                            <trigger property="tabstripplacement" value="bottom">
                                <setter property="grid.row" targetname="headerpanel" value="1"/>
                                <setter property="grid.row" targetname="contentpanel" value="0"/>
                                <setter property="height" targetname="rowdefinition0" value="*"/>
                                <setter property="height" targetname="rowdefinition1" value="auto"/>
                                <setter property="margin" targetname="headerpanel" value="2,0,2,2"/>
                            </trigger>
                            <trigger property="tabstripplacement" value="left">
                                <setter property="grid.row" targetname="headerpanel" value="0"/>
                                <setter property="grid.row" targetname="contentpanel" value="0"/>
                                <setter property="grid.column" targetname="headerpanel" value="0"/>
                                <setter property="grid.column" targetname="contentpanel" value="1"/>
                                <setter property="width" targetname="columndefinition0" value="auto"/>
                                <setter property="width" targetname="columndefinition1" value="*"/>
                                <setter property="height" targetname="rowdefinition0" value="*"/>
                                <setter property="height" targetname="rowdefinition1" value="0"/>
                                <setter property="margin" targetname="headerpanel" value="2,2,0,2"/>
                            </trigger>
                            <trigger property="tabstripplacement" value="right">
                                <setter property="grid.row" targetname="headerpanel" value="0"/>
                                <setter property="grid.row" targetname="contentpanel" value="0"/>
                                <setter property="grid.column" targetname="headerpanel" value="1"/>
                                <setter property="grid.column" targetname="contentpanel" value="0"/>
                                <setter property="width" targetname="columndefinition0" value="*"/>
                                <setter property="width" targetname="columndefinition1" value="auto"/>
                                <setter property="height" targetname="rowdefinition0" value="*"/>
                                <setter property="height" targetname="rowdefinition1" value="0"/>
                                <setter property="margin" targetname="headerpanel" value="0,2,2,2"/>
                            </trigger>
                            <trigger property="isenabled" value="false">
                                <setter property="foreground" value="{dynamicresource {x:static systemcolors.graytextbrushkey}}"/>
                            </trigger>
                        </controltemplate.triggers>
                    </controltemplate>
                </setter.value>
            </setter>
        </style>
    </usercontrol.resources>
    <usercontrol.datacontext>
        <local:viewamodel/>
    </usercontrol.datacontext>
    <grid>
        <textblock text="{binding text}" verticalalignment="center" horizontalalignment="center" fontsize="50"/>
    </grid>
</usercontrol>

viewaviewmodel:

using system;
using system.collections.generic;
using system.componentmodel;
using system.linq;
using system.text;
using system.threading.tasks;

namespace test
{
   public class viewamodel:inotifypropertychanged
    {
        public viewamodel()
        {
            text = "a";
        }

        public event propertychangedeventhandler propertychanged;

        private void change(string propertyname)
        {
            propertychanged?.invoke(this, new propertychangedeventargs(propertyname));
        }

        private string text;

        public string text
        {
            get { return text; }
            set
            {
                text = value;
                change("text");
            }
        }
    }
}

viewb:

<usercontrol x:class="test.viewb"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:test"
            
             mc:ignorable="d" 
             d:designheight="450" d:designwidth="800">
    <usercontrol.datacontext>
        <local:viewbmodel/>
    </usercontrol.datacontext>
    <grid>
        <textblock text="{binding text}" verticalalignment="center" horizontalalignment="center" fontsize="50"/>
    </grid>
</usercontrol>

viewbviewmodel:

using system;
using system.collections.generic;
using system.componentmodel;
using system.linq;
using system.text;
using system.threading.tasks;

namespace test
{
  public  class viewbmodel: inotifypropertychanged
    {
        public viewbmodel()
        {
            text = "viewb";
        }
        public event propertychangedeventhandler propertychanged;

        private void change(string propertyname)
        {
            propertychanged?.invoke(this, new propertychangedeventargs(propertyname));
        }

        private string text;

        public string text
        {
            get { return text; }
            set
            {
                text = value;
                change("text");
            }
        }
    }
}

在mainwindow切换viewa和viewb

<window x:class="test.mainwindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:test"
        mc:ignorable="d"
        title="mainwindow" height="450" width="800">
    <grid>
        <grid.columndefinitions>
            <columndefinition/>
            <columndefinition/>
        </grid.columndefinitions>

        <stackpanel>
            <button height="100" width="100" content="a" x:name="a" click="a_click"/>
            <button height="100" width="100" content="b" x:name="b" click="b_click"/>
        </stackpanel>

        <contentcontrol x:name="content" grid.column="1">
            <local:viewa/>
        </contentcontrol>

    </grid>
</window>

mainwindow.cs:   在初始化的时候,通过一个dictionary,把要展示的view先加载出来,存到字典上,确保只load一次view,在点击按钮切换contentcontrol时,从字典中获取,减少每一次都new一个view,造成内存的泄露

using system;
using system.collections.generic;
using system.linq;
using system.text;
using system.threading.tasks;
using system.windows;
using system.windows.controls;
using system.windows.data;
using system.windows.documents;
using system.windows.input;
using system.windows.media;
using system.windows.media.imaging;
using system.windows.navigation;
using system.windows.shapes;

namespace test
{
    /// <summary>
    /// mainwindow.xaml 的交互逻辑
    /// </summary>
    public partial class mainwindow : window
    {
        public mainwindow()
        {
            initializecomponent();

            framworkelements["a"]=new viewa();
            framworkelements["b"]=new viewb();
        }

        private dictionary<string, frameworkelement> framworkelements = new dictionary<string, frameworkelement>();

        private void a_click(object sender, routedeventargs e)
        {
            content.content = framworkelements["a"];
        }

        private void b_click(object sender, routedeventargs e)
        {
            content.content = framworkelements["b"];
        }
    }
}

展示的效果: 

点击a按钮,切换a视图

点击b按钮,切换b视图:

到此这篇关于wpf仿tabcontrol实现切换多个不同view的文章就介绍到这了,更多相关wpf切换不同view内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)
打赏 微信扫一扫 微信扫一扫

您想发表意见!!点此发布评论

推荐阅读

WPF实现数据绑定的几种方法

12-07

WPF实现自定义控件的几种方法

12-07

WPF如何在圆形上优雅地添加刻度线

11-22

WPF数据绑定时出现StringFormat失效的原因和解决方法

12-11

WPF实现Drawer抽屉控件

11-09

WPF实现图片按像素拉伸

11-04

猜你喜欢

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

发表评论