Son zamanlarda projemde Sürükle ve Bırak işlevini kullanmak istemiştim ve bu konuya rastlamamıştım, ancak merak ettim ve gerçekten de anlatılandan daha iyi bir yöntemle gelip gelemeyeceğimi görmek istedim. bağlandığınız sayfa. Umarım yapmak istediğin her şeyi açıkça anladım ve genel olarak problemi daha zarif ve basit bir şekilde çözmeyi başarabildiğimi düşünüyorum.
Hızlı bir yan notta, böyle bir sorun varsa, bazı kodları sağlamanız harika olur, böylece ne yapmaya çalıştığınızı tam olarak görürüz. Bunu sadece çözümümdeki kodunuzla ilgili birkaç şey üstlendiğim için söylüyorum ... yani umarım oldukça yakındır.
İşte aşağıda açıklayacağım kodu verilmiştir:
this.LabelDrag.QueryContinueDrag += new System.Windows.Forms.QueryContinueDragEventHandler(this.LabelDrag_QueryContinueDrag);
this.LabelDrag.MouseDown += new System.Windows.Forms.MouseEventHandler(this.LabelDrag_MouseDown);
this.LabelDrag.MouseUp += new System.Windows.Forms.MouseEventHandler(this.LabelDrag_MouseUp);
this.LabelDrop.DragDrop += new System.Windows.Forms.DragEventHandler(this.LabelDrop_DragDrop);
this.LabelDrop.DragEnter += new System.Windows.Forms.DragEventHandler(this.LabelMain_DragEnter);
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void LabelDrop_DragDrop(object sender, DragEventArgs e)
{
LabelDrop.Text = e.Data.GetData(DataFormats.Text).ToString();
}
private void LabelMain_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.Text))
e.Effect = DragDropEffects.Copy;
else
e.Effect = DragDropEffects.None;
}
private void LabelDrag_MouseDown(object sender, MouseEventArgs e)
{
//EXTREMELY IMPORTANT - MUST CALL LabelDrag's DoDragDrop method!!
//Calling the Form's DoDragDrop WILL NOT allow QueryContinueDrag to fire!
((Label)sender).DoDragDrop(TextMain.Text, DragDropEffects.Copy);
}
private void LabelDrag_MouseUp(object sender, MouseEventArgs e)
{
LabelDrop.Text = "LabelDrag_MouseUp";
}
private void LabelDrag_QueryContinueDrag(object sender, QueryContinueDragEventArgs e)
{
//Get rect of LabelDrop
Rectangle rect = new Rectangle(LabelDrop.Location, new Size(LabelDrop.Width, LabelDrop.Height));
//If the left mouse button is up and the mouse is not currently over LabelDrop
if (Control.MouseButtons != MouseButtons.Left && !rect.Contains(PointToClient(Control.MousePosition)))
{
//Cancel the DragDrop Action
e.Action = DragAction.Cancel;
//Manually fire the MouseUp event
LabelDrag_MouseUp(sender, new MouseEventArgs(Control.MouseButtons, 0, Control.MousePosition.X, Control.MousePosition.Y, 0));
}
}
}
Ben tasarımcı kod çoğu bırakmış, ama ne var bağlıdır emin olabilirsiniz kod Olay işleyicisi bağlantısını yukarı dahil. Örneğimde, LabelDrag ve LabelDrop etiketleri arasında sürükleme/bırakma gerçekleşiyor.
Çözümümün ana parçası QueryContinueDrag olayını kullanıyor. Bu olay, DoDragDrop'un bu denetime çağrılmasının ardından klavye veya fare durumu değiştiğinde tetiklenir. Bunu zaten yapıyor olabilirsiniz, ancak kaynağınız olan denetimin DoDragDrop yöntemini çağırmanız ve formla ilişkili yöntemi değil. Aksi takdirde QueryContinueDrag ateş etmeyecektir! Unutulmaması gereken
Bir şey damla kontrolü fareyi bıraktığınızda QueryContinueDrag aslında bu yüzden biz bunun için izin verdiğinden emin olmak gerekir yangın olmasıdır. Bu, Fare konumunu (genel Control.MousePosition özelliği ile alınan) LabelDrop denetim dikdörtgeninin içinde olduğunu kontrol ederek işlenir. Ayrıca, MousePosition'ı PointToClient ile Denetim Penceresi olarak İstemci Penceresine göre bir noktaya dönüştürdüğünüzden emin olmalısınız.MousePosition bir ekran göreli konumunu döndürür.
Yani fare damla kontrolü üzerinde değil olduğunu kontrol ederek ve o fare düğmesi artık etkili bir LabelDrag kontrolü için bir MouseUp olayı ele geçirdi kadar olduğunu! :) Şimdi, sadece burada yapmak istediğiniz işlemi yapabilirdiniz, ancak zaten MouseUp olay işleyicisinde kullandığınız kodunuz varsa, bu verimli değildir. Bu yüzden, buradan MouseUp olayınızı arayın, gerekli parametreleri geçirin ve MouseUp işleyicisi farkı asla bilmeyecektir. gerçi sadece bir not
, benim örnekte içinde den MouseDown olay işleyicisi DoDragDrop dediğimiz gibi, bu kod aslında doğrudan MouseUp olayı ateşe olsun asla. Bunu yapmak için mümkün olduğunu göstermek için o kodu koydum.
Bu yardımcı olur umarım!
argh, ben de bu problemle karşılaştım. Bana sorarsan çok sinir bozucu! –