例如,有一个派生自UserControl的类MyUserControlBase ,并且在其构造函数中有一组内容依赖属性的绑定。
MyUserControlBase.cs
namespace BindingBeforeInitComp
{
using System.Diagnostics;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Data;
public class MyUserControlBase : UserControl
{
public static readonly DependencyProperty MyContentProperty = DependencyProperty.Register("MyContent",
typeof(object),
typeof(MyUserControl),
new PropertyMetadata(null, MyContentChangedCallback));
public MyUserControlBase()
{
// Set binding to the Content property.
var propertyPath = new PropertyPath("Content");
var binding = new Binding { Path = propertyPath, Source = this };
SetBinding(MyContentProperty, binding);
}
public object MyContent
{
get { return GetValue(MyContentProperty); }
set { SetValue(MyContentProperty, value); }
}
private static void MyContentChangedCallback(
DependencyObject dependencyObject,
DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
Debugger.Break(); // Breaking here to show that binding to Content property has updated.
}
}
}
还有从MyUserControlBase派生的MyUserControl (cs+xaml) 。在构造函数中有默认的 IntializeComponents() 方法(注意:在基本构造函数中此方法之前设置了绑定)。在调用 IntializeComponents() 之前 Content 属性为空,在调用 Content 之后设置为 xaml 中描述的内容。但是绑定不会更新目标属性。
MyUserControl.xaml.cs
namespace BindingBeforeInitComp
{
using System.Diagnostics;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
public sealed partial class MyUserControl : MyUserControlBase
{
public MyUserControl()
{
Debugger.Break(); // Here Content is null.
InitializeComponent();
Debugger.Break(); // Here Content is set, but as you can see there is no binding update.
}
private void ChangeContentClick(object sender, RoutedEventArgs e)
{
// Change content by a click. In this case the property changing should trigger update.
Content = new Grid() { Background = new SolidColorBrush(Colors.Chartreuse) };
}
}
}
MyUserControl.xaml
<local:MyUserControlBase
x:Class="BindingBeforeInitComp.MyUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:BindingBeforeInitComp"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<Grid Background="OrangeRed">
<Button Click="ChangeContentClick" HorizontalAlignment="Center" Width="200" Height="150" Background="#FF00AE4F">Change content</Button>
</Grid>
</local:MyUserControlBase>
完整来源:https ://github.com/inTagger/Bugs/tree/master/BindingBeforeInitComp
更新:我已经更新了 GitHub 上的源代码,添加了 WPF (NET45) 项目来演示依赖属性和绑定应该如何工作的真实方式。是的,WPF 没有这样的问题(行为/功能/错误)。
UPDATE2:如果直接在构造函数中设置 Content 依赖属性 - 绑定有效,但如果 Content 在 InitializeComponents() 中的某个位置设置则无效。