有些情况下,为了提升用户体验,会自定义整个命令编辑界面。而不是通过属性定义自定生成命令编辑界面。例如页面跳转命令,数据表操作命令就是这样的情况。
要实现完全自定义的编辑控件需要自定义WPF 控件,并让此控件实现 ICommandEditor 接口。
步骤如下:
1.添加一个自定义窗体。
- 在插件工程中Designer文件夹点击右键,选择“添加->窗口(WPF)”。
- 在弹出对话框中指定名称为 MyCommandPropertyEditor.xaml。
- 创建成功过后分别按以下代码修改 MyPluginCommandEditor.xaml 和 MyPluginCommandEditor.xaml.cs 文件。
- 在插件工程中Designer文件夹点击右键,选择“添加->窗口(WPF)”。
MyPluginCommandEditor.xaml 文件
代码说明:在控件中添加了一个多行文本框(可以根据需求加入其它控件)。
<UserControl x:Class="MyPlugin.Designer.MyPluginCommandEditor" 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>
MyPluginCommandEditor.xaml.cs 文件
代码说明:实现 ICommandEditor 接口,使用 Command 属性和 Validate 方法实现编辑。
using GrapeCity.Forguncy.Commands; using System.ComponentModel; using System.Windows; using System.Windows.Controls; namespace MyPlugin.Designer { /// <summary> /// MyPluginCommandEditor.xaml 的交互逻辑 /// </summary> public partial class MyPluginCommandEditor : UserControl, ICommandEditor { public MyPluginCommandEditor() { 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 MyPluginCommand() { MyProperty = this.ViewModel.Text }; } set { var command = value as MyPluginCommand; 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.修改MyPluginCommandDesigner.cs文件,让控件和属性关联。
public class MyPluginCommandDesigner : CommandDesigner<MyPluginCommand> { public override ICommandEditor GetCommandEditor() { return new MyPluginCommandEditor(); } }
4.修改 MyPluginCommand.cs 文件,通过DesignerAttribute 和 MyPluginCommandDesigner 关联。
using GrapeCity.Forguncy.Commands; using System.ComponentModel; namespace MyPlugin { [Designer("MyPlugin.Designer.MyPluginCommandDesigner, MyPlugin")] public class MyPluginCommand : Command { public string MyProperty { get; set; } } }
5.效果如下: