我知道在OnApplyTemplate函数内,通过GetTemplateChild函数获取自定义控件的ControlTemplate内的控件,并设置处理自定义控件内部流程的内部事件,在自定义控件的内部事件,处理触发自定义事件和改变自定义的依赖属性。
但除了
OnApplyTemplate
还有其他的设置方式,能在自定义控件内部触发自定义的事件和改变自定义依赖属性的值吗?
我编写了一个比较简单用于测试的自定义控件的代码,继承于Control控件的自定义控件,为了测试,只设置了两个bool类型的依赖属性和一个测试事件。试图通过触发器的触发操作自定义控件的值改变,调用SetValue方法,在SetValue方法内触发自定义事件和改变其他自定义的依赖属性的值。
c#代码:
public class TestCustomControl : Control
static TestCustomControl()
DefaultStyleKeyProperty.OverrideMetadata(typeof(TestCustomControl), new FrameworkPropertyMetadata(typeof(TestCustomControl)));
public bool TestBool1
get { return (bool)GetValue(TestBool1Property); }
set {
SetValue(TestBool1Property, value);
TestBool2 = value;
if (value == true)
RoutedEventArgs args = new RoutedEventArgs(TestClickEvent, this);
RaiseEvent(args);
public static readonly DependencyProperty TestBool1Property =
DependencyProperty.Register("TestBool1", typeof(bool), typeof(TestCustomControl), new PropertyMetadata(false));
public bool TestBool2
get { return (bool)GetValue(TestBool2Property); }
set { SetValue(TestBool2Property, value); }
public static readonly DependencyProperty TestBool2Property =
DependencyProperty.Register("TestBool2", typeof(bool), typeof(TestCustomControl), new PropertyMetadata(false));
/// <summary>
/// 测试点击事件
/// </summary>
public static readonly RoutedEvent TestClickEvent =
EventManager.RegisterRoutedEvent("TestClick", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(SwitchButton));
public event RoutedEventHandler TestClick
AddHandler(TestClickEvent, value);
remove
RemoveHandler(TestClickEvent, value);
xaml代码:
<Style TargetType="{x:Type local:TestCustomControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:TestCustomControl}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Button x:Name="testBtn" Content="测试" FontSize="20" Margin="15" ></Button>
</Border>
<ControlTemplate.Triggers>
<Trigger SourceName="testBtn" Property="IsPressed" Value="True">
<Setter Property="local:TestCustomControl.TestBool1" Value="True" ></Setter>
<Setter TargetName="testBtn" Property="Button.Padding" Value="10" ></Setter>
<Setter TargetName="testBtn" Property="Button.Background" Value="Red" ></Setter>
<Setter TargetName="testBtn" Property="Button.FontSize" Value="15" ></Setter>
</Trigger>
<Trigger Property="local:TestCustomControl.TestBool1" Value="True">
<Setter Property="Background" Value="Green" ></Setter>
<Setter Property="BorderBrush" Value="Blue" ></Setter>
<Setter Property="BorderThickness" Value="2" ></Setter>
</Trigger>
<Trigger Property="local:TestCustomControl.TestBool2" Value="True">
<Setter TargetName="testBtn" Property="Button.Content" Value="5678" ></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
想要做的事情:
该测试自定义控件TestCustomControl,其ControlTemplate里的触发器中,TestCustomControl实例内,如果testBtn被点击,也就是IsPressed为true,则TestCustomControl和内部的testBtn按钮产生外观上的变化,并调用依赖属性TestBool1的SetValue,而TestBool1的SetValue调用过程中,如果value为true,则触发TestClick事件。并且Value的值赋值给TestBool2,而在触发器中,如果TestBool2值为true,testBtn的Content的显示内容为“5678”。
testBtn被点击,也就是IsPressed为true,Property="local:TestCustomControl.TestBool1" Value="True" 这段触发器代码被触发了,TestCustomControl实例的外观上是发生了变化(背景色为绿色,边框色为蓝色),但是依赖属性TestBool1的SetValue并没有被调用。TestClick事件未被触发和TestBool2值没有发生改变。
测试的自定义控件中ControlTemplate.Triggers内,Trigger内的settter对TestBool1的触发改变后,不会调用TestBool1依赖属性的SetValue方法。
这个要怎么解决,还是触发器对自定义依赖属性的触发改变,不会调用依赖属性的setValue方法?我想在自定义控件中设置某些依赖属性SetValue调用后,触发自定义的事件。
其 Extensible Application Markup Language (XAML) 处理器的 Windows Presentation Foundation (WPF) 实现本质上是依赖属性感知的。 因此,XAML 处理器使用 WPF 属性系统方法来加载 XAML
和处理依赖属性特性,并通过使用 WPF 属性系统方法(如 GetValue 和 SetValue)完全绕过依赖属性包装器。
因此,如果将自定义逻辑添加到自定义依赖属性的属性包装器,则在 XAML 中设置属性值时,XAML 处理器不会调用该逻辑。
您需要做的是注册一个回调方法,该方法在依赖项属性更改时触发:
public static readonly DependencyProperty TestBool1Property =
DependencyProperty.Register("TestBool1", typeof(bool), typeof(TestCustomControl),
new FrameworkPropertyMetadata(false, new PropertyChangedCallback(OnTestBool1Changed) ));
private static void OnTestBool1Changed(DependencyObject obj, DependencyPropertyChangedEventArgs args)
你可以参考Control authoring overview的自定义依赖属性和自定义路由事件的示例。
MSDN Community Support
Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to
MSDN Support, feel free to contact [email protected].