C# 如何在ControlTemplate中声明事件处理程序?
我有以下C# 如何在ControlTemplate中声明事件处理程序?,c#,wpf,C#,Wpf,我有以下控制模板: <ControlTemplate> <Grid VerticalAlignment="Stretch" HorizontalAlignment="Left" Width="400"> <Grid.ColumnDefinitions> <ColumnDefinition Width="18" /> <ColumnDefinition Width="20*
控制模板
:
<ControlTemplate>
<Grid VerticalAlignment="Stretch" HorizontalAlignment="Left" Width="400">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="18" />
<ColumnDefinition Width="20*" />
<ColumnDefinition Width="20*" />
<ColumnDefinition Width="20*" />
<ColumnDefinition Width="45" />
</Grid.ColumnDefinitions>
<TextBox Grid.Column="1" Template="{StaticResource watermark}" HorizontalAlignment="Stretch" Margin="4,0,0,4" Tag="Number" />
<TextBox Grid.Column="2" Template="{StaticResource watermark}" HorizontalAlignment="Stretch" Margin="4,0,0,4" Tag="Login" />
<TextBox Grid.Column="3" Template="{StaticResource watermark}" HorizontalAlignment="Stretch" Margin="4,0,0,4" Tag="Password" />
<Button Grid.Column="4" HorizontalAlignment="Stretch" Content="Add" Margin="4,0,0,4" Click="AddUser_Click"/>
</Grid>
</ControlTemplate>
如何写入AddUser\u单击以访问文本框Text
属性
upd:我只是想说清楚。我知道如何连接单击此处的事件处理程序。问题是如何读取其中文本框的内容,因为我无法给它们命名,因为它们位于模板中 你能做的就是给按钮起个名字“PART_Button”。然后重写控件中的OnApplyTemplate方法。在代码中,您可以
var btn = this.Template.FindName("PART_Button", this) as Button;
btn.Click += ...
在当前文件的指令所指向的类中搜索事件处理程序,这允许您内联添加事件处理程序,而无需费心重写该类,并通过添加处理程序来重写,而不管您声明ControlTemplate的位置如何
MainWindow.xaml:
<Window x:Class="WpfApplication1.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">
<Button Content="asdf">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Button Content="{TemplateBinding Content}" Click="Button_Click"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Button.Style>
</Button>
</Window>
MainWindow.xaml.cs:
using System.Windows;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Button clicked!");
}
}
}
使用System.Windows;
命名空间WpfApplication1
{
///
///MainWindow.xaml的交互逻辑
///
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
}
私有无效按钮\u单击(对象发送者,路由目标e)
{
MessageBox.Show(“单击按钮!”);
}
}
}
如果您有权访问templatedparent(选择EdItem、FindVisualParent等),则可以在文本框中应用名称。ControlTemplate用于ComboBoxItem的示例
private void AddUser_Click(object sender, RoutedEventArgs e)
{
ComboBoxItem comboBoxItem = GetVisualParent<ComboBoxItem>(button);
TextBox textBox = comboBoxItem.Template.FindName("numberTextBox", comboBoxItem) as TextBox;
//...
}
private void AddUser\u单击(对象发送者,路由目标)
{
ComboBoxItem ComboBoxItem=GetVisualParent(按钮);
TextBox TextBox=comboBoxItem.Template.FindName(“numberTextBox”,comboBoxItem)作为TextBox;
//...
}
获取ControlTemplate中文本框的另一种方法是使用可视化树。像这样的
private void AddUser_Click(object sender, RoutedEventArgs e)
{
Button button = sender as Button;
Grid parentGrid = GetVisualParent<Grid>(button);
List<TextBox> textBoxes = GetVisualChildCollection<TextBox>(parentGrid);
foreach (TextBox textBox in textBoxes)
{
if (textBox.Tag == "Number")
{
// Do something..
}
else if (textBox.Tag == "Login")
{
// Do something..
}
else if (textBox.Tag == "Password")
{
// Do something..
}
}
}
private void AddUser\u单击(对象发送者,路由目标)
{
按钮按钮=发送器为按钮;
Grid parentGrid=GetVisualParent(按钮);
列表文本框=GetVisualChildCollection(父网格);
foreach(文本框中的文本框)
{
如果(textBox.Tag==“数字”)
{
//做点什么。。
}
else if(textBox.Tag==“登录”)
{
//做点什么。。
}
else if(textBox.Tag==“密码”)
{
//做点什么。。
}
}
}
以及GetVisualParent和GetVisualChildCollection的实现
public static T GetVisualParent<T>(object childObject) where T : Visual
{
DependencyObject child = childObject as DependencyObject;
// iteratively traverse the visual tree
while ((child != null) && !(child is T))
{
child = VisualTreeHelper.GetParent(child);
}
return child as T;
}
public static List<T> GetVisualChildCollection<T>(object parent) where T : Visual
{
List<T> visualCollection = new List<T>();
GetVisualChildCollection(parent as DependencyObject, visualCollection);
return visualCollection;
}
private static void GetVisualChildCollection<T>(DependencyObject parent, List<T> visualCollection) where T : Visual
{
int count = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < count; i++)
{
DependencyObject child = VisualTreeHelper.GetChild(parent, i);
if (child is T)
{
visualCollection.Add(child as T);
}
else if (child != null)
{
GetVisualChildCollection(child, visualCollection);
}
}
}
publicstatict GetVisualParent(objectchildobject),其中T:Visual
{
DependencyObject子对象=作为DependencyObject的子对象;
//迭代遍历可视化树
while((child!=null)&&&!(child是T))
{
child=visualtreeheloper.GetParent(child);
}
返回子对象作为T;
}
公共静态列表GetVisualChildCollection(对象父对象),其中T:Visual
{
List visualCollection=新列表();
GetVisualChildCollection(父对象作为DependencyObject,visualCollection);
返回视觉采集;
}
私有静态void GetVisualChildCollection(DependencyObject父对象,列出visualCollection),其中T:Visual
{
int count=VisualTreeHelper.GetChildrenCount(父级);
for(int i=0;i
我没有幸运地找到我的复选框PART\u checkbox,带有
this.Template.FindName("control name", this)
方法
但是
成功了
“资源字典”存根
<Style x:Key="OGrid" TargetType="{x:Type local:OrientationGrid}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:OrientationGrid}" x:Name="PART_Control">
<CheckBox x:Name="PART_CheckBox"/>
...
答案基于:
<Style x:Key="OGrid" TargetType="{x:Type local:OrientationGrid}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:OrientationGrid}" x:Name="PART_Control">
<CheckBox x:Name="PART_CheckBox"/>
...
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
CheckBox chkbx = GetTemplateChild("PART_CheckBox") as CheckBox;
chkbx.Checked += Chkbx_Checked;
}
private void Chkbx_Checked(object sender, RoutedEventArgs e)
{
MessageBox.Show("Event Raised");
}
...