[]
        
(Showing Draft Content)

自定义命令编辑控件

有些情况下,为了提升用户体验,会自定义整个命令编辑界面。而不是通过属性定义自定生成命令编辑界面。例如页面跳转命令、数据表操作命令就是这样的情况。



要实现完全自定义的编辑控件需要自定义WPF 控件,并让此控件实现 ICommandEditor 接口。


步骤如下:

1. 添加一个自定义窗体。

  1. 在插件工程中Designer文件夹点击右键,选择“添加->窗口(WPF)”。


  2. 在弹出对话框中指定名称为 MyCommandPropertyEditor.xaml。


  3. 创建成功过后分别按以下代码修改 MyPluginServerCommandEditor.xaml 和 MyPluginServerCommandEditor.xaml.cs 文件。


    • MyPluginServerCommandEditor.xaml 文件

      代码说明:在控件中添加了一个多行文本框(可以根据需求加入其它控件)。

<UserControl x:Class="MyPlugin.Designer.MyPluginServerCommandEditor"
             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:MyPlugin.Designer"
             mc:Ignorable="d" 
             MinHeight="100" d:DesignWidth="800">
    <StackPanel x:Name="root">
        <TextBlock>完全自定义的命令编辑界面</TextBlock>
        <TextBlock>可以使用任何组件布局</TextBlock>
        <TextBox Width="300" Height="200" HorizontalAlignment="Left" AcceptsReturn="True" Text="{Binding Text}"></TextBox>
    </StackPanel>
</UserControl>
  • MyPluginServerCommandEditor.xaml.cs 文件

    代码说明:实现 ICommandEditor 接口,使用 Command 属性和 Validate 方法实现编辑。

using GrapeCity.Forguncy.Commands;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;

namespace MyPlugin.Designer
{
    /// <p>DOC-SUMMARY-TAG-OPEN</p>
    /// MyPluginServerCommandEditor.xaml 的交互逻辑
    /// <p>DOC-SUMMARY-TAG-CLOSE</p>
    public partial class MyPluginServerCommandEditor : UserControl, ICommandEditor
    {
        public MyPluginServerCommandEditor()
        {
            InitializeComponent();
            this.root.DataContext = new MyCommandPropertyEditorViewModel();
        }

        public MyCommandPropertyEditorViewModel ViewModel
        {
            get
            {
                return this.root.DataContext as MyCommandPropertyEditorViewModel;
            }
        }
        // 初始化时会调用属性的 set 方法,在set方法中可以初始化UI控件的值
        // 在Validate()函数校验通过后会调用属性的 get 方法,可以通过 UI 控件 编辑后的值生成一个命令保存
        public Command Command
        {
            get
            {
                return new MyPluginServerCommand() { MyProperty = this.ViewModel.Text };
            }
            set
            {
                var command = value as MyPluginServerCommand;
                this.ViewModel.Text = command.MyProperty;
            }
        }

        // 自定义校验逻辑,提交编辑的时候会被调用,返回false表示校验失败
        public bool Validate()
        {
            if (string.IsNullOrEmpty(this.ViewModel.Text))
            {
                MessageBox.Show("XXX属性值不能为空", "错误", MessageBoxButton.OKCancel, MessageBoxImage.Error);
                return false;
            }
            return true;
        }

        public class MyCommandPropertyEditorViewModel : INotifyPropertyChanged
        {

            private string _text;
            public string Text
            {
                get
                {
                    return this._text;
                }
                set
                {
                    if (_text != value)
                    {
                        this._text = value;
                        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Text)));
                    }
                }
            }


            public event PropertyChangedEventHandler PropertyChanged;
        }
    }
}

3. 修改MyPluginServerCommandDesigner.cs文件,让控件和属性关联。

    public class MyPluginServerCommandDesigner : CommandDesigner<MyPluginServerCommand>
    {
        public override ICommandEditor GetCommandEditor()
        {
            return new MyPluginServerCommandEditor();
        }
    }

4. 修改 MyPluginServerCommand.cs 文件,通过DesignerAttribute 和 MyPluginServerCommandDesigner关联。

using GrapeCity.Forguncy.Commands;
using System.ComponentModel;
using System.Threading.Tasks;

namespace MyPlugin
{
    [Designer("MyPlugin.Designer.MyPluginServerCommandDesigner, MyPlugin")]
    public class MyPluginServerCommand : Command, ICommandExecutableInServerSideAsync
    {
        public string MyProperty { get; set; }

        public async Task<ExecuteResult> ExecuteAsync(IServerCommandExecuteContext dataContext)
        {
            return new ExecuteResult();
        }

        public override CommandScope GetCommandScope()
        {
            return CommandScope.ExecutableInServer;
        }
    }
}

5. 效果如下:



注意,本示为了演示功能,只实现了一个很简单的界面,只声明了一个属性。如果在实际插件开发中,这种简单的情况不需要自定义命令编辑控件。只有属性较多,操作逻辑较为复杂的时候才需要使用本章节的方法。

通常,实现一个较为完善的命令编辑控件需要较长的开发和调试时间,请慎重选择此方案。