简体   繁体   中英

How can I create a click event on a custom user control?

I've created a custom user control. Is it possible for me to add a click event so that when someone clicks anywhere in the area of the control, a click event is fired?

The user control is defined as:

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;
    }
}

With the usage simply:

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

Ideally I'd be able to modify the user control so that I could specify the click event, eg

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

Is this possible? If so, what do I need to do to create a click event on a custom user control?

You need to add custom RoutedEvent to your TabItem UserControl, Below is code to add a Custom 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();
}

And then in your UserControl InitializeMethod wire up PreviewMouseLeftButtonUp event to fire your Custom RoutedEvent:

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

There is a pretty good How-to on MSDN discussing this, you might want to read that.

sthotakura, Has a good point and that would be a great way to do it. However, If you don't have more than one click event for this UserControl, Why dont you just use the any of the number of mouseclick events that come with defining a custom UserControl.

I didn't know you could set the datacontext to its self... That is interesting. I am going modify a custom Dialog that i created now.. :) Thanks for teaching me something.


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...
    }
}

So, I can aswer at the great Post of Sthotakura.

this is your post with the all namespace needs

 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();
            }
        }
    }

Add the following References:

Windows;
PresentationCore;
WindowsBase;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM