title: Drag-and-drop modifies read-only WinForm container (plus other peculiarities of drag-and-drop)
body: <p>Sampling drag-and-drop between WinForm RichTextBoxes within one application and between them and external applications revealed two interesting observations (item 1 certainly appears to be a bug; in a perfect world, item 2 would probably be as well):</p>
  
  <ol>
  <li>Some drag-and-drop operations delete the dragged text from the source container, <strong><em>whether or not it is set to read-only</em></strong>. (Thanks to Mark Morgan for first noticing this in his <a href="http://sourceforge.net/tracker/?func=detail&amp;aid=2832993&amp;group_id=101363&amp;atid=629536" rel="nofollow noreferrer">bug report</a> on my open-source site.)</li>
  <li>Whether text is retained or deleted from a source container is inconsistent among different applications.</li>
  </ol>
  
  <p>I could not find any definitive reference indicating what drag-and-drop behavior is supposed to be. The closest I found was on page 476 of the <em>Windows User Experience Interaction Guidelines</em> (for Vista):
  "Dragging and dropping: Object is moved or copied to the drop target". Well, that certainly aligns with my observations; some applications move the object, others copy it!</p>
  
  <p>The questions:  I would like to find a workaround for item 1 above; it irks me that a read-only container is not inviolate! As a secondary question, I am wondering if someone has a reference to how drag-and-drop is supposed to behave? When is it a move and when is it a copy?</p>
  
  <p>My sample WinForm application (code below) contains two RichTextBox controls, the left one being read-only (call this RTB1) and initialized with some text; the right one (RTB2) being read/write so it may receive text. Both have drag-and-drop enabled for the test. Here are the combinations I tested; notice that in each grouping there is at least one  "odd-man-out" :</p>
  
  <hr>
  
  <ol>
  <li>From RTB1 to RTB2: move</li>
  <li>From RTB1 to other RTB (external): move</li>
  <li>From RTB1 to WordPad: copy</li>
  <li>From RTB1 to Word2003: move</li>
  <li>From RTB1 to Outlook2003: copy</li>
  <li><p>From RTB1 to Firefox3.0: copy</p>
  
  <hr></li>
  <li><p>From RTB2 to other RTB (external): move</p></li>
  <li>From RTB2 to WordPad: copy</li>
  <li>From RTB2 to Outlook2003: copy</li>
  <li><p>From RTB2 to Firefox3.0: copy</p>
  
  <hr></li>
  <li><p>From Outlook2003 to RTB2: move</p></li>
  <li>From WordPad to RTB2: move</li>
  <li>From Word2003 to RTB2: move</li>
  <li>From other RTB (external) to RTB2: move</li>
  <li><p>From Firefox3.0 to RTB2: copy</p>
  
  <hr></li>
  <li><p>From Word2003 to Outlook2003: copy</p></li>
  <li>From Outlook2003 to Word2003 : move
  
  <hr></li>
  </ol>
  
  <p>Tests run on WinXP.<br>
  Test app compiled with .NET 2.0 (tried a couple with .NET 3.5 with the same results).</p>
  
  <hr>
  
  <p>Here is the sample application:</p>
  
  <pre><code>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 &amp;&amp; (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);
          }
      }
  }
  </code></pre>