如何在ListBoxItem上有Click事件?

时间:2010-11-11 07:27:52

标签: wpf listboxitem

我可以在Click上实施ListBoxItem吗?有MouseLeftButtonUp,但它不是一样的,我可以在其他地方鼠标拖动到另一个ListBoxItem它仍然有效,小问题,这对用户来说可能很奇怪

2 个答案:

答案 0 :(得分:3)

我删除了这个答案,因为我意识到这对于这个简单的任务很有用,但后来我想我会发布它,以防万一有人想要知道如何以任何理由继承ListBoxItem。

要真正从ListBoxItem获取Click事件,您必须执行以下操作。第一个子类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(); 
    }
}

然后我们可以在Xaml中使用这个ClickableListBox并获得像这样的Click事件。这不会影响你放在ItemTemplate,Buttons,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>

更简单的解决方案是在ListBoxItem的ItemTemplate中为Parent容器创建子类,并使用相同的Mouse例程。

答案 1 :(得分:2)

您可以为ListBoxItem创建一个新的ControlTemplate,并将可点击的内容作为根元素(如Button),处理点击事件并将ContentPresenter置于'clickable'中?