1

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

WorkflowView workflowView = rootDesigner.GetView(ViewTechnology.Default) as WorkflowView;
window.WorkflowViewHost.Child = workflowView;

大多数重新托管代码与http://msdn.microsoft.com/en-us/library/aa480213.aspx中的相同。

我使用绑定到 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>

在 ListBox_PreviewMouseLeftButtonDown 处理程序中:

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

 UIElement dataContainer;
 //get the ToolboxItem for the selected item
 object data = GetObjectDataFromPoint(parent, e.GetPosition(parent), out dataContainer);

 //if the data is not null then start the drag drop operation
 if (data != null)
 {
  DataObject dataObject = new DataObject();
  dataObject.SetData(typeof(ToolboxItem), data);

  DragDrop.DoDragDrop(parent, dataObject, DragDropEffects.Move | DragDropEffects.Copy);
 }
}

使用该设置,我无法将自定义工具箱中的任何项目拖到设计器上。光标在设计器的任何位置始终显示为“否”。

我已经尝试在网上找到有关此的任何信息半天了,我真的希望有人可以在这里帮助我。

非常感谢任何反馈。谢谢!

卡洛斯

4

2 回答 2

0

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

于 2009-11-19T09:35:14.867 回答
0

终于让拖放工作。无论出于何种原因,WorkflowView 都需要做三件事:

1.) 在进行 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);
    }
}

2.) DragDrop.DoDragDrop 源必须设置为 IDesignerHost 中设置的 IToolboxService。持有 ListBox 的控件实现了 IToolboxService。

// "this" points to ListBox's parent which implements IToolboxService.
DragDrop.DoDragDrop(this, dataObject, DragDropEffects.Move | DragDropEffects.Copy);

3.) ListBox 应该绑定到由以下帮助方法返回的 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 方法来自http://msdn.microsoft.com/en-us/library/aa480213.aspx源,在 ToolboxService 类中。

干杯,卡洛斯

于 2009-11-23T11:34:06.777 回答