项目开发中遇到一个要求,需要将ComboBox右侧中的小三角箭头给去掉,通过Blend工具“编辑ComboBox的模板副本”得知,这是一个名为"BtnArrow"的Path。但是在CS代码中,是无法引用到这个控件的。
解决办法:重新定义一个类,继承自ComboBox,然后重写OnApplyTemplate方法,代码如下
代码语言:javascript复制using System.Windows;
using System.Windows.Controls;
using System.Windows.Shapes;
namespace ContentTemplateTest
{
public class YJMComboBox : ComboBox
{
public bool IsShowDropDownArrow
{
get { return (bool)GetValue(IsShowDropDownArrowProperty); }
set { SetValue(IsShowDropDownArrowProperty, value); }
}
public static readonly DependencyProperty IsShowDropDownArrowProperty =
DependencyProperty.Register("IsShowDropDownArrow", typeof(bool), typeof(YJMComboBox), new PropertyMetadata(true, OnIsShowDropDownArrowChanged));
static void OnIsShowDropDownArrowChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
YJMComboBox _yjmCombobox = obj as YJMComboBox;
if (_yjmCombobox != null)
{
if ((bool)args.NewValue)
{
_yjmCombobox._DropDownToggleButton.Visibility = Visibility.Visible;
}
else
{
_yjmCombobox._DropDownToggleButton.Visibility = Visibility.Collapsed;
}
}
}
private Path _DropDownToggleButton = new Path();
public override void OnApplyTemplate()
{
_DropDownToggleButton = GetTemplateChild("BtnArrow") as Path;
base.OnApplyTemplate();
}
}
}
我增加了一个BOOL型的依赖属性IsShowDropDownArrow,并在OnApplyTemplate方法重载时获取了BtnArrow的引用,然后在IsShowDropDownArrow属性变化时,修改了BtnArrow的可视性。
注:
代码语言:javascript复制 //
// Summary:
// 在实例化的 System.Windows.Controls.ControlTemplate 可视化树中检索已命名的元素。
//
// Parameters:
// childName:
// 要查找的元素的名称。
//
// Returns:
// 模板中的命名元素(如果已找到)。如果在模板中找不到具有名称 childName 的元素,则可能返回 null。
protected DependencyObject GetTemplateChild(string childName);
通过查看GetTemplateChild方法的定义得知,这是一个Protected方法,所以只能在子类中使用,这也就是为什么在常规Xaml.cs文件中无法获取ContentTemplate中命名控件的原因。
剩下的事情就简单了,来测试一把!
xaml文件如下:
代码语言:javascript复制<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:System="clr-namespace:System;assembly=mscorlib" x:Class="ContentTemplateTest.MainPage"
mc:Ignorable="d"
xmlns:local="clr-namespace:ContentTemplateTest"
d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Background="White">
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center">
<local:YJMComboBox HorizontalAlignment="Center" VerticalAlignment="Center" Width="100" x:Name="cbo">
</local:YJMComboBox>
<Button Content="Test" HorizontalAlignment="Center" VerticalAlignment="Top" Click="Button_Click" Margin="10,0,0,0"></Button>
</StackPanel>
</Grid>
</UserControl>
Xaml.cs部分:
代码语言:javascript复制using System.Windows;
using System.Windows.Controls;
namespace ContentTemplateTest
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
this.cbo.IsShowDropDownArrow = !this.cbo.IsShowDropDownArrow;
}
}
}
运行截图:
按下按钮前
按下按钮后