[ACCEPTED]-How to declare event handlers inside ControlTemplate?-wpf
What you could do is give Button a name 2 "PART_Button". Then override OnApplyTemplate 1 method in control. In code, you can do
var btn = this.Template.FindName("PART_Button", this) as Button;
btn.Click += ...
The event handler is searched in the class 6 that the x:Class
directive of current file points 5 to, which allows you adding the event handler 4 inline without bothering to override the 3 class and override the OnApplyTemplate
with adding handlers 2 hassle, regardless of the place that you 1 declare the 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!");
}
}
}
If you have access to the templatedparent 7 (SelectedItem, FindVisualParent etc.) you 6 can do this if you apply Names to the TextBoxes. Example 5 if ControlTemplate is for ComboBoxItem.
private void AddUser_Click(object sender, RoutedEventArgs e)
{
ComboBoxItem comboBoxItem = GetVisualParent<ComboBoxItem>(button);
TextBox textBox = comboBoxItem.Template.FindName("numberTextBox", comboBoxItem) as TextBox;
//...
}
Another 4 way to get the TextBoxes within the ControlTemplate 3 would be to use the Visual Tree. Something 2 like this
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..
}
}
}
And an implementation of GetVisualParent 1 and 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);
}
}
}
I had no luck finding my checkbox, PART_CheckBox, with 3 the
this.Template.FindName("control name", this)
method but
GetTemplateChild("control name")
worked.
'ResourceDictionary' stub
<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"/>
...
Custom 2 Control, OrientationGrid, stub:
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");
}
...
answer based 1 on: WPF get element from template in code
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.