Невозможно перетащить действия из WPF ListBox в WorkflowView. - PullRequest
1 голос
/ 19 ноября 2009

Я пытаюсь разместить Workflow Designer в приложении 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.

Я создал пользовательскую панель инструментов, используя элемент управления ListBox WPF, связанный со списком элементов 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>

В обработчике 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);
 }
}

При такой настройке я не могу перетащить какой-либо элемент из моей пользовательской панели инструментов в конструктор. Курсор всегда отображается как «Нет» в любом месте дизайнера.

Я уже полдня пытаюсь найти что-нибудь об этом в сети, и я очень надеюсь, что кто-нибудь мне поможет.

Любая обратная связь высоко ценится. Спасибо!

Carlos

Ответы [ 2 ]

0 голосов
/ 23 ноября 2009

Наконец-то работает Drag and Drop. По какой-то причине WorkflowView нужно было выполнить три вещи:

1.) Мне пришлось использовать System.Windows.Forms.DataObject вместо System.Windows.DataObject при сериализации ToolboxItem при выполнении 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 должно быть установлено значение IToolboxService, установленное в IDesignerHost. Элемент управления, содержащий 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.

Cheers, Carlos

0 голосов
/ 19 ноября 2009

Это может звучать глупо, когда моя система выключается. :) Но можете ли вы проверить свой WorkflowView, установлен ли AllowDrop? Вы обрабатывали событие DragEnter?

...