Перетаскивание изменяет контейнер WinForm, доступный только для чтения (плюс другие особенности перетаскивания)
-
11-09-2019 - |
Вопрос
Выборочное перетаскивание между WinForm RichTextBoxes внутри одного приложения и между ними и внешними приложениями выявило два интересных наблюдения (пункт 1, безусловно, является ошибкой;в идеальном мире пункт 2, вероятно, был бы таким же):
- Некоторые операции перетаскивания удаляют перетаскиваемый текст из исходного контейнера, независимо от того, установлен ли он в режим только для чтения.(Спасибо Марку Моргану за то, что он впервые заметил это в своем отчет об ошибке на моем сайте с открытым исходным кодом.)
- Сохранение или удаление текста из исходного контейнера не согласуется между различными приложениями.
Я не смог найти какой-либо окончательной ссылки, указывающей, каким должно быть поведение перетаскивания.Самое близкое, что я нашел, было на странице 476 Рекомендации по взаимодействию с пользователем Windows (для Vista):"Перетаскивание:Объект перемещен или скопирован в цель удаления".Что ж, это определенно согласуется с моими наблюдениями;некоторые приложения перемещают объект, другие копируют его!
Вопросы:Я хотел бы найти обходной путь для пункта 1 выше;меня раздражает, что контейнер, доступный только для чтения, не является неприкосновенным!В качестве второстепенного вопроса мне интересно, есть ли у кого-нибудь ссылка на то, как должно вести себя перетаскивание?Когда это перемещение, а когда копия?
Мой пример приложения WinForm (код ниже) содержит два элемента управления RichTextBox, левый из которых доступен только для чтения (назовите это RTB1) и инициализирован некоторым текстом;правый (RTB2) читается / записывается, поэтому он может получать текст.В обоих случаях для теста включено перетаскивание.Вот комбинации, которые я протестировал;обратите внимание, что в каждой группе есть по крайней мере один "лишний человек". :
- От RTB1 до RTB2:двигаться
- Из RTB1 в другой RTB (внешний):двигаться
- Из RTB1 в WordPad:Копировать
- Из RTB1 в Word2003:двигаться
- От RTB1 до Outlook 2003:Копировать
От RTB1 до Firefox3.0:Копировать
Из RTB2 в другой RTB (внешний):двигаться
- Из RTB2 в WordPad:Копировать
- От RTB2 до Outlook 2003:Копировать
От RTB2 до Firefox3.0:Копировать
Из Outlook 2003 в RTB2:двигаться
- Из WordPad в RTB2:двигаться
- Из Word2003 в RTB2:двигаться
- Из другого RTB (внешнего) в RTB2:двигаться
От Firefox3.0 до RTB2:Копировать
Из Word2003 в Outlook 2003:Копировать
- Из Outlook 2003 в Word2003 :двигаться
Тесты выполняются на WinXP.
Тестовое приложение, скомпилированное с .NET 2.0 (попробовал пару с .NET 3.5 с теми же результатами).
Вот пример приложения:
using System;
using System.Windows.Forms;
namespace RichTextBoxTest
{
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
partial class Form1 : Form
{
private RichTextBox richTextBox1 = new RichTextBox();
private RichTextBox richTextBox2 = new RichTextBox();
public Form1()
{
InitializeComponent();
}
private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
private void InitializeComponent()
{
this.SuspendLayout();
//
// richTextBox1
//
this.richTextBox1.EnableAutoDragDrop = true;
this.richTextBox1.Location = new System.Drawing.Point(34, 25);
this.richTextBox1.ReadOnly = true;
this.richTextBox1.Size = new System.Drawing.Size(122, 73);
this.richTextBox1.Text = "some stuff here";
//
// richTextBox2
//
this.richTextBox2.EnableAutoDragDrop = true;
this.richTextBox2.Location = new System.Drawing.Point(177, 25);
this.richTextBox2.Size = new System.Drawing.Size(122, 73);
this.richTextBox2.Text = "";
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(338, 122);
this.Controls.Add(this.richTextBox2);
this.Controls.Add(this.richTextBox1);
this.Text = "Form1";
this.ResumeLayout(false);
}
}
}
Решение
Поскольку никаких лакомых кусочков по этому поводу представлено не было, я углубился в проблему еще глубже.
Во-первых, я получил некоторые информация от Корпорации Майкрософт (через поддержку MSDN) это стандартное поведение перетаскивания выполняет двигаться удерживая нажатой клавишу Control с помощью drag-and-drop, вы выполняете Копировать.
Далее рассмотрим эти три режима работы:
- Пользователь может редактировать текст.
- Пользователь может перемещать текст (с помощью перетаскивания).
- Приложение может изменять текст программно.
Согласно Microsoft, настройка доступно только для чтения отключает только пункт (1) !Также почитать доступно только для чтения для элемента (2) необходимо вручную закодировать решение, а не использовать свойство только для чтения.
Ну, для меня это явный дефект.Я верю доступно только для чтения следует отключить оба (1) и (2).Итак, я представил официальный отчет о дефекте в Microsoft Connect, поддерживающий это мнение.Увы, ответ вернулся таким же по существу "Спасибо, но проблема не настолько важна, чтобы ее можно было исправить". Вздох...