当前位置:网站首页 / AYUI9 / 正文

AYUI9-Taurus(金牛座)使用教程 [1] - Shell菜单栏拓展

时间:2019年09月02日 | 作者 : aaronyang | 分类 : AYUI9 | 浏览: 593次 | 评论 0

菜单栏 拓展

 新建一个模块类库,引用 Taurus

image.png

然后客户端RDS引用下

image.png

引用必要类库

image.png

新建一个菜单类

using Caliburn.Micro;
using System.ComponentModel.Composition;
using System.Threading.Tasks;
using System.Windows;
using Taurus.Framework.Commands;
using Taurus.Framework.Menus;
using Taurus.Framework.Services;
using Taurus.Framework.Threading;


namespace Taurus.Modules.Test1
{
    public static class MenuDefinitions
    {
        [Export]
        public static MenuItemDefinition TestTextMenuItem = new CommandMenuItemDefinition<TestTextCommandDefinition>(
            Taurus.Modules.MainMenu.MenuDefinitions.FileNewOpenMenuGroup, 2);
    }
    [CommandDefinition]
    public class TestTextCommandDefinition : CommandDefinition
    {
        public const string CommandName = "File.TestText";

        public override string Name
        {
            get { return CommandName; }
        }

        public override string Text
        {
            get { return "testText1"; }
        }

        public override string ToolTip
        {
            get { return "test1"; }
        }
    }
    [CommandHandler]
    public class TestTextCommandHandler : CommandHandlerBase<TestTextCommandDefinition>
    {
        private readonly IShell _shell;

        [ImportingConstructor]
        public TestTextCommandHandler(IShell shell)
        {
            _shell = shell;
        }

        public override Task Run(Command command)
        {
            MessageBox.Show("new");
            return TaskUtility.Completed;
        }
    }
}

这样子,在菜单栏- 文件F 下面索引为2的地方就会有个 菜单,单击时候弹出new

image.png image.png

一个菜单,3个文件,第一个文件可以 共享和其他一起用,类名无所谓,自己随便定义的,具体到哪个命令, 用  XXCommandHandler和XXCommandDefinition命名方式

默认框架: MainMenuBar定义顶级菜单容器,然后MenuDefinition第一个参数定义第一个菜单

image.png

所以定义一级菜单代码如下:

定义顶级,必须要有子菜单,才会显示

  [Export]
        public static MenuDefinition TestText2MenuItem = new MenuDefinition(Taurus.Modules.MainMenu.MenuDefinitions.MainMenuBar, 0,"顶级菜单测试");

子菜单,然后定义个组

        [Export]
        public static MenuItemGroupDefinition TestText2_1MenuGroup = new MenuItemGroupDefinition(TestText2MenuItem, 0);

组内必须要有item,不然不会显示的

        [Export]
        public static MenuItemDefinition TestTextMenuItem = new CommandMenuItemDefinition<TestTextCommandDefinition>(
        TestText2_1MenuGroup, 0);

image.png

单击的时候同样会出来弹框的

当然如果你定义了菜单,没有定义CommandHandler,菜单是灰色,不可以点击


当然同一个Handler可以被重复使用的,

image.png

image.png

随便放位置


接下来看下动态菜单,比如这里的新建 右侧是动态列表

我们还是在顶级菜单测试 那个MenuItem定义

首先定义个组类型的

        [Export]
        public static MenuItemGroupDefinition TestText2_2MenuGroup = new MenuItemGroupDefinition(TestText2MenuItem, 1);

接下来,插入一个文本MenuItem(TextMenuItemDefinition)

        [Export]
        public static MenuItemDefinition TestText2_2MenuItem = new TextMenuItemDefinition(TestText2_2MenuGroup, 0, "顶级菜单测试列表");

image.png

此时就是个普通的文本,接下来,让它成为二级菜单的容器,先声明一个组

        [Export]
        public static MenuItemGroupDefinition TestText2_2CascadeGroup = new MenuItemGroupDefinition(TestText2_2MenuItem, 0);

接下来再这个组内加一个列表

    [Export]
        public static MenuItemDefinition TestText2_2MenuItemList = new CommandMenuItemDefinition<TestText2_2CommandListDefinition>(TestText2_2CascadeGroup, 0);
    [CommandDefinition]
    public class TestText2_2CommandListDefinition : CommandListDefinition
    {
        public const string CommandName = "File.TestText2_2";

        public override string Name
        {
            get { return CommandName; }
        }
    }

image.png

此时已经有了列表的人,刚才加了个组,所以这里中间有条横线。

使用CommandMenuItemDefinition 表示 可以执行的 菜单item

如果不想要横线

image.png

那么直接用testText1的组就行了。

image.png

竟然有 可执行命令的定义,就应该有对应的Handler

添加基本的实现

    [CommandHandler]
    public class NewFileCommandHandler : ICommandListHandler<TestText2_2CommandListDefinition>
    {
        public void Populate(Command command, List<Command> commands)
        {
            throw new System.NotImplementedException();
        }

        public Task Run(Command command)
        {
            throw new System.NotImplementedException();
        }
    }

image.png

对比下 两个接口,一个是单个的,一个是列表的

接下来,丰富handler

    [CommandHandler]
    public class TestText2_2CommandHandler : ICommandListHandler<TestText2_2CommandListDefinition>
    {

        private readonly IShell _shell;

        /// <summary>
        /// 填充
        /// </summary>
        /// <param name="command"></param>
        /// <param name="commands"></param>
        public void Populate(Command command, List<Command> commands)
        {
            for (int i = 0; i < 10; i++)
            {
                commands.Add(new Command(command.CommandDefinition)
                {
                    Text = "动态MenuItem" + i,
                    Tag = i
                });
            }
        }

        public Task Run(Command command)
        {
            MessageBox.Show(command.Tag.ToString());
            return TaskUtility.Completed;
        }
    }

image.png

单击时候就会弹窗显示 对应的数字了。


接下来我们定义个动态菜单接口,让功能更强大

添加一个简单的 编辑器接口

  //框架自带的
    public class EditorFileType
    {
        public string Name { get; set; }
        public string FileExtension { get; set; }

        public EditorFileType(string name, string fileExtension)
        {
            Name = name;
            FileExtension = fileExtension;
        }

        public EditorFileType()
        {
            
        }
    }
//丰富命令的run执行的时候,传递的参数
public  class AyFileTag
    {
        public IAyProvider EditorProvider;
        public EditorFileType FileType;
    }
//每一个界面执行的基本的菜单
    public interface IAyProvider
    {
        IEnumerable<EditorFileType> FileTypes { get; }

        bool Handles(string path);

        IDocument Create();

        Task New(IDocument document, string name);
        Task Open(IDocument document, string path);
    }


  [CommandHandler]
    public class TestText2_2CommandHandler : ICommandListHandler<TestText2_2CommandListDefinition>
    {
        private int _TestText2_2Counter = 1;

        private readonly IShell _shell;
        private readonly IAyProvider[] _editorProviders;

        [ImportingConstructor]
        public TestText2_2CommandHandler(
            IShell shell,
            [ImportMany] IAyProvider[] editorProviders)
        {
            _shell = shell;
            _editorProviders = editorProviders;

        }
        /// <summary>
        /// 填充
        /// </summary>
        /// <param name="command"></param>
        /// <param name="commands"></param>
        public void Populate(Command command, List<Command> commands)
        {
            foreach (var editorProvider in _editorProviders)
                foreach (var editorFileType in editorProvider.FileTypes)
                    commands.Add(new Command(command.CommandDefinition)
                    {
                        Text = editorFileType.Name,
                        Tag = new AyFileTag
                        {
                            EditorProvider = editorProvider,
                            FileType = editorFileType
                        }
                    });
        }

        public Task Run(Command command)
        {
            var tag = (AyFileTag)command.Tag;
            var editor = tag.EditorProvider.Create();

            var viewAware = (IViewAware)editor;
            viewAware.ViewAttached += (sender, e) =>
            {
                var frameworkElement = (FrameworkElement)e.View;

                RoutedEventHandler loadedHandler = null;
                loadedHandler = async (sender2, e2) =>
                {
                    frameworkElement.Loaded -= loadedHandler;
                    await tag.EditorProvider.New(editor, string.Format("新文件", (_TestText2_2Counter++) + tag.FileType.FileExtension));
                };
                frameworkElement.Loaded += loadedHandler;
            };

            _shell.OpenDocument(editor);

            return TaskUtility.Completed;
        }
    }

接下来实现IAyProvider接口

   [Export(typeof(IAyProvider))]
    public class AyEditorProvider : IAyProvider
    {

        private IEnumerable<EditorFileType> _FileTypes;
        public IEnumerable<EditorFileType> FileTypes
        {
            get
            {
                if (_FileTypes == null)
                {
                    var _Ft = new List<EditorFileType>();
                    for (int i = 0; i < 5; i++)
                    {
                        _Ft.Add(new EditorFileType
                        {
                            Name = "hello文件"+i,
                            FileExtension = "后缀"+i
                        });
                        _FileTypes = _Ft;
                    }
                }
                return _FileTypes;
            }
        }

        public bool Handles(string path)
        {
            return true;//文件存在就可以执行
        }

        public IDocument Create()
        {
            return IoC.Get<AyEditorViewModel>();
        }

        public async Task New(IDocument document, string name)
        {
            await ((AyEditorViewModel)document).New(name);
        }

        public async Task Open(IDocument document, string path)
        {
            await ((AyEditorViewModel)document).Load(path);
        }
    }

这一步完成后,添加页面VM,然后添加View,就可以 文档选项卡方式打开了

添加用户控件类型的AyEditorView.xaml

<UserControl x:Class="Taurus.Modules.Test1.AyEditorView"
             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:Taurus.Modules.Test1"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
        <TextBlock Text="测试动态菜单列表文档"/>
    </Grid>
</UserControl>

添加AyEditorViewModel.cs

using System;
using System.ComponentModel.Composition;
using System.IO;
using System.Threading.Tasks;
using Taurus.Framework;
using Taurus.Framework.Threading;


namespace Taurus.Modules.Test1
{
    [Export(typeof(AyEditorViewModel))]
    [PartCreationPolicy(CreationPolicy.NonShared)]
#pragma warning disable 659
    public class AyEditorViewModel : PersistedDocument
#pragma warning restore 659
    {
 
        private string _originalText;


        public override bool ShouldReopenOnStart
        {
            get { return true; }
        }

        public override void SaveState(BinaryWriter writer)
        {
            writer.Write(FilePath);
        }

        public override void LoadState(BinaryReader reader)
        {
            Load(reader.ReadString());
        }

        protected override void OnViewLoaded(object view)
        {
           
        }

        public override bool Equals(object obj)
        {
            var other = obj as AyEditorViewModel;
            return other != null
                && string.Equals(FilePath, other.FilePath, StringComparison.InvariantCultureIgnoreCase)
                && string.Equals(FileName, other.FileName, StringComparison.InvariantCultureIgnoreCase);
        }

        protected override Task DoNew()
        {
            _originalText = string.Empty;

            return TaskUtility.Completed;
        }

        protected override Task DoLoad(string filePath)
        {
            _originalText = File.ReadAllText(filePath);
    
            return TaskUtility.Completed;
        }

        protected override Task DoSave(string filePath)
        {
            return TaskUtility.Completed;
        }



    }
}

这里菜单动态生成不用讲了

image.png

单击时候

image.png

前面代码少个花括号,格式化内容

image.png

这样动态选项卡的内容

image.png

这里ViewModel,我继承了PersistedDocument,表示是一个可以保存的文档编辑,支持Ctrl+S,还有IsDirty属性

image.png

image.png

支持前进后退,保存,另存为

image.png

接下来给MenuItem添加图标,快捷键

图标:

重写IconSource属性,添加一个16*16的png图标

image.png

image.png

接下来添加快捷键

        [Export]
        public static CommandKeyboardShortcut KeyGesture = new 
            CommandKeyboardShortcut<TestTextCommandDefinition>(new System.Windows.Input.KeyGesture(System.Windows.Input.Key.E, 
                System.Windows.Input.ModifierKeys.Control));

image.png

按下Ctrl+E时候

image.png


这样菜单栏的需求就解决了





推荐您阅读更多有关于“”的文章

猜你喜欢

额 本文暂时没人评论 来添加一个吧

发表评论

必填

选填

选填

必填

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

  查看权限

合肥科大智能常年招聘.NET,Web前端,有想换工作的私聊我AY唯一QQ:875556003和AY交流

抖音号:wpfui,可以看到我的很多作品效果,私活合作请qq联系我

AYUI8社区版Github地址:前往获取

作者:杨洋(AaronYang简称AY,安徽六安人)目前是个人,还没公司AY唯一QQ:875556003和AY交流

高中学历,2015年1月17日开始,兴趣学习研究WPF,目前工作繁忙,不接任何活

声明:AYUI7个人与商用免费,源码可购买。部分DEMO不免费.AY主要靠卖技术服务挣钱

不是从我处购买的ayui7源码,我不提供任何技术服务,如果你举报从哪里买的,我可以帮你转正为我的客户,并送demo

查看捐赠

AYUI7.X MVC教程 更新如下:

第一课 第二课 程序加密教程

vs2015 企业版密钥HM6NR-QXX7C-DFW2Y-8B82K-WTYJV

vs2017 企业版密钥NJVYC-BMHX2-G77MM-4XJMR-6Q8QF

标签列表