2013-07-18 45 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) 
    { 

    } 
} 

我希望你能得到一個想法,我是什麼試圖說

相關問題