Перетаскивание изменяет контейнер WinForm только для чтения (плюс другие особенности перетаскивания)

Выборка перетаскивания между окнами WinForm RichTextBox в одном приложении и между ними и внешними приложениями выявила два интересных наблюдения (пункт 1, безусловно, является ошибкой; в идеальном мире пункт 2, вероятно, тоже был бы таким):

  1. Некоторые операции перетаскивания удаляют перетаскиваемый текст из исходного контейнера, независимо от того, настроен ли он только для чтения. (Спасибо Марку Моргану за то, что он первым заметил это в своем отчете об ошибке. на моем сайте с открытым исходным кодом.)
  2. Сохранение или удаление текста из исходного контейнера несовместимо между различными приложениями.

Я не смог найти какой-либо окончательной ссылки, указывающей, каким должно быть поведение перетаскивания. Самое близкое, что я нашел, было на странице 476 Рекомендаций по взаимодействию с пользователем в Windows (для Vista): «Перетаскивание: объект перемещается или копируется в цель перетаскивания». Что ж, это, безусловно, совпадает с моими наблюдениями; одни приложения перемещают объект, другие копируют!

Вопросы: Я хотел бы найти обходной путь для пункта 1 выше; меня раздражает, что контейнер только для чтения не является неприкосновенным! В качестве второстепенного вопроса мне интересно, есть ли у кого-нибудь ссылка на то, как должно вести себя перетаскивание? Когда это ход, а когда копия?

Мой пример приложения WinForm (код ниже) содержит два элемента управления RichTextBox, левый доступен только для чтения (назовем его RTB1) и инициализирован некоторым текстом; правый (RTB2) предназначен для чтения/записи, поэтому он может получать текст. У обоих включено перетаскивание для теста. Вот комбинации, которые я тестировал; обратите внимание, что в каждой группе есть по крайней мере один «лишний человек»:


  1. От RTB1 к RTB2: перейти
  2. От RTB1 к другому RTB (внешнему): перемещение
  3. Из RTB1 в WordPad: скопировать
  4. С RTB1 на Word2003: переход
  5. Из RTB1 в Outlook2003: скопировать
  6. С RTB1 на Firefox3.0: скопировать


  7. С RTB2 на другой RTB (внешний): переместить

  8. С RTB2 на WordPad: скопировать
  9. Из RTB2 в Outlook2003: скопировать
  10. С RTB2 на Firefox3.0: скопировать


  11. Из Outlook2003 в RTB2: переместить

  12. С WordPad на RTB2: переход
  13. С Word2003 на RTB2: переход
  14. С другого RTB (внешнего) на RTB2: переместить
  15. С Firefox3.0 на RTB2: скопировать


  16. Из Word2003 в Outlook2003: скопировать

  17. Из Outlook2003 в 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);
        }
    }
}

person Michael Sorens    schedule 06.08.2009    source источник


Ответы (1)


Не имея никаких лакомых кусочков, представленных по этому поводу, я углубился в проблему.

Во-первых, я получил некоторую информацию от Microsoft (через поддержку MSDN), что стандартное поведение перетаскивания выполняет перемещение, а удерживание нажатой клавиши Control с перетаскиванием выполняет копирование.

Далее рассмотрим эти три режима работы:

  1. Пользователь может редактировать текст.
  2. Пользователь может перемещать текст (посредством перетаскивания).
  3. Приложение может изменять текст программно.

Согласно Microsoft, настройка только для чтения отключает только элемент (1)! Чтобы также соблюдать только для чтения для элемента (2), необходимо вручную кодировать решение, а не использовать свойство только для чтения.

Ну для меня это явный недостаток. Я считаю, что только для чтения следует отключить как (1), так и (2). Поэтому я отправил официальный отчет о дефекте в Microsoft Connect, поддерживающий это мнение. Увы, ответ был по существу "Спасибо, но проблема не настолько важна, чтобы ее можно было исправить". Эх...

person Michael Sorens    schedule 26.08.2009
comment
Спасибо за информацию; полезные вещи. - person Joel in Gö; 04.03.2010