[]
有些情况下,为了提升用户体验,会自定义整个命令编辑界面。而不是通过属性定义自定生成命令编辑界面。例如页面跳转命令、数据表操作命令就是这样的情况。
要实现完全自定义的编辑控件需要自定义WPF 控件,并让此控件实现 ICommandEditor 接口。
步骤如下:
1. 添加一个自定义窗体。
在插件工程中Designer文件夹点击右键,选择“添加->窗口(WPF)”。
在弹出对话框中指定名称为 MyCommandPropertyEditor.xaml。
创建成功过后分别按以下代码修改 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. 效果如下:
注意,本示为了演示功能,只实现了一个很简单的界面,只声明了一个属性。如果在实际插件开发中,这种简单的情况不需要自定义命令编辑控件。只有属性较多,操作逻辑较为复杂的时候才需要使用本章节的方法。
通常,实现一个较为完善的命令编辑控件需要较长的开发和调试时间,请慎重选择此方案。