大部分情况下,通过标注不同的Attribute给属性,可以指定使用不同的内置属性编辑器。
但是如果希望命令通过自定义的对话框编辑,就需要自定义一个WPF的窗体来实现了。
1.在MyPluginCommand中定义一个属性。
[Designer("MyPlugin.Designer.MyPluginCommandDesigner, MyPlugin")] public class MyPluginCommand : Command { public string MyProperty { get; set; } }
2.添加一个自定义窗体。
- 在插件工程中Designer文件夹点击右键,选择“添加->窗口(WPF)”。
- 在弹出对话框中指定名称为 MyCommandPropertyEditor.xaml。
- 创建成功过后分别按以下代码修改 MyCommandEditorWindow.xaml 和 MyCommandEditorWindow.xaml.cs 文件。
- 在插件工程中Designer文件夹点击右键,选择“添加->窗口(WPF)”。
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 属性与控件绑定。
- MyCommandEditorWindow.xaml.cs 文件
using System.ComponentModel; using System.Windows; namespace MyPlugin.Designer { /// <summary> /// Interaction logic for MyCommandEditorWindow.xaml /// </summary> 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.修改MyPluginCommandDesigner.cs文件,让窗体和属性关联。
using GrapeCity.Forguncy.Commands; using GrapeCity.Forguncy.Plugin; using System; using System.ComponentModel; namespace MyPlugin.Designer { public class MyPluginCommandDesigner : CommandDesigner<MyPluginCommand> { public override EditorSetting GetEditorSetting(PropertyDescriptor property, IBuilderCommandContext builderContext) { if(property.Name == nameof(MyPluginCommand.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.效果: