如何在自定义用户控件上创建单击事件?

时间:2013-11-12 12:26:16

标签: c# wpf events user-controls

我已经创建了一个自定义用户控件。我是否可以添加点击事件,以便当有人点击控件区域中的任何位置时,会触发点击事件?

用户控件定义为:

XAML:

<Grid x:Name="LayoutRoot" Background="{StaticResource PhoneChromeBrush}">
    <StackPanel Orientation="Vertical">
        <Image  Source="{Binding TabItemImage}" HorizontalAlignment="Center" Stretch="None" VerticalAlignment="Top" />
        <TextBlock Text="{Binding TabItemText}" FontSize="15" HorizontalAlignment="Center" VerticalAlignment="Bottom" />
    </StackPanel>
</Grid>

C#:

public partial class TabItem : UserControl
{
    public static readonly DependencyProperty ImageProperty = DependencyProperty.Register("TabItemImage", typeof(string), typeof(TabItem), null);
    public static readonly DependencyProperty TextProperty = DependencyProperty.Register("TabItemText", typeof(string), typeof(TabItem), null);

    public string TabItemImage
    {
        get { return (string)GetValue(ImageProperty); }
        set { SetValue(ImageProperty, value); }
    }

    public string TabItemText
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }

    public TabItem()
    {
        InitializeComponent();
        this.DataContext = this;
    }
}

使用简单:

<tabs:TabItem TabItemText="OVERVIEW" TabItemImage="/Resources/Images/overview.png" />

理想情况下,我可以修改用户控件,以便指定点击事件,例如

<tabs:TabItem 
    TabItemText="OVERVIEW" 
    TabItemImage="/Resources/Images/options_64.png" 
    Click="TabItem_Clicked"/> <!-- when someone clicks the control, this fires -->

这可能吗?如果是这样,我需要做什么才能在自定义用户控件上创建点击事件?

3 个答案:

答案 0 :(得分:6)

您需要向TabItem UserControl添加自定义RoutedEvent,以下是添加自定义RoutedEvent的代码:

public static readonly RoutedEvent ClickEvent = EventManager.RegisterRoutedEvent(
"Click", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TabItem));

public event RoutedEventHandler Click
{
    add { AddHandler(ClickEvent, value); }
    remove { RemoveHandler(ClickEvent, value); }
}

void RaiseClickEvent()
{
    RoutedEventArgs newEventArgs = new RoutedEventArgs(TabItem.ClickEvent);
    RaiseEvent(newEventArgs);
}

void OnClick()
{
    RaiseClickEvent();
}

然后在你的UserControl InitializeMethod连接PreviewMouseLeftButtonUp事件来触发你的自定义RoutedEvent:

PreviewMouseLeftButtonUp += (sender, args) => OnClick();

在MSDN上有一个非常好的How-to讨论这个问题,你可能想要阅读它。

答案 1 :(得分:3)

sthotakura,有一个好点,这将是一个很好的方式来做到这一点。但是,如果此UserControl没有多个单击事件,为什么不使用定义自定义UserControl所带来的任何鼠标单击事件。

我不知道你可以将datacontext设置为自己...这很有趣。我要修改我现在创建的自定义对话框.. :)感谢您教我一些东西。


XAML:

<UserControl x:Class="StackTest.TestControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             MouseLeftButtonUp="TestControl_OnMouseLeftButtonUp"
             MouseDoubleClick="TestControl_OnMouseDoubleClick"
             MouseLeftButtonDown="TestControl_OnMouseLeftButtonDown">

  <Grid x:Name="LayoutRoot" Background="{StaticResource PhoneChromeBrush}">
    <StackPanel Orientation="Vertical">
      <Image  Source="{Binding TabItemImage}" HorizontalAlignment="Center" Stretch="None" VerticalAlignment="Top" />
      <TextBlock Text="{Binding TabItemText}" FontSize="15" HorizontalAlignment="Center" VerticalAlignment="Bottom" />
    </StackPanel>
  </Grid>

</UserControl>

CS:

public partial class TestControl : UserControl
{
    public static readonly DependencyProperty ImageProperty = DependencyProperty.Register("TabItemImage" , typeof(string) , typeof(TabItem) , null);
    public static readonly DependencyProperty TextProperty = DependencyProperty.Register("TabItemText" , typeof(string) , typeof(TabItem) , null);

    public string TabItemImage
    {
        get { return (string)GetValue(ImageProperty); }
        set { SetValue(ImageProperty , value); }
    }

    public string TabItemText
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty , value); }
    }

    public TestControl()
    {
        InitializeComponent();
        this.DataContext = this;
    }

    // or

    private void TestControl_OnMouseDoubleClick(object sender, MouseButtonEventArgs e)
    {
        // Add logic...
    }

    // or

    private void TestControl_OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        // Add logic...
    }

    // or

    private void TestControl_OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        // Add logic...
    }
}

答案 2 :(得分:0)

所以,我可以回到Sthotakura的伟大帖子。

这是您的所有命名空间需求的帖子

 using System;
    using System.Windows;
    using System.Windows.Controls;

    namespace YourNameSpace
    {
        partial class OPButton
        {
            /// <summary>
            /// Create a custom routed event by first registering a RoutedEventID
            /// This event uses the bubbling routing strategy
            /// see the web page https://msdn.microsoft.com/EN-US/library/vstudio/ms598898(v=vs.90).aspx 
            /// </summary>
            public static readonly RoutedEvent ClickEvent = EventManager.RegisterRoutedEvent("Click", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(OPButton));
            /// <summary>
            /// Provide CLR accessors for the event Click OPButton 
            /// Adds a routed event handler for a specified routed event Click, adding the handler to the handler collection on the current element.
            /// </summary>
            public event RoutedEventHandler Click
            {
                add {AddHandler(ClickEvent, value); }
                remove { RemoveHandler(ClickEvent, value); }
            }
            /// <summary>
            /// This method raises the Click event 
            /// </summary>
            private void RaiseClickEvent()
            {
                RoutedEventArgs newEventArgs = new RoutedEventArgs(OPButton.ClickEvent);
                RaiseEvent(newEventArgs);
            }
            /// <summary>
            /// For isPressed purposes we raise the event when the OPButton is clicked
            /// </summary>
            private void OnClick()
            {
                RaiseClickEvent();
            }
        }
    }

添加以下参考文献:

Windows;
PresentationCore;
WindowsBase;