2010-11-10 51 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

相關問題