2010-09-22 16 views
6

ListBox'um var ve seçim modunun genişletilmesini istiyorum. Ayrıca sürükle ve bırak işlevselliğini uygulamak istiyorum. Sorun şu ki, fare seçilen bir öğeye tıklanırsa, bunu yapmak için hemen mouse-up-olayı beklemek yerine tek seçim olarak seçilecektir.WPF, bir ListBox'a sahip olan bir ListBox'tan sürükleyip bırakın SelectionMode = Genişletilmiş

Bu davranış nedeniyle, birden çok öğeyi sürüklemeye hemen hemen olanaksızdır çünkü her zaman sürüklemeye başlamak için seçimi tıklatır, seçim, farenin altındaki öğeye değişir ve bu öğeyle birlikte sürüklemeyi başlatır. .

Bu sorun için iyi bir çözüm var mı, yoksa resmi bir çözüm var mı?

+0

Daha sonra farklı bir yanıtı tekrar kabul edersiniz. Öyleyse diğer cevabı daha iyi seviyorsan, kabul et. – Rohit

+0

Aşağıdaki bağlantıyı kullanmanızı öneririm. Harika çalışıyor. http://stackoverflow.com/a/23151248 – Youngjae

cevap

8

İşte yaptığım şey. DragDrop kodunuzda, PreviewMouseLeftButtonDown'a abone olun. Zaten üzerine tıklamak istediğiniz öğe seçilirse, e.Handled değerini true olarak ayarlayın.

Aşağıdaki örnekte, liste kutusu öğesinin bir bölümünü sürükleme tutamacı olarak (çarpmalarla) tanımlayacağım, böylece öğe ile sürükle yüzeyi arasında ayrım yapabilirim. Sadece liste kutusu öğesi veri şablonunu ve sürükleme tutamaç öğesinin adını kabul etmek için sürükle ve bırak davranışını almam gerekiyordu. Devam eden benim işten

PreviewMouseLeftButtonDown:

private void ItemsControl_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
{ 
    dragStartPoint = e.GetPosition(null); 

    ItemsControl itemsControl = this.AssociatedObject as ItemsControl; 
    if (itemsControl != null) 
    { 
     this.sourceItemContainer = itemsControl.ContainerFromElement((Visual)e.OriginalSource) as FrameworkElement; 
    } 

    // If this is an multiple or extended selection list box, and on a drag grip, then ensure the item being hit is selected 
    // This prevents the ItemsControl from using this MouseDown to change selection, except over a selected item's drag grip.    
    if ((this.IsMultipleSelectionListBox() == true) && (this.IsOriginalSourceDragGrip(e) != false) && (this.IsSourceListBoxItemSelected() == true)) 
    { 
     e.Handled = true; 
    } 
} 
+0

+1 Evet, sonunda benzer şekilde çözdüm. Cevap için teşekkürler. Ancak ben zaten MrDosu'nun cevabını kabul ettim. Ama aynı sorunu çözmek isteyen diğer kişilere de yolunuzu öneririm. – HCL

2

i düşünebilirsiniz en kolay çözüm, özel ListBoxItems hizmet etmek değil Aşağı şöyle MouseUp üzerinde seçmek için ListBoxItem değiştirip ContainerGenerator değiştirmek olacaktır:

public class CustomListBoxItem : ListBoxItem 
{ 
    protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) 
    { 
     //do nothing 
    } 

    protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e) 
    { 
     base.OnMouseLeftButtonDown(e); 
    } 
} 

Bazı MouseLeave/LeftButtonDown mantığını gerekebilir Fare düğmesini basılı tutarken Listede hareket ederken farklı öğelerin seçilmesini önlemek istiyorsanız.

+0

+1 Güzel çözüm. Ancak ben bir litte kaygılıyım çünkü bir başka bir olayı bir çağrı-yönteminin içinden çağırmak FCL'nin gelecekteki sürümlerinde sorunlara yol açabilir mi bilmiyorum. – HCL

+0

EventArgs'ın farklı olması gerektiğinde (düğme durumu gibi) yapılması gereken bazı işler olabilir, ancak olayın işleyicisini görmeye çalıştığınızda yalnızca bir kırılma değişikliği senaryosunu düşünemedim. – MrDosu

+0

Ne yazık ki, bu çok basit, çünkü bazı durumlarda fare aşağı seçim etkinliği vardır. Doğru davranış, seçili olmayan bir öğenin seçilmesinin (veya bir seçimin genişletilmesinin) fareyle ilgili olarak gerçekleşmesidir (önceden seçilmişse herhangi bir değişiklik olmaz), önceden seçilmiş olan öğelerin seçiminin kaldırılması yalnızca farenin üstünde gerçekleşir ve yalnızca dikkate değer bir imleç yoksa hareket oluştu. – CuriousKea

0

Kullanım PreviewMouseLeftButtonDown sürükleme işlemi için seçilen öğeler eklemek için.

İlgili konular