ドラッグイベントを特定の方法で処理する必要があるwinformsコントロールがあります。このコントロールには、多くの子コントロールが含まれています。そのうちのいくつかは、ElementHost
オブジェクトに埋め込まれたWPFです。これは、ドラッグイベントを処理するために必要な最上位のwinformsコントロールです。ホストされているWPFコントロールで飲み込まれたイベントを、そのwinformsの親にドラッグします。
マウスがwinformsコンポーネント内で親の上にある間に、簡単にドラッグ動作を実行できます。私がする必要のあることは何もありません。しかし、WPFコントロールはブラックホールです。ドラッグイベントを呑み込んで、メインのwinformsコントロールが正しく処理できないように見えます。
私は次のようにこの問題を回避ハックすることができます
- は私がトップを見つけるまで
- オーバーライド
OnDragEnter
WPFコントロール - を再帰的に
ElementHost
から始まるControl.Parent
参照を歩くWPFコントロールにAllowDrop = true
を設定しましたレベルコントロールが必要です IDropTarget.OnDragEnter
最上位のコントロールで見つかった
ご想像のとおり、これはかなり醜いです:
public MyWPFControl()
{
InitializeComponent();
_host = new Lazy<System.Windows.Forms.Control>(BuildHostControl);
AllowDrop = true;
}
private System.Windows.Forms.Control BuildHostControl()
{
return new System.Windows.Forms.Integration.ElementHost
{
Dock = System.Windows.Forms.DockStyle.Fill,
Child = this,
};
}
protected override void OnDragEnter(DragEventArgs e)
{
base.OnDragEnter(e);
if (e.Data.GetDataPresent(typeof(MyDragObject)))
{
var args = ConvertDragArgs(e);
var control = GetControl(_host.Value)
((System.Windows.Forms.IDropTarget)control).OnDragEnter(args);
}
}
private System.Windows.Forms.DragEventArgs ConvertDragArgs(DragEventArgs e)
{
var dragObject = e.Data.GetData(typeof(MyDragObject)) as MyDragObject;
var position = e.GetPosition(this);
var data = new System.Windows.Forms.DataObject(dragObject);
return new System.Windows.Forms.DragEventArgs(data, (int)e.KeyStates, (int)position.X, (int)position.Y, System.Windows.Forms.DragDropEffects.Copy, System.Windows.Forms.DragDropEffects.Copy);
}
private MyTopLevelControl GetControl(System.Windows.Forms.Control control)
{
var cell = control as MyTopLevelControl;
if (cell != null)
return cell;
return GetControl(control.Parent);
}
同様の努力がOnDragDropのために取らなければならないが、簡潔にするために、私は確かに
それを省略している、私は挿入できトップレベルコントロールとWPFコントロールの両方の参照を持つヘルパーオブジェクトを使用して、ウォーキングコントロールを削除していくことができます。
しかし、私はそれを避けることができれば、ドラッグイベントをWPFコントロールで処理したいとは思っていません。トップレベルのコントロールでは、ドラッグしているときのように、子フォームのコントロールをwinformsします。これを達成する方法はありますか?