Windows Workflow Designer 4.5 中的 UITypeEditor(浏览文件夹)

UITypeEditor in Windows Workflow Designer 4.5 (Browse for folder)

我正在尝试在 WF 4.5 工作流中实现浏览文件夹 Activity 但是省略号按钮没有显示,几乎没有任何反应。

这是我的 UITypeEditor class:

public class BrowseForFolderEditor : UITypeEditor
{
    public override object EditValue(ITypeDescriptorContext context, 
         IServiceProvider provider, object value)
    {
        string folderName = string.Empty;
        BrowseForFolderAttribute browseForFolderAttribute = null;

        if (value is string)
        {
            if (context?.PropertyDescriptor != null)
            {
                browseForFolderAttribute =
                    (BrowseForFolderAttribute)
                context.PropertyDescriptor.Attributes[typeof(BrowseForFolderAttribute)];
            }

            var browse = new FolderBrowserDialogEx
            {
                Description = browseForFolderAttribute?.Description,
                ShowNewFolderButton = true,
                ShowEditBox = true,
                SelectedPath = folderName,
                ShowFullPathInEditBox = false,
                RootFolder = Environment.SpecialFolder.MyComputer
            };

            var result = browse.ShowDialog();

            if (result == DialogResult.OK)
                folderName = browse.SelectedPath;

            return folderName;
        }

        // Return whatever value if it wasn't a string - Should never occur!
        return value;
    }

    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
    {
        return UITypeEditorEditStyle.Modal; //base.GetEditStyle(context);
    }

    public class BrowseForFolderAttribute : Attribute
    {
        public BrowseForFolderAttribute(string description)
        {
            this.Description = description;
        }

        public string Description { get; set; }
    }
}

这就是我在 Activity:

中声明代码的方式
    [Description("Select the folder where the files will be 
     copied/moved to.")]
    [Category("Folders")]
    [Browsable(true)]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
    [BrowseForFolderEditor.BrowseForFolder("Select the folder where the files will be 
     copied/moved to.")]
    [Editor(typeof(BrowseForFolderEditor), typeof(UITypeEditor))]
    public string TargetPath { get; set; }

我不知道这是否有任何区别,但我的工作流程 Activity 属于 NativeActivity.

类型

属性 显示在 属性 网格中,但它仅显示为没有省略号按钮的文本框。

如有任何帮助,我们将不胜感激。

更新-1:

这个问题与它是一个 NativeCodeActivity 的事实没有任何关系,因为我刚刚将我的代码更改为 CodeActivity 并且没有任何区别。

我是通过查看 Microsoft 提供的一些示例来弄明白的,即 Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF) Samples for .NET Framework 4

无论如何,基于此信息,我设法在文本框太短而无法显示路径的情况下显示省略号按钮('...')、文本框和工具提示。它还不完美,因为我正在寻找如何添加额外的属性来设置 'BrowseForFolder' 对话框的其他属性,但我想我会分享我的发现。

我的编辑器定义如下:

public class BrowseForFolderEditor : DialogPropertyValueEditor
{
    public BrowseForFolderEditor()
    {
        // Create a textbox, a '...' button and a tooltip.
        string template = @"
            <DataTemplate
                xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
                xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
                xmlns:pe='clr-namespace:System.Activities.Presentation.PropertyEditing;assembly=System.Activities.Presentation'>
                <DockPanel LastChildFill='True'>
                    <pe:EditModeSwitchButton TargetEditMode='Dialog' Name='EditButton' DockPanel.Dock='Right'>...</pe:EditModeSwitchButton>
                    <TextBlock Text='{Binding Value}' Margin='2,0,0,0' VerticalAlignment='Center'>
                        <TextBox.ToolTip>
                            <ToolTip>
                                <TextBlock Text='{Binding Value}' Margin='2' VerticalAlignment='Center' HorizontalAlignment='Left'/>
                            </ToolTip>
                        </TextBox.ToolTip>
                    </TextBlock>
                </DockPanel>
            </DataTemplate>";

        using (var sr = new MemoryStream(Encoding.UTF8.GetBytes(template)))
        {
            this.InlineEditorTemplate = XamlReader.Load(sr) as DataTemplate;
        }
    }

    public override void ShowDialog(PropertyValue propertyValue, 
      IInputElement commandSource)
    {
        var browse = new FolderBrowserDialog
        {
            ShowNewFolderButton = true,
            SelectedPath = propertyValue.StringValue,
            Description = "Select Target Folder:",
            RootFolder = Environment.SpecialFolder.MyComputer
        };

        if (browse.ShowDialog() == DialogResult.OK)
        {
            propertyValue.Value = browse.SelectedPath;
        }

        browse.Dispose();
    }
}

我不会详细介绍 XAML,但有几点需要注意:

  1. 如何设置 InlineEditorTemplate,即将其设置为字符串中预定义的 XAML。
  2. 文本框的绑定,即值
  3. 工具提示的绑定,即值

Activity 构造函数中包含的 'important' 代码是:

AttributeTableBuilder builder = new AttributeTableBuilder();

builder.AddCustomAttributes(typeof(CopyMoveFiles), "TargetPath",
            new EditorAttribute(
            typeof(BrowseForFolderEditor), 
            typeof(DialogPropertyValueEditor)));

MetadataStore.AddAttributeTable(builder.CreateTable());

其中 TargetPath 表示将显示在 PropertyGrid 中的字符串 属性。

肯定有改进的余地,但这只是一个开始,而且似乎工作得很好。值得一提的是,添加各种参考文献是一件痛苦的事情。我不能再浪费时间在这上面了,但是即使按照 Microsoft 项目添加了所有引用之后,它仍然无法正常工作,最终还是成功了,所以我仍然不确定为什么会发生这种情况,这很遗憾但如果有人尝试过并能查明是哪个参考给他们带来了麻烦,我很想知道。

希望对您有所帮助。

更新:

如果您不想在构造函数中以编程方式定义属性,您可以简单地使用属性:

[Editor(typeof(BrowseForFolderEditor), typeof(DialogPropertyValueEditor))]
public string TargetPath { get; set; }