views:

86

answers:

0

I want to enable drag and drop operations in my application (c#, wpf). However I’ve concluded that my current model sometimes calls event duplicated. In the sample code below one sees the events that I’ve added to buttons in a stack-panel. The Stack-panel is data-bound against a collection of IToolboxItem.

I’ve determined that due STA events are executed sequentially rather than concurrently. It appears to queue the mouse-move event of the button around the ‘button in question’ (depends on how you move the mouse). And that DoDragDrop is implemented as context switch (cooperative multi threading).

I would like to know how/what I should modify my code so my drag-drop operations will not 'react' to the queued event (Assuming here I've no control over the queued event(s)).

    Point startPoint = new Point(0, 0);
    object source = null;

    private void MouseMove(object sender, MouseEventArgs e)
    {
        if ( source == sender )
        {
            Point mousePos = e.GetPosition(null);
            Vector diff = startPoint - mousePos;

            if (e.LeftButton == MouseButtonState.Pressed &&
                Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance &&
                Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance)
            {
                DataObject dragData = new DataObject("myFormat", (sender as Button).DataContext);
                DragDrop.DoDragDrop(sender as DependencyObject, dragData, DragDropEffects.Move);
                source = null;
            }
        }
    }

    private void PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        startPoint = e.GetPosition(null);
        source = sender;            
    }

    private void textEditor_Drop(object sender, DragEventArgs e)
    {
        if (e.Handled == true)
            return;

        if (sender == e.Source && e.Data.GetDataPresent("myFormat"))
        {
            IToolboxItem contact = e.Data.GetData("myFormat") as IToolboxItem;
            if (contact != null)
            {
                e.Handled = true;

                string text = string.Empty;
                switch (contact.Name)
                {
                    case "Button":
                        text = "<Button />";
                        break;
                    case "Listbox":
                        text = "<Listbox />";
                        break;
                }

                obj.textEditor.Document.Text += text;
            }

            e.Handled = true;
            e.Effects = DragDropEffects.None;
        }
    }

The above code may result in a single drop or two drops to be performed. It depends both on how you move your cursor over the buttons, and timing. Sometimes it would add '<combobox /><combobox />', sometimes '<combobox /><listbox />' and on occasion just plain '<combobox />'

Thanks in advance,