How can I create a click event on a custom user co

2019-06-17 14:24发布

问题:

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, e.g.

<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?

回答1:

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


回答2:

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.



回答3:

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;