WPF仿Tabcontrol加载切换多个不同View
阅读原文时间:2023年07月08日阅读:1

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

1、ViewA:

¨C41C ¨C42C

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>  

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



    <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>  

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
{
///

/// MainWindow.xaml 的交互逻辑 ///
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视图: