2010-11-10 25 views
3

我有以下ControlTemplate如何在ControlTemplate中声明事件处理程序?

<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_Click以访问文本框Text属性?

更新:只是为了说清楚。我知道如何在这里连接Click事件处理程序。问题是如何阅读其中的文本框的内容,因为我不能给他们的名字,因为他们在模板中。

回答

0

如果您有机会获得templatedparent(的SelectedItem,FindVisualParent等),如果你申请的名称,你可以这样做到TextBoxes。示例如果ControlTemplate用于ComboBoxItem。

private void AddUser_Click(object sender, RoutedEventArgs e) 
{ 
    ComboBoxItem comboBoxItem = GetVisualParent<ComboBoxItem>(button); 
    TextBox textBox = comboBoxItem.Template.FindName("numberTextBox", comboBoxItem) as TextBox; 
    //... 
} 

获取ControlTemplate中TextBoxes的另一种方法是使用Visual Tree。事情是这样的

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.. 
     } 
    } 
} 

而且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); 
     } 
    } 
} 
17

你可以做的是给Button一个名字“PART_Button”。然后在控件中覆盖OnApplyTemplate方法。在代码中,你可以做

var btn = this.Template.FindName("PART_Button", this) as Button; 
btn.Click += ... 
+1

如果我能给予好评100次我会!谢谢! – 2014-09-26 07:10:11

4

事件处理程序中搜索类的x:Class指令当前文件点到,它允许你添加事件处理程序内联而不打扰覆盖类和覆盖OnApplyTemplate与无论您声明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!"); 
    } 
    } 
} 
0

我没有运气找到我的复选框,PART_CheckBox,与

this.Template.FindName("control name", this) 

方法 但

GetTemplateChild("control name") 

工作。

'资源字典' 存根

<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"/> 
          ... 

自定义控件,OrientationGrid,存根:基于

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"); 
    } 
    ... 

答案: WPF get element from template in code

相关问题