Перетаскивание WPF внутри приложения, выбрасывающее HRESULT E_FAIL из компонента COM - PullRequest
2 голосов
/ 01 декабря 2010

У меня есть несколько UserControls в моем приложении, которые мне нужно поддерживать перетаскиванием, поэтому я выделил код в абстрактный класс, расширяющий UserControl (код ниже).Когда я использую это в одном элементе управления, который является частью DataTemplate в ListBox, все работает нормально.

Когда я использую его в элементе управления, который также может быть целью перетаскивания, я получаю следующее исключение в DoDragDropстрока:

COMException
Error HRESULT E_FAIL has been returned from a call to a COM component

Возможно, это связано с взаимодействием WinForms, но я не использую какие-либо компоненты WinForms или COM - приложение является чистым WPF.

Если я просто продолжу выполнение,падение произошло успешно.Если я окружаю вызов DoDragDrop блоком try с пустым блоком catch, кажется, что все работает так, как ожидалось.Я действительно не хочу отправлять код с таким хаком.

public abstract class DraggableUserControl : UserControl
{
    private Point? lastMouseDownPoint;

    protected override void  OnMouseLeftButtonDown(MouseButtonEventArgs e)
    {
        base.OnMouseLeftButtonDown(e);

        lastMouseDownPoint = e.GetPosition(this);
    }

    protected override void OnMouseMove(System.Windows.Input.MouseEventArgs e)
    {
        base.OnMouseMove(e);

        if (e.LeftButton == MouseButtonState.Pressed && lastMouseDownPoint != null)
        {
            Point mousePosition = e.GetPosition(this);

            if (((Point)lastMouseDownPoint - mousePosition).Length > 3)
            {
                BeginDrag();
            }
        }
    }

    protected override void OnMouseLeave(MouseEventArgs e)
    {
        base.OnMouseLeave(e);

        if (e.LeftButton == MouseButtonState.Pressed && lastMouseDownPoint != null)
        {
            BeginDrag();
        }
    }

    protected override void OnMouseUp(MouseButtonEventArgs e)
    {
        base.OnMouseUp(e);

        if (e.ChangedButton == MouseButton.Left)
        {
            lastMouseDownPoint = null;
        }
    }

    private void BeginDrag()
    {
        DataObject dragData = new DataObject(DragFormat, DragData);

        //try
        //{
            DragDrop.DoDragDrop(this, dragData, DragDropEffects.Move);
        //} catch {}

        lastMouseDownPoint = null;
    }

    protected abstract String DragFormat
    { get; }

    protected abstract Object DragData
    { get; }

    protected abstract DragDropEffects DragAllowedEffects
    { get; }
}

1 Ответ

3 голосов
/ 01 декабря 2010

Простой пример, созданный вашим классом, кажется, работает просто отлично. Я использовал строку и DragFormat из DataFormats.StringFormat. Работало просто отлично. Ганс прав, порицания нет.

Я предполагаю, что объект Data каким-то образом портит отражение Get Data или передает его обратно.

Мое предложение состояло бы в том, чтобы разбить ваш объект данных и посмотреть, имеет ли какая-либо конкретная часть ту же проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...