ドラッグ アンド ドロップにより、読み取り専用の WinForm コンテナが変更されます (さらに、ドラッグ アンド ドロップのその他の特徴)
-
11-09-2019 - |
質問
1 つのアプリケーション内の WinForm RichTextBox 間、および WinForm RichTextBox と外部アプリケーション間のドラッグ アンド ドロップをサンプリングすると、2 つの興味深い観察結果が明らかになりました (項目 1 は確かにバグであるようです。完璧な世界では、項目 2 もおそらく同様でしょう):
- 一部のドラッグ アンド ドロップ操作では、ドラッグされたテキストがソース コンテナから削除されます。 読み取り専用に設定されているかどうか. 。(このことに最初に気づいてくれた Mark Morgan に感謝します。 バグレポート 私のオープンソース サイトにあります。)
- テキストがソース コンテナから保持されるか削除されるかは、アプリケーションによって異なります。
ドラッグ アンド ドロップの動作がどのようなものであるかを示す決定的なリファレンスは見つかりませんでした。私が見つけた最も近いものは、 Windows ユーザー エクスペリエンス インタラクション ガイドライン (Vistaの場合):「ドラッグアンドドロップ:オブジェクトはドロップ ターゲットに移動またはコピーされます。」そうですね、それは確かに私の観察と一致します。オブジェクトを移動するアプリケーションもあれば、コピーするアプリケーションもあります。
質問:上記の項目 1 の回避策を見つけたいと思います。読み取り専用コンテナが無違反ではないことに腹が立ちます。二次的な質問として、ドラッグ アンド ドロップがどのように動作するかについて参考になっている人がいるかどうか疑問に思っています。いつが移動で、いつがコピーなのか?
私のサンプル WinForm アプリケーション (以下のコード) には 2 つの RichTextBox コントロールが含まれており、左側のコントロールは読み取り専用 (これを RTB1 と呼びます) で、テキストで初期化されています。右側 (RTB2) は読み取り/書き込みが行われるため、テキストを受信できるようになります。どちらもテスト用にドラッグ アンド ドロップが有効になっています。私がテストした組み合わせは次のとおりです。各グループに少なくとも 1 つの「odd-man-out」があることに注意してください。
- RTB1 から RTB2 へ:動く
- RTB1 から他の RTB (外部) へ:動く
- RTB1 からワードパッドへ:コピー
- RTB1 から Word2003 へ:動く
- RTB1 から Outlook2003 へ:コピー
RTB1からFirefox3.0へ:コピー
RTB2 から他の RTB (外部) へ:動く
- RTB2 からワードパッドへ:コピー
- RTB2 から Outlook2003 へ:コピー
RTB2からFirefox3.0へ:コピー
Outlook2003 から RTB2 へ:動く
- ワードパッドから RTB2 へ:動く
- Word2003からRTB2へ:動く
- 他の RTB (外部) から RTB2 へ:動く
Firefox3.0からRTB2へ:コピー
Word2003からOutlook2003へ:コピー
- 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);
}
}
}
解決
これに関して何も提出されていなかったので、私はこの問題をさらに掘り下げました。
まず、いくつか入手しました マイクロソフトからの情報 (MSDN サポート経由) 標準のドラッグ アンド ドロップ動作では、 動く Control を押したままドラッグ アンド ドロップすると、 コピー.
次に、次の 3 つの動作モードを考慮してください。
- ユーザーはテキストを編集できます。
- ユーザーはテキストを (ドラッグ アンド ドロップで) 移動できます。
- アプリケーションはプログラムによってテキストを変更できます。
Microsoft によると、設定は 読み取り専用 項目 (1) のみを無効にします。名誉のためにも 読み取り専用 項目 (2) については、読み取り専用プロパティを使用するのではなく、ソリューションを手動でコーディングする必要があります。
まあ、私にとって、これは明らかに欠陥です。私は信じている 読み取り専用 (1) と (2) の両方を無効にする必要があります。それで私は提出しました 公式の欠陥報告書 この意見を支持する Microsoft Connect へのコメント。残念ながら、基本的に次のような応答が返されました。 「ありがとう。ただし、修正するほど重要な問題ではありません。」 はぁ...