Patrick Skelton Ответов: 2

Почему я получаю неправильный значок перетаскивания мыши в списке?


У меня есть ListBox это отображает файлы в реальном физическом каталоге. Иногда ни один каталог не был выбран, и в этом случае ListBox остается пустым.

У меня есть код, который позволяет пользователям копировать файлы в отображаемый каталог. Когда я делаю это, я получаю правильный значок мыши, чтобы указать пользователю, что это допустимое действие.

Если не отображается ни один допустимый каталог, пользователь все равно может попытаться поместить файлы в него. ListBox Код корректно игнорирует такой запрос, но я, похоже, не могу заставить его отображать правильный значок мыши, чтобы показать пользователю, что то, что он пытается сделать, не имеет смысла.

Это код, который должен управлять значком мыши:

код XAML
<ListBox x:Name="ListBoxFiles" ItemsSource="{Binding Files}" AllowDrop="True" SelectionMode="Single"
	DragOver="ListBox_Files_DragOver"
	Drop="ListBox_Files_Drop"
	MouseLeftButtonUp="ListBoxFiles_MouseLeftButtonUp"
	MouseDoubleClick="ListBox_Files_MouseDoubleClick">
</ListBox>


В коде-за спиной:

private void ListBox_Files_DragOver( object sender, DragEventArgs e )
{
	if( GetWindowLogic<MainWindowLogic>().ValidProjectsDirectory && e.Data.GetDataPresent( DataFormats.FileDrop ) )
	{
		QA.LogTrace( $"Got a valid directory and data." );
		e.Effects = DragDropEffects.Copy;
	}
	else
	{
		QA.LogTrace( $"Either a valid directory or data is absent." );
		e.Effects = DragDropEffects.None;
	}
}


Обратите внимание, что я получаю ожидаемые сообщения трассировки в своем файле журнала, но DragDropEffects.None кажется, это не работает.

Может ли кто-нибудь сказать мне, что я делаю не так?

Что я уже пробовал:

Код, показанный в тексте выше.

Jochen Arndt

Я не знаю, понимаю ли я эту проблему.
Когда перетаскивание вокруг во время падения невозможно, это обозначается курсором (или знаком остановки). Как только вы войдете в область, где возможно падение, курсор изменится.

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

Из вашего описания я бы подумал, что курсор всегда меняется на "может упасть" при входе в ваш список, даже если он пуст. Если это так, то это странное поведение, потому что ваш код выглядит нормально.

Patrick Skelton

Да, Йохен, именно это и происходит. Я получаю символ No-Drop, когда перетаскиваю любую область своего рабочего стола, которая не принимает падение. Когда я перемещаюсь над своим главным окном приложения, я все еще получаю No-Drop. Но как только я перехожу через список, я получаю символ Can-Drop.

Я предполагаю, что мой else{} делает то, что должен, но, возможно, что-то выше или ниже в визуальном дереве XAML переопределяет это поведение.

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

Jochen Arndt

Спасибо за разъяснение.

Я не знаю XAML, так что, возможно, от меня будет мало толку.

Буксировать больше вопросов:
Что такое источник перетаскивания (Проводник Windows или ваше / другое приложение)?
Меняет курсор назад, чтобы не упасть, когда оставив свой (пустой) список?

Некоторая справочная информация:
Функция, ответственная за рисование курсора, - это реализация обратной связи drag &drop источника перетаскивания, которая использует эффект, переданный от обработчиков цели перетаскивания (enter, over, drop и leave).

Patrick Skelton

Источником перетаскивания является проводник. Курсор действительно возвращается к символу остановки при выходе из списка. Спасибо за дополнительную информацию.

Patrick Skelton

Обходной путь состоит в том, чтобы привязать свойство IsEnabled списка к логическому свойству ValidProjectsDirectory, которое устанавливается true только тогда, когда панель файлов показывает содержимое каталога.

Jochen Arndt

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

Но ваш журнал показывает, что вы установили эффект "нет". Так что изменить его можно будет только позже.

Что произойдет, если вы всегда устанавливаете None в обработчике?
Если вы затем все еще получаете курсор can drop, это доказывает, что он установлен где-то еще.

Patrick Skelton

Ты прав, Йохен. Если я выну обходной путь, о котором я упоминал выше, и сделаю так, чтобы обе части if{}else{} возвращали эффект None, я все равно получу can-drop над списком. Таким образом, мой обработчик событий игнорируется. Что-то еще просто использует свойство AllowDrop="True" в списке, чтобы установить символ can-drop.

Jochen Arndt

Ваш обработчик вызывается, но настройка эффекта игнорируется или изменяется где-то еще позже.

У меня больше нет идей (недостаточно знаний о том, как drag & drop обрабатывается приложениями XAML / списками).

Надеюсь, кто - нибудь еще сможет помочь.

2 Ответов

Рейтинг:
4

Member 13515121

<ListBox x:Name="ListBoxFiles"
	ItemsSource="{Binding Files}"
	AllowDrop="True"
	SelectionMode="Single"
	DragEnter="ListBox_Files_DragEnterOverLeave"
	DragOver="ListBox_Files_DragEnterOverLeave"
	DragLeave="ListBox_Files_DragEnterOverLeave"
	Drop="ListBox_Files_Drop"
	MouseLeftButtonUp="ListBoxFiles_MouseLeftButtonUp"
	MouseDoubleClick="ListBox_Files_MouseDoubleClick">
</ListBox>






частная ListBox_Files_DragEnterOverLeave недействительным( объект отправителя, DragEventArgs е )
{
если( GetWindowLogic&ЛТ;mainwindowlogic и GT;().ValidProjectsDirectory &&усилителя; электронные.Данных.GetDataPresent( Версии Dataformats.FileDrop ) )
{
КК.LogTrace( $"получил допустимый каталог и данные в обработчике событий." );
e.Effects = DragDropEffects.Копировать;
}
еще
{
КК.LogTrace( $"в обработчике событий отсутствует либо допустимый каталог, либо данные." );
e.Effects = DragDropEffects.None;
е.Обработано = истина;
}
}


Рейтинг:
20

Patrick Skelton

Кажется, решение таково: Обрабатывать События Перетаскивания

Теперь мой код таков...

<ListBox x:Name="ListBoxFiles"
	ItemsSource="{Binding Files}"
	AllowDrop="True"
	SelectionMode="Single"
	DragEnter="ListBox_Files_DragEnterOverLeave"
	DragOver="ListBox_Files_DragEnterOverLeave"
	DragLeave="ListBox_Files_DragEnterOverLeave"
	Drop="ListBox_Files_Drop"
	MouseLeftButtonUp="ListBoxFiles_MouseLeftButtonUp"
	MouseDoubleClick="ListBox_Files_MouseDoubleClick">
</ListBox>


private void ListBox_Files_DragEnterOverLeave( object sender, DragEventArgs e )
{
	if( GetWindowLogic<MainWindowLogic>().ValidProjectsDirectory && e.Data.GetDataPresent( DataFormats.FileDrop ) )
	{
		QA.LogTrace( $"Got a valid directory and data in event handler." );
		e.Effects = DragDropEffects.Copy;
	}
	else
	{
		QA.LogTrace( $"Either a valid directory or data is absent in event handler." );
		e.Effects = DragDropEffects.None;
		e.Handled = true;
	}
}


Jochen Arndt

Прекрасно видеть, что вы решили эту проблему (у вас должна была быть идея, что все обработчики должны быть реализованы).