Как я могу иметь событие Click на ListBoxItem?
Есть ли способ, которым я могу реализовать Click
на ListBoxItem
? Есть MouseLeftButtonUp
но это не совсем то же самое, я могу навести курсор мыши в другом месте и перетащить в другое ListBoxItem
и это все еще работает, небольшая проблема, хотя, это может быть странно для пользователей, хотя
2 ответа
Вы могли бы создать новый ControlTemplate для ListBoxItem с чем-то, что можно щелкнуть в качестве корневого элемента (например, Button), обработать событие click для этого и поместить ContentPresenter внутри "clickable"?
Я удалил этот ответ, потому что понял, что для этой простой задачи это слишком много, но потом я решил опубликовать его в любом случае, если кто-то захочет узнать, как создать подкласс ListBoxItem по какой-либо причине.
Чтобы действительно получить событие Click от ListBoxItem, вам нужно сделать следующее. Первый подкласс ListBoxItem и проверьте MouseEnter, MouseLeave, MouseUp, MouseDown, чтобы знать, когда его запускать.
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);
}
}
Чтобы получить ListBox для использования ClickableListBoxItem вместо ListBoxItem, мы также должны создать подкласс ListBox и переопределить GetContainerForItemOverride.
public class ClickableListBox : ListBox
{
protected override DependencyObject GetContainerForItemOverride()
{
//Use our own ListBoxItem
return new ClickableListBoxItem();
}
}
Затем мы можем использовать этот ClickableListBox в Xaml и получить событие Click следующим образом. Это не будет работать независимо от того, что вы положили в ItemTemplate, кнопки, TextBoxes, TextBlocks и т. Д.
<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>
Более простым решением было бы просто создать подкласс родительского контейнера в ItemTemplate для ListBoxItem и использовать те же процедуры Mouse.