Silverlight:获取ContentTemplate中的命名控件

项目开发中遇到一个要求,需要将ComboBox右侧中的小三角箭头给去掉,通过Blend工具“编辑ComboBox的模板副本”得知,这是一个名为"BtnArrow"的Path。但是在CS代码中,是无法引用到这个控件的。

 

解决办法:重新定义一个类,继承自ComboBox,然后重写OnApplyTemplate方法,代码如下

01 using System.Windows;
02 using System.Windows.Controls;
03 using System.Windows.Shapes;
04  
05 namespace ContentTemplateTest
06 {
07     public class YJMComboBox : ComboBox
08     {
09  
10         public bool IsShowDropDownArrow
11         {
12             get { return (bool)GetValue(IsShowDropDownArrowProperty); }
13             set { SetValue(IsShowDropDownArrowProperty, value); }
14         }
15  
16          
17         public static readonly DependencyProperty IsShowDropDownArrowProperty =
18             DependencyProperty.Register("IsShowDropDownArrow", typeof(bool), typeof(YJMComboBox), new PropertyMetadata(true, OnIsShowDropDownArrowChanged));
19  
20  
21         static void OnIsShowDropDownArrowChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
22         {
23             YJMComboBox _yjmCombobox = obj as YJMComboBox;
24             if (_yjmCombobox != null)
25             {
26                 if ((bool)args.NewValue)
27                 {
28                     _yjmCombobox._DropDownToggleButton.Visibility = Visibility.Visible;
29                 }
30                 else
31                 {
32                     _yjmCombobox._DropDownToggleButton.Visibility = Visibility.Collapsed;
33                 }
34             }
35         }
36  
37         private Path _DropDownToggleButton = new Path();
38  
39         public override void OnApplyTemplate()
40         {
41             _DropDownToggleButton = GetTemplateChild("BtnArrow") as Path;
42             base.OnApplyTemplate();
43         }
44     }
45 }

我增加了一个BOOL型的依赖属性IsShowDropDownArrow,并在OnApplyTemplate方法重载时获取了BtnArrow的引用,然后在IsShowDropDownArrow属性变化时,修改了BtnArrow的可视性。

注:

01 //
02 // Summary:
03 //     在实例化的 System.Windows.Controls.ControlTemplate 可视化树中检索已命名的元素。
04 //
05 // Parameters:
06 //   childName:
07 //     要查找的元素的名称。
08 //
09 // Returns:
10 //     模板中的命名元素(如果已找到)。如果在模板中找不到具有名称 childName 的元素,则可能返回 null。
11 protected DependencyObject GetTemplateChild(string childName);

  通过查看GetTemplateChild方法的定义得知,这是一个Protected方法,所以只能在子类中使用,这也就是为什么在常规Xaml.cs文件中无法获取ContentTemplate中命名控件的原因。

剩下的事情就简单了,来测试一把!

xaml文件如下:

01 <UserControl
06     xmlns:System="clr-namespace:System;assembly=mscorlib" x:Class="ContentTemplateTest.MainPage"
07     mc:Ignorable="d"
08     xmlns:local="clr-namespace:ContentTemplateTest"
09     d:DesignHeight="300" d:DesignWidth="400">
10  
11  
12  
13     <Grid x:Name="LayoutRoot" Background="White">
14         <StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center">
15             <local:YJMComboBox HorizontalAlignment="Center" VerticalAlignment="Center" Width="100" x:Name="cbo">
16                
17             </local:YJMComboBox>
18             <Button Content="Test" HorizontalAlignment="Center" VerticalAlignment="Top" Click="Button_Click" Margin="10,0,0,0"></Button>
19         </StackPanel>
20     </Grid>
21 </UserControl>

 Xaml.cs部分:

01 using System.Windows;
02 using System.Windows.Controls;
03  
04 namespace ContentTemplateTest
05 {
06     public partial class MainPage : UserControl
07     {
08         public MainPage()
09         {
10             InitializeComponent();           
11         }
12  
13         private void Button_Click(object sender, RoutedEventArgs e)
14         {
15             this.cbo.IsShowDropDownArrow = !this.cbo.IsShowDropDownArrow;
16         }
17     }
18 }
posted @ 2011-09-07 09:49  牟向阳  阅读(355)  评论(0编辑  收藏  举报