Как я могу иметь событие 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.

Другие вопросы по тегам