0

たとえば、UserControlから派生したクラスMyUserControlBaseがあり、そのコンストラクター内にContent依存関係プロパティのバインディングのセットがあります。

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 プロパティが null で、呼び出し後は 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() 内のどこかに設定されている場合は機能しません。

4

1 に答える 1

0

このInitializeComponentメソッドの仕事は Xaml をロードすることなので、実行が完了するまで UI 要素を使用できないことが予想されます。

イベントの処理を検討Loadedしてください。基本コンストラクターでハンドラーをアタッチできます。オブジェクトが完全に構築されるまでイベントは発生しません。

于 2013-08-05T13:15:32.667 に答える