大部分情况下,通过标注不同的Attribute给属性,可以指定使用不同的内置属性编辑器。
但是如果希望命令通过更复杂的方式编辑就需要通过自定义一个WPF的用户组件来实现了。
1.在MyPluginCommand中定义一个属性。
[Designer("MyPlugin.Designer.MyPluginCommandDesigner, MyPlugin")] public class MyPluginCommand : Command { [DisplayName("说明:")] public string MyProperty { get; set; } }
2.添加一个自定义窗体。
- 在插件工程中Designer文件夹点击右键,选择“添加->用户控件(WPF)”。
- 在弹出对话框中指定名称为 MyCommandPropertyEditor.xaml。
- 创建成功过后分别按以下代码修改 MyCommandPropertyEditor.xaml 和 MyCommandPropertyEditor.xaml.cs 文件。
- 在插件工程中Designer文件夹点击右键,选择“添加->用户控件(WPF)”。
- MyCommandPropertyEditor.xaml 文件
代码说明:在控件中添加了一个多行文本框(可以根据需求加入其它控件)。
- MyCommandPropertyEditor.xaml 文件
<UserControl x:Class="MyPlugin.Designer.MyCommandPropertyEditor" 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"> <Grid x:Name="root"> <TextBox VerticalContentAlignment="Stretch" Margin="9,0,0,0" AcceptsReturn="True" Text="{Binding Text}"></TextBox> </Grid> </UserControl>
- MyCommandPropertyEditor.xaml.cs 文件
代码说明:MyCommandPropertyEditor_DataContextChanged 通过 DataContext 属性可以和属性值互操作。
- MyCommandPropertyEditor.xaml.cs 文件
using GrapeCity.Forguncy.Plugin; using System.ComponentModel; using System.Windows; using System.Windows.Controls; namespace MyPlugin.Designer { public partial class MyCommandPropertyEditor : UserControl { public MyCommandPropertyEditor() { InitializeComponent(); this.root.DataContext = new MyCommandPropertyEditorViewModel(); this.DataContextChanged += MyCommandPropertyEditor_DataContextChanged; } private void MyCommandPropertyEditor_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e) { if (this.DataContext is IEditorSettingsDataContext editorSettingsDataContext) { this.ViewModel.Text = editorSettingsDataContext.Value?.ToString(); this.ViewModel.PropertyChanged += (o, e2) => { editorSettingsDataContext.Value = this.ViewModel.Text; }; } } public MyCommandPropertyEditorViewModel ViewModel { get { return this.root.DataContext as MyCommandPropertyEditorViewModel; } } 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文件,让控件和属性关联。
using GrapeCity.Forguncy.Commands; using GrapeCity.Forguncy.Plugin; using System; using System.ComponentModel; using System.Windows; namespace MyPlugin.Designer { public class MyPluginCommandDesigner : CommandDesigner<MyPluginCommand> { public override EditorSetting GetEditorSetting(PropertyDescriptor property, IBuilderCommandContext builderContext) { if(property.Name == nameof(MyPluginCommand.MyProperty)) { return new MyEditorSetting(); } return base.GetEditorSetting(property, builderContext); } } class MyEditorSetting : EditorSetting { public override DataTemplate GetDataTemplate() { DataTemplate template = new DataTemplate(); FrameworkElementFactory spFactory = new FrameworkElementFactory(typeof(MyCommandPropertyEditor)); template.VisualTree = spFactory; return template; } public override VerticalAlignment LabelVerticalAlignment => VerticalAlignment.Top; } }
4.效果: