Reputation: 88189
Is there a way I can implement Click
on a ListBoxItem
? There is MouseLeftButtonUp
but its not really the same, I can mouse down elsewhere and drag into another ListBoxItem
and it still works, minor problem tho, it maybe weird for users tho
Upvotes: 3
Views: 5534
Reputation: 84647
I deleted this answer because I realized that this is way to much for this simple task, but then I thought I'll post it anyway in case someone wants to know how to subclass ListBoxItem for whatever reason.
To really get a Click event from a ListBoxItem you'll have to do the following. First subclass ListBoxItem and check MouseEnter, MouseLeave, MouseUp, MouseDown to know when to fire it.
public class ClickableListBoxItem : ListBoxItem
{
// Register the routed event
public static readonly RoutedEvent ClickEvent =
EventManager.RegisterRoutedEvent( "Click", RoutingStrategy.Bubble,
typeof(RoutedEventHandler), typeof(ClickableListBoxItem));
// .NET wrapper
public event RoutedEventHandler Click
{
add
{
AddHandler(ClickEvent, value);
}
remove
{
RemoveHandler(ClickEvent, value);
}
}
protected void OnClick()
{
RaiseEvent(new RoutedEventArgs(ClickEvent));
}
private bool m_isClickable = false;
private bool m_click = false;
protected override void OnMouseEnter(System.Windows.Input.MouseEventArgs e)
{
m_isClickable = true;
base.OnMouseEnter(e);
}
protected override void OnMouseLeave(System.Windows.Input.MouseEventArgs e)
{
m_isClickable = false;
base.OnMouseLeave(e);
}
protected override void OnPreviewMouseLeftButtonUp(System.Windows.Input.MouseButtonEventArgs e)
{
if (m_click == true)
{
OnClick();
}
base.OnPreviewMouseLeftButtonUp(e);
}
protected override void OnPreviewMouseLeftButtonDown(System.Windows.Input.MouseButtonEventArgs e)
{
if (m_isClickable == true)
{
m_click = true;
}
base.OnPreviewMouseLeftButtonDown(e);
}
}
To get the ListBox to use ClickableListBoxItem instead of ListBoxItem we must also subclass ListBox and override GetContainerForItemOverride.
public class ClickableListBox : ListBox
{
protected override DependencyObject GetContainerForItemOverride()
{
//Use our own ListBoxItem
return new ClickableListBoxItem();
}
}
Then we can use this ClickableListBox in Xaml and get the Click event like this. This will work no mather what you put in the ItemTemplate, Buttons, TextBoxes, TextBlocks etc.
<local:ClickableListBox x:Name="c_listBox">
<local:ClickableListBox.ItemContainerStyle>
<Style TargetType="{x:Type local:ClickableListBoxItem}">
<EventSetter Event="Click" Handler="ListBoxItem_Click"/>
</Style>
</local:ClickableListBox.ItemContainerStyle>
</local:ClickableListBox>
An easier solution would be to just subclass the Parent container in the ItemTemplate for the ListBoxItem and use the same Mouse routines.
Upvotes: 4
Reputation: 8022
You could make a new ControlTemplate for the ListBoxItem with something clickable as the root-element (like a Button), handle the click-event on that and place the ContentPresenter inside the 'clickable'?
Upvotes: 2