2010-05-23 106 views
4

我有一個ListBox和一個ItemTemplate,其中包含一個與鼠標交互的控件。這會干擾ListBox的選擇功能,即單擊控件不會選擇該項目。這是因爲ListBoxItem在OnMouseLeftButtonDown中將鼠標事件的Handled屬性設置爲true。我嘗試以下ListBoxItem子項(WPF)中的鼠標交互

protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) { 
    base.OnMouseLeftButtonDown(e); 
    e.Handled = false; 
} 

但ListBoxItem中「接管」鼠標和防止控制從做自己的互動。然後我有了另一個想法

protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) { 
    base.OnMouseLeftButtonDown(e); 
    ((ListBoxItem)VisualTreeHelper.GetParent(VisualTreeHelper.GetParent(VisualTreeHelper.GetParent(this)))).IsSelected = true; 
} 

其實際工作,但給人的感覺更像一個醜陋的雜牌不是完美的解決方案。有沒有更好的解決方案不依賴於視覺樹的確切內容?

回答

0

我已經找到一種方法就是少了雜牌的:

protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) { 
    base.OnMouseLeftButtonDown(e); 
    Selector.SetIsSelected(this, true); 
} 

對於這個有什麼影響,在列表框控件的ItemTemplate中需要以下XAML屬性:

Selector.IsSelected="{Binding IsSelected, Mode=OneWayToSource, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}" 

它提出了兩個新問題:

  1. 定義我自己的依賴屬性而不是找到附加的o ne目前沒有使用?
  2. 有沒有辦法在標記中實現類似的東西?
0

我相信MouseLeftButtonDown是一個隧道事件:你可以嘗試使用PreviewMouseLeftButtonDown,在那裏做你的處理,然後確保e.Handled = false;正如你已經嘗試過的那樣 - 那應該可以做到!

希望有所幫助。

+0

感謝您的建議,但你有它倒退:MouseLeftButtonDown冒泡事件和PreviewMouseLeftButtonDown是隧道。 :) PreviewMouseLeftButtonDown將如何改善情況? – absence 2010-07-07 11:55:46

+0

預覽事件發生在實際事件之前:所以如果你在那裏做了處理,然後設置e.Handled = false;你的代碼將被執行,但是ListBox仍然會運行它自己的處理代碼,以改變選擇的項目。至少有希望;這就是我的理解! – 2010-07-07 12:21:48

0

下面是一個簡單的解決方案,但不幸的是,處理程序只能附加在代碼中,而不能附加在標記中。
事件處理程序可以通過使用AddHandler方法的handledEventsToo簽名被添加:

myListBox.AddHandler(UIElement.MouseDownEvent, 
     new MouseButtonEventHandler(ListBox_MouseDown), true); 

第三參數以上是handledEventsToo以確保該處理程序將它是否已經被標記爲Handled(被調用無論哪個ListBoxItem確實在列表框)。

查看Marking Routed Events as Handled, and Class Handling的解釋。例如,
參見How to Attach to MouseDown Event on ListBox