【发布时间】:2017-07-03 16:55:39
【问题描述】:
全部:
我越是寻找这个问题的解决方案,我就越感到困惑。在花了 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;
}
*/
}
}
【问题讨论】:
-
你能说清楚你想要什么吗,Norm?您唯一的要求是单击按钮返回一个值,但单击处理程序返回 void。你到底想用“1”和“2”做什么,因为我不知道你的问题。
-
Matrix44.cs 中按下的按钮(btnIn1,2,3,.... 或 btnOut1,2,3...)应该发送其对应的数字(1,2,3... ) 返回到 MainWindow.xaml.cs,它将存储在 VideoInputChannel 或 VideoOutputChannel 属性中。谢谢。
-
我认为您不应该在按钮单击处理程序中调用 Click()。似乎这只是一个无限循环。与其调用 Click,不如做一些有用的事情,比如设置 VideoInputChannel 和 VideoOutputChannel 变量?