我發展我的第一個WPF自定義控件,我面臨的一些問題之後調用自定義控制OnApplyTemplate,這裏是我目前使用的代碼的簡化版本:依賴屬性回調
using System.Windows;
using System.Windows.Controls;
namespace MyControls
{
[TemplatePart(Name = "PART_Button", Type = typeof (Button))]
public class MyControl : Control
{
public static readonly DependencyProperty ContentProperty = DependencyProperty.Register("Content", typeof (object), typeof (MyControl), new PropertyMetadata(null, OnLabelPropertyChanged));
private Button _buttonElement;
public object Content
{
get { return this.GetValue(LabelProperty); }
set { this.SetValue(ContentProperty, value); }
}
static MyControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof (MyControl), new FrameworkPropertyMetadata(typeof (MyControl)));
}
private static void OnContentPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
MyControl myControl = sender as MyControl;
if (myControl != null && myControl._buttonElement != null)
myControl._buttonElement.Content = e.NewValue;
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
this._buttonElement = this.Template.FindName("PART_Button", this) as Button;
}
}
}
這是模板爲我的自定義控件:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyControls">
<Style TargetType="{x:Type local:MyControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:MyControl}">
<Button x:Name="PART_Button" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
然後我把它放在一個網格內,並嘗試設置其Content屬性:
<Grid x:Name="layoutRoot">
<controls:MyControl x:Name="myControl" />
</Grid>
這裏是後面的代碼:
using System.Windows;
namespace MyControls
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
this.InitializeComponent();
this.myControl.Content = "test";
}
}
}
這是不行的,由於某種原因,OnContentPropertyChanged回調OnApplyTemplate之前調用,因此myControl._buttonElement分配太晚了,試圖把它的內容時,它仍然是零。爲什麼會發生這種情況,我該如何改變這種行爲?
我還需要提供完整的設計時支持,但我不能找到一種方法,讓我的自定義控件接受一些額外的標記,就像網格控件使用ColumnDefinitions:
<Grid x:Name="layoutRoot">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
</Grid>
任何幫助將是很大的不勝感激!
UPDATE
我發現了一個文件,解釋爲何在控制性的判定所設置的OnApplyTemplate方法被稱爲:
http://msdn.microsoft.com/en-us/library/dd351483%28v=vs.95%29.aspx
因此問題是:我怎麼能保持跟蹤屬性(以XAML或編程方式)設置,以及在控件尚未初始化時調用的方法,以便在調用OnApplyTemplate方法時設置/調用它們?如何在不重複代碼的情況下在控制初始化之前和之後使用相同的回調/方法?
你試過打電話給base.OnApplyTemplate();在您的Template.FIndName(..)之後? – sam 2016-05-30 09:55:34