5

以下のコードの問題は、 to へのバインドがSomeClassProp.SubTextProp機能しない (ソース プロパティがテキスト ボックスのコンテンツに設定されていない) のに対し、 toは機能するTextPropことです。

XAML:

<Window x:Class="TestWPF.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow"
        Name="wMain"
        SizeToContent="WidthAndHeight">
    <StackPanel>
        <TextBox Text="{Binding ElementName=wMain, Path=SomeClassProp.SubTextProp}" Width="120" Height="23" />
        <TextBox Text="{Binding ElementName=wMain, Path=TextProp}" Width="120" Height="23" />
    </StackPanel>
</Window>

そしてコード:

public partial class MainWindow : Window
{
    public SomeClass SomeClassProp { get; set; }
    public string TextProp { get; set; }

    public MainWindow()
    {
        InitializeComponent();
        SomeClassProp = new SomeClass();
    }
}

public class SomeClass
{
    public string SubTextProp { get; set; }
}

ここで明らかな何かが欠けていますか?

ターゲット (テキスト ボックス) からソース (クラス プロパティ) への動作には、このバインドが必要であることに注意してください。

更新:バインディングをからに変更すると、ElementName=wMain両方のRelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}バインディングが機能します。ElementNameしたがって、問題はバインディング プロパティに固有のものです。

4

1 に答える 1

7

わかりました、ついに問題が見つかりました!

バインディング定義に追加diag:PresentationTraceSources.TraceLevel=Highした後 (非常に便利なことですが、通常の古い段階的なデバッグがない場合)、出力に次のように表示されました。

System.Windows.Data 警告: 108: BindingExpression (ハッシュ = 54116930): レベル 0 - MainWindow.SomeClassProp の場合、アクセサー RuntimePropertyInfo(SomeClassProp) が見つかりました
System.Windows.Data 警告: 104: BindingExpression (ハッシュ = 54116930): アクセサー RuntimePropertyInfo(SomeClassProp) を使用して、レベル 0 の項目を MainWindow (ハッシュ = 47283970) に置き換えます
System.Windows.Data 警告: 101: BindingExpression (ハッシュ = 54116930): RuntimePropertyInfo(SomeClassProp) を使用して MainWindow (ハッシュ = 47283970) からレベル 0 で GetValue:
System.Windows.Data 警告: 106: BindingExpression (hash=54116930): レベル 1 の項目が null - アクセサーがありません
System.Windows.Data 警告: 80: BindingExpression (ハッシュ = 54116930): TransferValue - 生の値 {DependencyProperty.UnsetValue} を取得しました
System.Windows.Data 警告: 88: BindingExpression (ハッシュ = 54116930): TransferValue - フォールバック/既定値を使用 ''
System.Windows.Data 警告: 89: BindingExpression (ハッシュ = 54116930): TransferValue - 最終値 '' を使用

問題は MainWindow の初期化の順序にありました!

そのため、バインディングが構築された時点で、レベル 0 のプロパティ ( SomeClassProp) がまだ初期化されていなかったため、バインディングが完全に失敗しました (何らかの理由で通常レベルのビンジング警告を発行することなく)。

簡単に言えば、 inコンストラクターがトリックをSomeClassProp実行する前に初期化を移動すると、バインドも機能し始めました。InitializeComponent()MainWindowElementName

public MainWindow()
{
    SomeClassProp = new SomeClass();
    InitializeComponent();
}

質問に対する答え -RelativeSourceプロパティを使用して機能した理由 - は、出力ログの次の行にあります

System.Windows.Data Warning: 66 : BindingExpression (hash=28713467): RelativeSource (FindAncestor) requires tree context
System.Windows.Data Warning: 65 : BindingExpression (hash=28713467): Resolve source deferred

ツリー コンテキストを必要とするデータ コンテキストの初期化はRelativeSource、 の構築後のある時点まで延期されますWindow(その時点までSomeClassPropertyには既に初期化されています)。

于 2013-08-24T14:24:04.297 に答える