为自定义控件中的多个按钮添加单独的单击事件

时间:2017-07-03 16:55:40

标签: c# wpf xaml

所有

我越是寻找这个问题的解决方案,我就越困惑。花了12-16个小时观看YouTube,阅读StackOverflow和一般的护目镜后,我想我会请求额外的帮助。

我想创建一个自定义控件,以便我可以将各种应用程序编写到我的视频切换器远程。

我已经使用依赖属性创建了我的控件,并且该部分运行良好。

关于SO的答案似乎让我很接近,但我仍然无法让我的应用程序运行。   How to wire up a click event for a custom usercontrol button? Should I use CustomControl?

我只想点击控件中的btnIn1并让它返回“1”,btnIn2返回“2”,依此类推。

我还阅读了有关委托,ICommand,TemplateParts和MVVM模式的内容,这些模式似乎都非常复杂,可以单击组中的按钮。也许这不是一个简单的方法。

这是我到目前为止所拥有的。我将所有内容简化为2x2矩阵切换器(而不是我正在使用的4x4)

感谢您的帮助。 规范

Generic.xaml

<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:VideoSwitcher"
xmlns:enk="clr-namespace:VideoSwitcher.Controls">

<Style TargetType="{x:Type enk:Matrix44}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type enk:Matrix44}">
                <Grid x:Name="grdBase" HorizontalAlignment="Stretch">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="25*"/>
                        <ColumnDefinition Width="25*"/>
                        <ColumnDefinition Width="25*"/>
                        <ColumnDefinition Width="25*"/>
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="40*"/>
                        <RowDefinition Height="100*"/>
                        <RowDefinition Height="40*"/>
                        <RowDefinition Height="100*"/>
                        <RowDefinition Height="*"/>
                    </Grid.RowDefinitions>
                    <Label x:Name="lblInputHeader" Content="Input"
                           Grid.Column="0"
                           Grid.Row="0"
                           Grid.ColumnSpan="4"
                           Visibility="{TemplateBinding HeaderVisible}"
                           FontFamily="{TemplateBinding HeaderFont}"
                           FontSize="{TemplateBinding HeaderFontSize}"/>
                    <StackPanel Orientation="Horizontal"
                                Grid.Column="0"
                                Grid.Row="1"
                                Grid.ColumnSpan="4">
                        <Button x:Name="btnIn1"
                                Margin="{TemplateBinding ButtonMargin}"
                                Height="{TemplateBinding ButtonHeight}"
                                Width="{TemplateBinding ButtonWidth}"
                                Content="{TemplateBinding Input1Label}"
                                Click="btnIn1Click"/>
                        <Button x:Name="btnIn2"
                                Margin="{TemplateBinding ButtonMargin}"
                                Height="{TemplateBinding ButtonHeight}"
                                Width="{TemplateBinding ButtonWidth}"
                                Content="{TemplateBinding Input2Label}"
                                Click="btnIn2Click"/>
                    </StackPanel>
                    <Label x:Name="lblOutputHeader" Content="Output"
                           Grid.Column="0"
                           Grid.Row="2"
                           Grid.ColumnSpan="4"
                           Visibility="{TemplateBinding HeaderVisible}"
                           FontFamily="{TemplateBinding HeaderFont}"
                           FontSize="{TemplateBinding HeaderFontSize}"/>
                    <StackPanel Orientation="Horizontal"
                                Grid.Column="0"
                                Grid.Row="3"
                                Grid.ColumnSpan="4">
                        <Button x:Name="btnOut1"
                                Margin="{TemplateBinding ButtonMargin}"
                                Height="{TemplateBinding ButtonHeight}"
                                Width="{TemplateBinding ButtonWidth}"
                                Content="{TemplateBinding Output1Label}"
                                Click="btnOut1Click"/>
                        <Button x:Name="btnOut2"
                                Margin="{TemplateBinding ButtonMargin}"
                                Height="{TemplateBinding ButtonHeight}"
                                Width="{TemplateBinding ButtonWidth}"
                                Content="{TemplateBinding Output2Label}"
                                Click="btnOut2Click"/>
                    </StackPanel>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
</ResourceDictionary>

自定义控件(Matrix44.cs)

using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.ComponentModel;

namespace VideoSwitcher.Controls
{

public class Matrix44 : Control
{

    #region Events - Go here if I can ever find out how to use them


    #endregion

    //This does not work --------
    public event RoutedEventHandler Click;

    void btnIn1Click(object sender, RoutedEventArgs e)
    {
        if (this.Click != null)
        {
            this.Click(this, e);
        }
    }

    void btnIn2Click(object sender, RoutedEventArgs e)
    {
        if (this.Click != null)
        {
            this.Click(this, e);
        }
    }

    void btnOut1Click(object sender, RoutedEventArgs e)
    {
        if (this.Click != null)
        {
            this.Click(this, e);
        }
    }

    void btnOut2Click(object sender, RoutedEventArgs e)
    {
        if (this.Click != null)
        {
            this.Click(this, e);
        }
    }

    #region Properties - Exposed to the user in the Properties panel, XAML or code-behind

    #region Switcher Appearance Properies (Height, Width, Margin)

    [Category("Switcher Appearance Properties")]
    public double ButtonHeight
    {
        get { return (double)GetValue(ButtonHeightProperty); }
        set { SetValue(ButtonHeightProperty, value); }
    }

    public static readonly DependencyProperty ButtonHeightProperty =
        DependencyProperty.Register(nameof(ButtonHeight), typeof(double), typeof(Matrix44), new PropertyMetadata(50.0));

    [Category("Switcher Appearance Properties")]
    public double ButtonWidth
    {
        get { return (double)GetValue(ButtonWidthProperty); }
        set { SetValue(ButtonWidthProperty, value); }
    }

    public static readonly DependencyProperty ButtonWidthProperty =
        DependencyProperty.Register(nameof(ButtonWidth), typeof(double), typeof(Matrix44), new PropertyMetadata(50.0));

    [Category("Switcher Appearance Properties")]
    public Thickness ButtonMargin
    {
        get { return (Thickness)GetValue(ButtonMarginProperty); }
        set { SetValue(ButtonMarginProperty, value); }
    }

    public static readonly DependencyProperty ButtonMarginProperty =
        DependencyProperty.Register("ButtonMargin", typeof(Thickness), typeof(Matrix44));



    #endregion

    #region Labels

    [Category("Switcher Label Properties")]
    public string Input1Label
    {
        get { return (string)GetValue(Input1LabelProperty); }
        set { SetValue(Input1LabelProperty, value); }
    }


    public static readonly DependencyProperty Input1LabelProperty =
        DependencyProperty.Register(nameof(Input1Label), typeof(string), typeof(Matrix44), new PropertyMetadata("Input 1"));

    [Category("Switcher Label Properties")]
    public string Input2Label
    {
        get { return (string)GetValue(Input2LabelProperty); }
        set { SetValue(Input2LabelProperty, value); }
    }

    public static readonly DependencyProperty Input2LabelProperty =
        DependencyProperty.Register(nameof(Input2Label), typeof(string), typeof(Matrix44), new PropertyMetadata("Input 2"));


    [Category("Switcher Label Properties")]
    public string Output1Label
    {
        get { return (string)GetValue(Output1LabelProperty); }
        set { SetValue(Output1LabelProperty, value); }
    }

    public static readonly DependencyProperty Output1LabelProperty =
        DependencyProperty.Register(nameof(Output1Label), typeof(string), typeof(Matrix44), new PropertyMetadata("Output 1"));

    [Category("Switcher Label Properties")]
    public string Output2Label
    {
        get { return (string)GetValue(Output2LabelProperty); }
        set { SetValue(Output2LabelProperty, value); }
    }

    public static readonly DependencyProperty Output2LabelProperty =
        DependencyProperty.Register(nameof(Output2Label), typeof(string), typeof(Matrix44), new PropertyMetadata("Output 2"));

    #endregion

    #region Header Properties

    [Category("Switcher Header Properties")]
    public Visibility HeaderVisible
    {
        get { return (Visibility)GetValue(HeaderVisibleProperty); }
        set { SetValue(HeaderVisibleProperty, value); }
    }

    public static readonly DependencyProperty HeaderVisibleProperty =
        DependencyProperty.Register("HeaderVisible", typeof(Visibility), typeof(Matrix44));

    [Category("Switcher Header Properties")]
    public FontFamily HeaderFont
    {
        get { return (FontFamily)GetValue(HeaderFontProperty); }
        set { SetValue(HeaderFontProperty, value); }
    }

    public static readonly DependencyProperty HeaderFontProperty =
        DependencyProperty.Register("HeaderFont", typeof(FontFamily), typeof(Matrix44));

    [Category("Switcher Header Properties")]
    public double HeaderFontSize
    {
        get { return (double)GetValue(HeaderFontSizeProperty); }
        set { SetValue(HeaderFontSizeProperty, value); }
    }

    public static readonly DependencyProperty HeaderFontSizeProperty =
        DependencyProperty.Register("HeaderFontSize", typeof(double), typeof(Matrix44));


    #endregion

    #region Channel Properties
    [Category("Switcher Channel Properties")]

    //Channel Property - use to extend switcher tool capabilties; e.g. add new bank of ins/outs and remap input 1 to input 5 on 2nd bank

    public int Input1Channel
    {
        get { return (int)GetValue(Input1ChannelProperty); }
        set { SetValue(Input1ChannelProperty, value); }
    }

    public static readonly DependencyProperty Input1ChannelProperty =
        DependencyProperty.Register("Input1Channel", typeof(int), typeof(Matrix44), new PropertyMetadata(1));

    [Category("Switcher Channel Properties")]
    public bool Input1Enabled
    {
        get { return (bool)GetValue(Input1EnabledProperty); }
        set { SetValue(Input1EnabledProperty, value); }
    }

    public static readonly DependencyProperty Input1EnabledProperty =
        DependencyProperty.Register("Input1Enabled", typeof(bool), typeof(Matrix44), new PropertyMetadata(false));


    [Category("Switcher Channel Properties")]
    public int Input2Channel
    {
        get { return (int)GetValue(Input2ChannelProperty); }
        set { SetValue(Input2ChannelProperty, value); }
    }

    public static readonly DependencyProperty Input2ChannelProperty =
        DependencyProperty.Register("Input2Channel", typeof(int), typeof(Matrix44), new PropertyMetadata(2));

    [Category("Switcher Channel Properties")]
    public bool Input2Enabled
    {
        get { return (bool)GetValue(Input1EnabledProperty); }
        set { SetValue(Input1EnabledProperty, value); }
    }

    [Category("Switcher Channel Properties")]
    public int Output1Channel
    {
        get { return (int)GetValue(Output1ChannelProperty); }
        set { SetValue(Output1ChannelProperty, value); }
    }

    //Output channels

    public static readonly DependencyProperty Output1ChannelProperty =
        DependencyProperty.Register("Output1Channel", typeof(int), typeof(Matrix44), new PropertyMetadata(1));

    [Category("Switcher Channel Properties")]
    public int Output2Channel
    {
        get { return (int)GetValue(Output2ChannelProperty); }
        set { SetValue(Output2ChannelProperty, value); }
    }

    public static readonly DependencyProperty Output2ChannelProperty =
        DependencyProperty.Register("Output2Channel", typeof(int), typeof(Matrix44), new PropertyMetadata(2));

    #endregion

    #endregion

    public Matrix44()
    {
        DefaultStyleKey = typeof(Matrix44);
    }

}

}

MainWindow.XAML

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:VideoSwitcher"
    xmlns:Controls="clr-namespace:VideoSwitcher.Controls" x:Class="VideoSwitcher.MainWindow"
    mc:Ignorable="d"
    Title="MainWindow" Height="300" Width="200">
<Grid Margin="0,1,0,0">
    <Controls:Matrix44 x:Name="swtMatrix"
                       HorizontalAlignment="Left"
                       Margin="10,10,0,0"
                       VerticalAlignment="Top"
                       ButtonHeight="65"
                       ButtonMargin="4"
                       ButtonWidth="65"/>
    <Button x:Name="btnTake"
            Content="Take"
            HorizontalAlignment="Left"
            Margin="10,213,0,0"
            VerticalAlignment="Top"
            Width="146"
            Height="45" Click="btnTake_Click"/>
</Grid>

MainWindow.xaml.cs

    using System.Windows;

    namespace VideoSwitcher
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public int VideoInputChannel { get; set; }
    public int VideoOutputChannel { get; set; }

    public MainWindow()
    {
        InitializeComponent();
        AddLabelsToMatrix();
    }

    public void AddLabelsToMatrix()
    {
        swtMatrix.Input1Label = "DVR1";
        swtMatrix.Input2Label = "DVR2";
        swtMatrix.Output1Label = "Videowall";
        swtMatrix.Output2Label = "US Right";
    }

    private void btnTake_Click(object sender, RoutedEventArgs e)
    {
        MessageBox.Show("Input channel: " + VideoInputChannel + " routed to Output: " + VideoOutputChannel);
    }


    /* switcher button psuedo-code

        btnIn1_Click (object sender, RoutedEventArgs e)
        {
            //get input channel of matrix switcher
            VideoInputChannel = swtMatrix.btnIn1.Channel;
        }

        btnIn2_Click (object sender, RoutedEventArgs e)
        {
            //get input channel of matrix switcher
            VideoInputChannel = swtMatrix.btnIn2.Channel;
        }

         btnOut1_Click (object sender, RoutedEventArgs e)
        {
            //get output channel of matrix switcher
            VideoInputChannel = swtMatrix.btnIn1.Channel;
        }

        btnOut2_Click (object sender, RoutedEventArgs e)
        {
            //get output channel of matrix switcher
            VideoInputChannel = swtMatrix.btnIn2.Channel;
        }

    */

}
}

1 个答案:

答案 0 :(得分:1)

您可以覆盖OnApplyTemplate()方法以获取对每个Button的引用,然后挂钩事件处理程序:

public class Matrix44 : Control
{
    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        Button btnOut1 = this.Template.FindName("btnOut1", this) as Button;
        if (btnOut1 != null)
            btnOut1.Click += btnIn1Click;

        //...and so on for each Button

    }
}

然后,您可以针对每个Button提出特定事件,也可以定义可用于识别在事件处理程序中单击的EventArgs的自定义Button

C# event with custom arguments