【问题标题】:How can I create a click event on a custom user control?如何在自定义用户控件上创建单击事件?
【发布时间】:2013-11-24 14:24:23
【问题描述】:

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

用户控件定义为:

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

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

【问题讨论】:

标签: c# wpf events user-controls


【解决方案1】:

您需要在 TabItem 用户控件中添加自定义 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 讨论这个,你可能想读一下。

【讨论】:

    【解决方案2】:

    This answer by Suresh 有一个很好的观点,这将是一个很好的方法。但是,如果此 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...
        }
    }
    

    【讨论】:

      【解决方案3】:

      SureshThis answer 需要以下命名空间声明:

      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;
      

      【讨论】:

      猜你喜欢
      • 2014-10-31
      • 2016-08-11
      • 1970-01-01
      • 1970-01-01
      • 2015-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多