Drag and drop - System.InvalidOperationException

0

Hej.

Chce zrobić okno z dwoma panelami pomiędzy którymi będzie można przenosić TextBoxy.

Mam:
MainWindow.xaml

<Window x:Class="DragAndDropTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:DragAndDropTest"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>

        <StackPanel Grid.Column="0" Width="Auto" HorizontalAlignment="Stretch"
                AllowDrop="True" Drop="StackPanel_Drop">
            <TextBox IsReadOnly="True"  Text="Test1" MouseMove="TextBox_MouseMove" PreviewMouseLeftButtonDown="TextBox_PreviewMouseLeftButtonDown" />
            <TextBox IsReadOnly="True" Text="Test2" MouseMove="TextBox_MouseMove" PreviewMouseLeftButtonDown="TextBox_PreviewMouseLeftButtonDown"/>
            <TextBox IsReadOnly="True" Text="Test3" MouseMove="TextBox_MouseMove" PreviewMouseLeftButtonDown="TextBox_PreviewMouseLeftButtonDown"/>
        </StackPanel>

        <StackPanel Grid.Column="1" Width="Auto" HorizontalAlignment="Stretch"
                AllowDrop="True" Drop="StackPanel_Drop">
            <TextBox IsReadOnly="True" Text="Test4" MouseMove="TextBox_MouseMove" PreviewMouseLeftButtonDown="TextBox_PreviewMouseLeftButtonDown"/>
            <TextBox IsReadOnly="True" Text="Test5" MouseMove="TextBox_MouseMove" PreviewMouseLeftButtonDown="TextBox_PreviewMouseLeftButtonDown"/>
            <TextBox IsReadOnly="True" Text="Test6" MouseMove="TextBox_MouseMove" PreviewMouseLeftButtonDown="TextBox_PreviewMouseLeftButtonDown" />
        </StackPanel>
    </Grid>
</Window>

MainWindow.xaml.cs

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace DragAndDropTest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private TextBox draggedTextBox;
        
        public MainWindow()
        {
            InitializeComponent();
        }

        private void TextBox_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            draggedTextBox = sender as TextBox;
        }

        private void TextBox_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed && draggedTextBox != null)
            {
                draggedTextBox.Dispatcher.Invoke(() =>
                {
                    DragDrop.DoDragDrop(draggedTextBox, draggedTextBox.Text, DragDropEffects.Move);
                });
            }
        }

        private void StackPanel_Drop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.Text))
            {
                string text = (string)e.Data.GetData(DataFormats.Text);

                if (sender != draggedTextBox.Parent)
                {
                    var stackPanel = sender as StackPanel;
                    if (stackPanel != null)
                    {
                        var textBox = new TextBox { Text = text };
                        stackPanel.Children.Add(textBox);
                    }

                    var originalStackPanel = draggedTextBox.Parent as StackPanel;
                    if (originalStackPanel != null)
                    {
                        originalStackPanel.Children.Remove(draggedTextBox);
                    }
                }
            }
        }
    }
}

Przy próbie przeciągnięcia elementu na linii:

DragDrop.DoDragDrop(draggedTextBox, draggedTextBox.Text, DragDropEffects.Move);

w metodzie TextBox_MouseMove dostaje wyjątek:
System.InvalidOperationException: 'Przetwarzanie dyspozytora zostało wstrzymane, ale komunikaty są wciąż przetwarzane.'

Nie mogę znaleźć rozwiązania w necie.
Podpowiecie mi co zrobiłem źle?

Pozdrawiam

1

najpierw polecam zmienic język na angielski i dopiero szukac w necie po tresci bledu.

0

Drag&drop działa trochę dziwnie i ingeruje w kolejkę komunikatów uruchamiając jakby alternatywny event loop, nie wiem jak się zachowa w połączeniu z Dispatcher.Invoke które dokłada rzeczy do zrobienia na koniec kolejki. Podejrzewam że nie lubią się ze sobą i powinieneś to wywalić.
W ogóle od wprowadzenia async / await nie powinieneś potrzebować Dispatcher.Invoke

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.