[]
        
(Showing Draft Content)

自定义命令属性编辑窗体

大部分情况下,通过标注不同的Attribute给属性,可以指定使用不同的内置属性编辑器。

但是如果希望命令通过自定义的对话框编辑,就需要自定义一个WPF的窗体来实现了。


1. 在MyPluginServerCommand中定义一个属性。

    [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;
        }
    }

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

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


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


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

    • MyCommandEditorWindow.xaml 文件

      代码说明:在窗体中添加了一个标签控件、一个多行文本框控件(文本属性和.cs文件中的文本属性绑定)、一个确定按钮、一个取消按钮。

<Window x:Class="MyPlugin.Designer.MyCommandEditorWindow"
        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:MyPlugin.Designer"
        mc:Ignorable="d"
        WindowStartupLocation="CenterScreen"
        Title="MyCommandEditorWindow" Height="400" Width="500">
    <Grid Margin="10">
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"></RowDefinition>
            <RowDefinition></RowDefinition>
            <RowDefinition Height="auto"></RowDefinition>
        </Grid.RowDefinitions>
        <TextBlock>我的注释</TextBlock>
        <TextBox VerticalContentAlignment="Stretch"  Margin="0,5,0,5" Grid.Row="1" AcceptsReturn="True" Text="{Binding Text}"></TextBox>
        <StackPanel Orientation="Horizontal" Grid.Row="2" HorizontalAlignment="Right">
            <Button x:Name="OkButton" Click="OKButton_Click"  Height="30" Width="70" Margin="0,0,10,0">确定</Button>
            <Button Click="CancelButton_Click"  Height="30" Width="70">取消</Button>
        </StackPanel>
    </Grid>
</Window>
  • MyCommandEditorWindow.xaml.cs 文件代码说明:添加了确定按钮,取消按钮的点击逻辑,在ViewModel类上声明了 Text 属性与控件绑定。

using System.ComponentModel;
using System.Windows;

namespace MyPlugin.Designer
{
    /// <p>DOC-SUMMARY-TAG-OPEN</p>
    /// Interaction logic for MyCommandEditorWindow.xaml
    /// <p>DOC-SUMMARY-TAG-CLOSE</p>
    public partial class MyCommandEditorWindow : Window
    {
        public MyCommandEditorWindow()
        {
            this.DataContext = new MyCommandEditorWindowViewModel();
            InitializeComponent();
        }

        public MyCommandEditorWindowViewModel ViewModel
        {
            get
            {
                return this.DataContext as MyCommandEditorWindowViewModel;
            }
        }

        public class MyCommandEditorWindowViewModel: 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;
        }

        private void OKButton_Click(object sender, RoutedEventArgs e)
        {
            this.OkButton.Focus();
            this.DialogResult = true;
            this.Close();
        }

        private void CancelButton_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }
    }
}

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

using GrapeCity.Forguncy.Commands;
using GrapeCity.Forguncy.Plugin;
using System;
using System.ComponentModel;

namespace MyPlugin.Designer
{
    public class MyPluginServerCommandDesigner : CommandDesigner<MyPluginServerCommand>
    {
        public override EditorSetting GetEditorSetting(PropertyDescriptor property, IBuilderCommandContext builderContext)
        {
            if(property.Name == nameof(MyPluginServerCommand.MyProperty))
            {
                return new HyperlinkEditorSetting(new ShowDialogCommand());
            }
            return base.GetEditorSetting(property, builderContext);
        }
    }

    class ShowDialogCommand : System.Windows.Input.ICommand
    {
        public event EventHandler CanExecuteChanged;

        public bool CanExecute(object parameter)
        {
            return true;
        }

        public void Execute(object parameter)
        {
            if(parameter is IEditorSettingsDataContext dataContext)
            {
                var editWindow = new MyCommandEditorWindow();
                editWindow.ViewModel.Text = dataContext.Value?.ToString();
                if(editWindow.ShowDialog() == true)
                {
                    dataContext.Value = editWindow.ViewModel.Text;
                }
            }
        }
    }
}

4. 效果: