我可以在控件的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));
}
}
自定义控件不会更新。
非常感谢您对缺失内容的任何提示。