所有
我越是寻找这个问题的解决方案,我就越困惑。花了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)
感谢您的帮助。 规范
<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>
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);
}
}
}
<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>
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;
}
*/
}
}
答案 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
: