C# 无法将活动从WPF列表框拖动到WorkflowView中

C# 无法将活动从WPF列表框拖动到WorkflowView中,c#,wpf,workflow,workflow-foundation,winforms-interop,C#,Wpf,Workflow,Workflow Foundation,Winforms Interop,我正在尝试在WPF应用程序中托管工作流设计器。WorkflowView控件位于WindowsFormsHost控件下。我已成功地将工作流加载到设计器中,该设计器已成功链接到PropertyGrid,它也托管在另一个WindowsFormsHost中 WorkflowView workflowView = rootDesigner.GetView(ViewTechnology.Default) as WorkflowView; window.WorkflowViewHost.Child = wor

我正在尝试在WPF应用程序中托管工作流设计器。WorkflowView控件位于WindowsFormsHost控件下。我已成功地将工作流加载到设计器中,该设计器已成功链接到PropertyGrid,它也托管在另一个WindowsFormsHost中

WorkflowView workflowView = rootDesigner.GetView(ViewTechnology.Default) as WorkflowView;
window.WorkflowViewHost.Child = workflowView;
大多数重宿主代码与中的相同

我使用绑定到ToolboxItems列表的ListBox WPF控件创建了一个自定义工具箱

<ListBox Grid.Row="1" Margin="0 0 0 4" BorderThickness="1" BorderBrush="DarkGray" ItemsSource="{Binding Path=ToolboxItems}" PreviewMouseLeftButtonDown="ListBox_PreviewMouseLeftButtonDown" AllowDrop="True">
 <ListBox.Resources>
  <vw:BitmapSourceTypeConverter x:Key="BitmapSourceConverter" />
 </ListBox.Resources>
 <ListBox.ItemTemplate>
  <DataTemplate DataType="{x:Type dd:ToolboxItem}">
   <StackPanel Orientation="Horizontal" Margin="3">
    <Image Source="{Binding Path=Bitmap, Converter={StaticResource BitmapSourceConverter}}" Height="16" Width="16" Margin="0 0 3 0"     />
    <TextBlock Text="{Binding Path=DisplayName}" FontSize="14" Height="16" VerticalAlignment="Center" />
    <StackPanel.ToolTip>
     <TextBlock Text="{Binding Path=Description}" />
    </StackPanel.ToolTip>
   </StackPanel>
  </DataTemplate>
 </ListBox.ItemTemplate>
</ListBox>
使用该设置,我无法将任何项目从自定义工具箱拖到设计器上。在设计器中,光标始终显示为“无”

我已经在网上找了半天了,我真的希望有人能帮我

非常感谢您的反馈。谢谢大家!


Carlos这听起来可能很愚蠢,因为我的系统正在关闭:但是您可以检查WorkflowView是否设置了AllowDrop吗?您处理过DragEnter事件吗?

终于可以进行拖放操作了。无论出于何种原因,WorkflowView都需要做三件事:

一,。在执行DragDrop时序列化ToolboxItem时,我必须使用System.Windows.Forms.DataObject而不是System.Windows.DataObject

private void ListBox_MouseDownHandler(object sender, MouseButtonEventArgs e)
{
    ListBox parent = (ListBox)sender;

    //get the object source for the selected item
    object data = GetObjectDataFromPoint(parent, e.GetPosition(parent));

    //if the data is not null then start the drag drop operation
    if (data != null)
    {
        System.Windows.Forms.DataObject dataObject = new System.Windows.Forms.DataObject();
        dataObject.SetData(typeof(ToolboxItem), data as ToolboxItem);
        DragDrop.DoDragDrop(this, dataObject, DragDropEffects.Move | DragDropEffects.Copy);
    }
}
二,。DragDrop.DoDragDrop源必须设置为IDesignerHost中的IToolboxService集。持有ListBox的控件实现IToolboxService

// "this" points to ListBox's parent which implements IToolboxService.
DragDrop.DoDragDrop(this, dataObject, DragDropEffects.Move | DragDropEffects.Copy);
三,。ListBox应绑定到由以下helper方法返回的ToolboxItems列表,并向其传递要在工具箱中显示的活动类型:

...
this.ToolboxItems = new ToolboxItem[] 
    {
        GetToolboxItem(typeof(IfElseActivity))
    };
...

internal static ToolboxItem GetToolboxItem(Type toolType)
{
    if (toolType == null)
        throw new ArgumentNullException("toolType");

    ToolboxItem item = null;
    if ((toolType.IsPublic || toolType.IsNestedPublic) && typeof(IComponent).IsAssignableFrom(toolType) && !toolType.IsAbstract)
    {
        ToolboxItemAttribute toolboxItemAttribute = (ToolboxItemAttribute)TypeDescriptor.GetAttributes(toolType)[typeof(ToolboxItemAttribute)];
        if (toolboxItemAttribute != null && !toolboxItemAttribute.IsDefaultAttribute())
        {
            Type itemType = toolboxItemAttribute.ToolboxItemType;
            if (itemType != null)
            {
                // First, try to find a constructor with Type as a parameter.  If that
                // fails, try the default constructor.
                ConstructorInfo ctor = itemType.GetConstructor(new Type[] { typeof(Type) });
                if (ctor != null)
                {
                    item = (ToolboxItem)ctor.Invoke(new object[] { toolType });
                }
                else
                {
                    ctor = itemType.GetConstructor(new Type[0]);
                    if (ctor != null)
                    {
                        item = (ToolboxItem)ctor.Invoke(new object[0]);
                        item.Initialize(toolType);
                    }
                }
            }
        }
        else if (!toolboxItemAttribute.Equals(ToolboxItemAttribute.None))
        {
            item = new ToolboxItem(toolType);
        }
    }
    else if (typeof(ToolboxItem).IsAssignableFrom(toolType))
    {
        // if the type *is* a toolboxitem, just create it..
        //
        try
        {
            item = (ToolboxItem)Activator.CreateInstance(toolType, true);
        }
        catch
        {
        }
    }

    return item;
}
GetToolboxItem方法来自ToolboxService类中的源代码

干杯,
Carlos

是的,我已经在WindowsFormsHost和WorkflowView控件中检查了AllowDrop,它们都设置为true。我还处理了DrageEvent,e.Data参数字段包含System.Windows.Forms.DataObject,相当于调用DragDrop.DoDragDrop之前创建的System.Windows.DataObject。我能够从e.Data中获得ToolboxItem,一切正常。
...
this.ToolboxItems = new ToolboxItem[] 
    {
        GetToolboxItem(typeof(IfElseActivity))
    };
...

internal static ToolboxItem GetToolboxItem(Type toolType)
{
    if (toolType == null)
        throw new ArgumentNullException("toolType");

    ToolboxItem item = null;
    if ((toolType.IsPublic || toolType.IsNestedPublic) && typeof(IComponent).IsAssignableFrom(toolType) && !toolType.IsAbstract)
    {
        ToolboxItemAttribute toolboxItemAttribute = (ToolboxItemAttribute)TypeDescriptor.GetAttributes(toolType)[typeof(ToolboxItemAttribute)];
        if (toolboxItemAttribute != null && !toolboxItemAttribute.IsDefaultAttribute())
        {
            Type itemType = toolboxItemAttribute.ToolboxItemType;
            if (itemType != null)
            {
                // First, try to find a constructor with Type as a parameter.  If that
                // fails, try the default constructor.
                ConstructorInfo ctor = itemType.GetConstructor(new Type[] { typeof(Type) });
                if (ctor != null)
                {
                    item = (ToolboxItem)ctor.Invoke(new object[] { toolType });
                }
                else
                {
                    ctor = itemType.GetConstructor(new Type[0]);
                    if (ctor != null)
                    {
                        item = (ToolboxItem)ctor.Invoke(new object[0]);
                        item.Initialize(toolType);
                    }
                }
            }
        }
        else if (!toolboxItemAttribute.Equals(ToolboxItemAttribute.None))
        {
            item = new ToolboxItem(toolType);
        }
    }
    else if (typeof(ToolboxItem).IsAssignableFrom(toolType))
    {
        // if the type *is* a toolboxitem, just create it..
        //
        try
        {
            item = (ToolboxItem)Activator.CreateInstance(toolType, true);
        }
        catch
        {
        }
    }

    return item;
}