2013-07-18 76 views
4

如何侦听我的WPF应用程序中的所有按钮点击。也许包括一些复选框左右,但理想情况下,我不想有额外的事件处理程序。如何为所有按钮注册单个事件侦听器

我想收集最初的统计数据,以了解人们如何使用我们的应用程序。我想确保我不会干扰任何其他事件处理功能。

在应用新的窗口被打开,并用自己的按钮,关闭,所以我不能做静态。

另外,是否有任何常见的方式来收集来自WPF应用程序的使用情况统计信息。

回答

5

我怎么能听我的WPF应用程序的所有按钮的点击?

您可以通过使用EventManager挂钩事件为一个类型的所有对象:

EventManager.RegisterClassHandler(typeof(Button), Button.ClickEvent, new RoutedEventHandler(Button_Click)); 

private void Button_Click(object sender, RoutedEventArgs e) 
{ 

} 

在应用新的窗口被打开,并用自己的 按钮关闭,所以我不能做静态。

如果您在WPF中创建这些Windows,您可以挂入Window events(如Closed,Sizechanged和Got/LostFocus())。如果这些Windows是不是WPF/WinForm的基础,你可以使用一个ShellHook

+0

这对我来说很好,加上它对我的代码分散的程度最小。它也处理其他类型的按钮,这是很好的副作用。 谢谢 – Marek

0

你应该使用按钮单击事件处理命令。每个窗口都将有实例的CommandBinding在地方执行的处理方法,您可以发送关于当前按钮的使用信息为若干类,将持有的结果对你的一些静态单一实例。命令和CommandBinding不是必需的,但如果您使用的是MVVM模式,请尝试使用它们。而不是静态单例使用自定义服务。

1

您可以使用样式:

的.xaml

<Window x:Class="WpfApp.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <StackPanel> 
     <StackPanel.Resources> 
      <Style TargetType="Button"> 
       <EventSetter Event="Click" Handler="Button_Click" /> 
      </Style> 
     </StackPanel.Resources> 
     <Button x:Name="b1" Click="Button1_Click" Content="1" /> 
     <Button x:Name="b2" Click="Button2_Click" Content="2" /> 
     <Button Content="other" /> 
    </StackPanel> 
</Window> 

xaml.cs

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     Console.WriteLine("some button"); 
    } 

    private void Button1_Click(object sender, RoutedEventArgs e) 
    { 
     Console.WriteLine("button1"); 
    } 

    private void Button2_Click(object sender, RoutedEventArgs e) 
    { 
     Console.WriteLine("button2"); 
    } 
} 

风格上在放入app.xaml时应用范围很广。

0

您可以使用每个窗口的Window_Loaded事件,遍历您的VisualTree,找到所有按钮和注册您的附加通用处理程序:

private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 
     //Capture all buttons of this form. 
     findButtons(this); 
    } 

    public void findButtons(FrameworkElement parent) 
    { 
     int childCount = VisualTreeHelper.GetChildrenCount(parent); 

     for(int i=0; i<childCount; i++){ 
      var child = VisualTreeHelper.GetChild(parent,i); 

      if (child is Button){ 
        ((Button)child).Click += All_Button_Click; 
      } 

      var frameworkElement = child as FrameworkElement; 
      findButtons(frameworkElement); 
     } 
    } 

    private void All_Button_Click(object sender, RoutedEventArgs e) 
    { 
     MessageBox.Show("Generic Handler"); 
    } 

你所有的按钮可以保持原样,并拥有自己的定制事件处理程序 你也可以在你的主窗口上使用处理程序来覆盖所有窗体等。

-1

嗨,我有一个想法做到这一点我不知道它是否完美与否。

public partial class App : Application 
{ 
    //Create list of string in your App class this will contain the names of button in order they are clicked 
    public static List<string> ButtonNames = new List<string>(); 
} 

创建一个继承Button类自定义按钮类,并在您的应用程序和超载按钮类的OnClick方法使用的CustomButton类,而不是巴顿在其订阅的事件。这将增加按钮名称上面创建ButtonNames列表

public class MyButton : Button 
{ 
    private bool isClickEventAttached = false; 
    protected override void OnClick() 
    { 
     if (!isClickEventAttached) 
     { 
      this.Click += MyButton_Click; 
      isClickEventAttached = true; 
     } 
     //dont forget to do this base.Click() otherwise your 
     //button click event that you will subscribe in your application will not fire 
     base.OnClick(); 
    } 

    private void MyButton_Click(object sender, RoutedEventArgs e) 
    { 
     var button=sender as Button; 
     if (button != null) 
      App.ButtonNames.Add((button.Name)); 
    } 
} 

XAML

<Window x:Class="WpfApplication1.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:commonControls="clr-namespace:WpfApplication1" 
    Title="MainWindow" Height="350" Width="525"> 
<StackPanel> 
    <commonControls:MyButton x:Name="mybutton1" Click="MyButton_Click_1"/> 
    <commonControls:MyButton x:Name="mybutton2" Click="MyButton_Click_2"/> 
</StackPanel> 

的.cs

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    private void MyButton_Click_1(object sender, RoutedEventArgs e) 
    { 

    } 

    private void MyButton_Click_2(object sender, RoutedEventArgs e) 
    { 

    } 
} 

我希望你能得到一个想法,我是什么试图说

相关问题