WPF:在OnApplyTemplate中绘制自定义控件的部分:如何更新?

时间:2019-01-23 12:58:15

标签: c# wpf viewmodel

我可以在控件的OnApplyTemplate方法中成功绘制自定义控件的一部分,但是,此方法仅被调用一次,而当控件的{{ 1}}属性更改。

这是自定义控件的代码:

ApplyTemplate

我知道调用Num是因为using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Shapes; namespace Cc1 { public class CirclesControl : Control { static CirclesControl() { DefaultStyleKeyProperty.OverrideMetadata(typeof(CirclesControl), new FrameworkPropertyMetadata(typeof(CirclesControl))); } public int Num { get { return (int)GetValue(NumProperty); } set { SetValue(NumProperty, value); } } public static readonly DependencyProperty NumProperty = DependencyProperty.Register("Num", typeof(int), typeof(CirclesControl), new PropertyMetadata(2, new PropertyChangedCallback(OnNumChanged))); private static void OnNumChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is CirclesControl control) { System.Diagnostics.Debug.WriteLine($"Num changed - value is now {control.Num}"); control.ApplyTemplate(); } } public override void OnApplyTemplate() { base.OnApplyTemplate(); var canvasPart = Template.FindName("Part_Canvas", this); if (canvasPart is Canvas canvas) { for (int i = 0; i < Num; i++) { var circle = new Ellipse { Height = 50, Width = 50, Fill = Brushes.Red, Stroke = Brushes.Green }; canvas.Children.Add(circle); Canvas.SetLeft(circle, i * 55); Canvas.SetTop(circle, 50); } } } } } 将消息写入输出窗口。 OnNumChanged也会调用System.Diagnostics.Debug.WriteLine,但这不会导致OnNumChanged被调用。

这是主窗口的xaml:

ApplyTemplate

控件的OnApplyTemplate

<Window x:Class="Cc1.MainWindow"
        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:local="clr-namespace:Cc1"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="1024">
<Window.DataContext>
    <local:ViewModel/>
</Window.DataContext>
    <StackPanel>
        <TextBlock Text="{Binding NumberOfCircles}" FontSize="36"/>
        <local:CirclesControl Num="{Binding NumberOfCircles}"/>
    </StackPanel>
</Window>

和视图模型:

generic.xaml

圆数(在视图模型中)一直在变化(这是调度程序计时器执行的操作)。主窗口上的<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:Cc1"> <Style TargetType="{x:Type local:CirclesControl}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type local:CirclesControl}"> <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> <Canvas x:Name="Part_Canvas"/> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> </ResourceDictionary> 可以准确地反映出圆圈的数量,但是主窗口上的using System; using System.Windows; using System.Windows.Threading; namespace Cc1 { public class ViewModel : DependencyObject { public ViewModel() { var timer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(500) }; timer.Tick += (s, e) => { NumberOfCircles++; if (NumberOfCircles == 10) { NumberOfCircles = 2; } }; timer.Start(); } public int NumberOfCircles { get { return (int)GetValue(NumberOfCirclesProperty); } set { SetValue(NumberOfCirclesProperty, value); } } public static readonly DependencyProperty NumberOfCirclesProperty = DependencyProperty.Register("NumberOfCircles", typeof(int), typeof(ViewModel), new PropertyMetadata(4)); } } 自定义控件不会更新。

非常感谢您对缺失内容的任何提示。

0 个答案:

没有答案