[]
大部分情况下,通过标注不同的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. 添加一个自定义窗体。
在插件工程中Designer文件夹点击右键,选择“添加->窗口(WPF)”。
在弹出对话框中指定名称为 MyCommandPropertyEditor.xaml。
创建成功过后分别按以下代码修改 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. 效果: