Avalonia 主窗体嵌入子窗体

 首先在Main中添加一句代码

 

 

 窗体设计器代码如下

<UserControl xmlns="https://github.com/avaloniaui"
             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:vm="clr-namespace:AvaloniaPlant01.ViewModels"
             mc:Ignorable="d" d:DesignWidth="1920" d:DesignHeight="1020"
               Width="1920" Height="1020"
             x:Class="AvaloniaPlant01.Views.MainView"
               xmlns:converters="clr-namespace:AvaloniaPlant01.Base"
             x:DataType="vm:MainViewModel">

    <Design.DataContext>
        <vm:MainViewModel />
    </Design.DataContext>


    <!-- 窗体控件代码开始-->
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="300"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <!-- 第一列用于左侧栏-->
        <Grid Grid.Column="0" Background="Transparent">
            <Grid.RowDefinitions>
                <RowDefinition Height="100"/>
                <RowDefinition Height="550" />
                <RowDefinition />
            </Grid.RowDefinitions>
            <!-- 第一列.第一行 Logo区域 -->
            <StackPanel Grid.Row="0" Orientation="Horizontal" Background="Transparent" Height="64" VerticalAlignment="Center">
                <Image Source="/Assets/avalonia-logo.ico" Height="45" Margin="10,0,8,0"/>
                <TextBlock FontSize="24" Text ="Navigation menu" Foreground="Black" VerticalAlignment="Center" />
            </StackPanel>

            <!-- 第一列.第二行 菜单区域 -->
            <Grid Grid.Row="1" Background="Transparent">
                <StackPanel  Margin="0,0,0,0" VerticalAlignment="Center"    Orientation="Vertical">
                    <!--  Command绑定命令,CommandParameter传递参数  -->
                    <RadioButton   Command="{Binding OpenWindowCommand}" CommandParameter="DashboardView"
                                 Content=" &#xe88f;  DashboardView" Margin="0,2,0,0" Classes="nav"/>
                    <RadioButton  Command="{Binding OpenWindowCommand}" CommandParameter="DeviceView"
                                 Content=" &#xe893;  DeviceView" Margin="0,2,0,0"  Classes="nav"/>
                    <RadioButton  Command="{Binding OpenWindowCommand}" CommandParameter="ExperimentView"
                                 Content=" &#xe899;  ExperimentView" Margin="0,2,0,0" Classes="nav"/>
                    <RadioButton Command="{Binding OpenWindowCommand}" CommandParameter="SettingsView"
                                 Content=" &#xe884;  SettingsView" Margin="0,2,0,0" Classes="nav"/>
                    <RadioButton  Command="{Binding OpenWindowCommand}" CommandParameter="TagsView"
                                 Content=" &#xe882;  TagsView" Margin="0,2,0,0" Classes="nav"/>
                    <RadioButton  Command="{Binding OpenWindowCommand}" CommandParameter="TaskView"
                                 Content=" &#xe875;  TaskView" Margin="0,2,0,0" Classes="nav"/>
                    <RadioButton  Command="{Binding OpenWindowCommand}" CommandParameter="UserView"
                                 Content=" &#xe895;  UserView" Margin="0,2,0,0" Classes="nav"/>
                    <RadioButton  Command="{Binding OpenWindowCommand}" CommandParameter="OtherView"
                                 Content=" &#xe871;  OtherView" Margin="0,2,0,0" Classes="nav"/>
                </StackPanel>
            </Grid>

            <Grid Grid.Row="2" Background="Transparent">
                <!-- 第1列.第三行 当前用户和头像  -->
                <StackPanel Margin="10,0,0,50" Orientation="Horizontal" Background="Transparent" Height="64" VerticalAlignment="Bottom">
                    <Image Source="avares://AvaloniaPlant01/Assets/Images/Man_png/Man03.png" Height="45" Margin="20,0,8,0"/>
                    <TextBlock FontSize="24" Text ="User Name" Foreground="Black" VerticalAlignment="Center" />
                </StackPanel>
            </Grid>
        </Grid>

        <!-- 第二列用于右侧容器 -->
        <Grid Grid.Column="1" Background="Transparent" >
            <ContentControl
              Margin="0,0,0,0"
              Content="{Binding Content}">
                <ContentControl.ContentTemplate>
                    <converters:ViewLocator />
                </ContentControl.ContentTemplate>
            </ContentControl>
        </Grid>

    </Grid>
</UserControl>

 

  窗体模型 代码如下

using System;
using System.Collections.ObjectModel;
using System.Windows.Input;
using Avalonia.Controls;
using AvaloniaPlant01.Base;
using AvaloniaPlant01.ViewModels.EmbeddedForm;
using AvaloniaPlant01.Views;
using CommunityToolkit.Mvvm.Messaging;

namespace AvaloniaPlant01.ViewModels;

public partial class MainViewModel : ViewModelBase
{
    public ICommand OpenWindowCommand { get; set; }

    private object? _content;

    public object? Content
    {
        get => _content;
        set => SetProperty(ref _content, value);
    }

    public MainViewModel()
    {
        OpenWindowCommand = new Command(ExeOpenWindowCommand);
        WeakReferenceMessenger.Default.Register<MainViewModel, string>(this, OnNavigation);
    }

    private void OnNavigation(MainViewModel vm, string s)
    {
        Content = s switch
        {

            MenuKeys.MenuKeyDashboard => new DashboardViewModel(),
            MenuKeys.MenuKeyDevice => new DeviceViewModel(),
            MenuKeys.MenuKeyExperiment => new ExperimentViewModel(),
            MenuKeys.MenuKeySettings => new SettingsViewModel(),
            MenuKeys.MenuKeyTags => new TagsViewModel(),
            MenuKeys.MenuKeyTask => new TaskViewModel(),
            MenuKeys.MenuKeyUser => new UserViewModel(),
            MenuKeys.MenuKeyOther => new OtherViewModel(),
            _ => throw new ArgumentOutOfRangeException(nameof(s), s, null)
        };
    }

    //打开窗体方法
    private void ExeOpenWindowCommand(object obj)
    {
        OnNavigation(this, obj.ToString());
    }

}

 

using System;
using Avalonia.Controls;
using Avalonia.Controls.Templates;

namespace AvaloniaPlant01.Base;

/// <summary>
/// 把嵌入子视图嵌入主窗体实体,需要使用
/// </summary>
public class ViewLocator : IDataTemplate
{
    public Control? Build(object? param)
    {
        if (param is null) return null;
        var name = param.GetType().Name.Replace("Model", "");
        string strname = "AvaloniaPlant01.Views." + name;
        var type = Type.GetType("AvaloniaPlant01." + name);
        if (type != null)
        {
            return (Control)Activator.CreateInstance(type)!;
        }
        return new TextBlock { Text = "Not Found: " + name };
    }

    public bool Match(object? data)
    {
        return true;
    }
}
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using System.Windows.Input;

namespace AvaloniaPlant01.ViewModels.EmbeddedForm
{
    public enum ControlStatus
    {
        New,
        Beta,
        Stable,
    }

    public class MenuItemViewModel : ViewModelBase
    {
        public string? MenuHeader { get; set; }
        public string? MenuIconName { get; set; }
        public string? Key { get; set; }
        public string? Status { get; set; }

        public bool IsSeparator { get; set; }
        public ObservableCollection<MenuItemViewModel> Children { get; set; } = new();

        public ICommand ActivateCommand { get; set; }

        public MenuItemViewModel()
        {
            ActivateCommand = new RelayCommand(OnActivate);
        }

        private void OnActivate()
        {
            if (IsSeparator || Key is null) return;
            WeakReferenceMessenger.Default.Send(Key);
        }
    }
}
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AvaloniaPlant01.ViewModels.EmbeddedForm
{
    public class MenuViewModel : ViewModelBase
    {
        public ObservableCollection<MenuItemViewModel> MenuItems { get; set; }

        public MenuViewModel()
        {
            MenuItems = new ObservableCollection<MenuItemViewModel>()
            {
                    new() { MenuHeader = "DashboardView", Key = MenuKeys.MenuKeyDashboard, IsSeparator = false },
                    new() { MenuHeader = "DeviceView", Key = MenuKeys.MenuKeyDevice, IsSeparator = false },
                    new() { MenuHeader = "ExperimentView", Key = MenuKeys.MenuKeyExperiment, IsSeparator = false },
                    new() { MenuHeader = "OtherView", Key = MenuKeys.MenuKeyOther, IsSeparator = false },
                    new() { MenuHeader = "SettingsView", Key = MenuKeys.MenuKeySettings, IsSeparator = false },
                    new() { MenuHeader = "TagsView", Key = MenuKeys.MenuKeyTags, IsSeparator = false },
                    new() { MenuHeader = "TaskView", Key = MenuKeys.MenuKeyTask, IsSeparator = false },
                    new() { MenuHeader = "UserView", Key = MenuKeys.MenuKeyUser, IsSeparator = false },
            };
        }
    }


    public static class MenuKeys
    {
        public const string MenuKeyDashboard = "DashboardView";
        public const string MenuKeyDevice = "DeviceView";
        public const string MenuKeyExperiment = "ExperimentView";
        public const string MenuKeyOther = "OtherView";
        public const string MenuKeySettings = "SettingsView";
        public const string MenuKeyTags = "TagsView";
        public const string MenuKeyTask = "TaskView";
        public const string MenuKeyUser = "UserView";
    }

}

下面看看结果展示

 

 

 

(当前第三集 主窗体嵌入子窗体  下一集 用户登录管理)

posted @ 2024-11-18 14:32  funiyi816  阅读(36)  评论(0编辑  收藏  举报