无法将活动从 WPF ListBox 拖到 WorkflowView 中

发布于 2024-08-11 16:55:14 字数 2296 浏览 6 评论 0原文

我正在尝试在 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);
 }
}

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

我已经在网上寻找有关此问题的任何信息半天了,我真的希望有人可以帮助我。

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

卡洛斯

I'm trying to host the Workflow Designer in a WPF application. The WorkflowView control is hosted under a WindowsFormsHost control. I've managed to load workflows onto the designer which is successfully linked to a PropertyGrid, also hosted in another WindowsFormsHost.

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

The majority of the rehosting code is the same as in http://msdn.microsoft.com/en-us/library/aa480213.aspx.

I've created a custom Toolbox using a ListBox WPF control bound to a list of ToolboxItems.

<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>

In the ListBox_PreviewMouseLeftButtonDown handler:

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);
 }
}

With that setup, I'm unable to drag any item from my custom Toolbox onto the designer. The cursor is always displayed as "No" anywhere on the designer.

I've been trying to find anything about this on the net for half a day now and I really hope some can help me here.

Any feedback is much appreciated. Thank you!

Carlos

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

帅的被狗咬 2024-08-18 16:55:14

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

This might sound stupid as my system is shutting down. :) But can you check your WorkflowView for whether AllowDrop is set? Have you handled the DragEnter event?

深空失忆 2024-08-18 16:55:14

终于让拖放工作了。无论 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 类中。

干杯,
卡洛斯

Finally got Drag and Drop working. There were three things that needed doing, for whatever reason WorkflowView has:

1.) I had to use System.Windows.Forms.DataObject instead of System.Windows.DataObject when serializing the ToolboxItem when doing DragDrop.

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 source must be set to the IToolboxService set in the IDesignerHost. The control holding the ListBox implements IToolboxService.

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

3.) The ListBox should be bound to a list of ToolboxItems returned by the following helper method, passing it the Type of the activities to show in the tool box:

...
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 method is from http://msdn.microsoft.com/en-us/library/aa480213.aspx source, in the ToolboxService class.

Cheers,
Carlos

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文