2016-10-16 3 views
5

私は、次のリソースを持っている:WPFのDataContextは、一見同じ状況で異なる動作を

<Window.Resources> 
    <SolidColorBrush x:Key="b" Color="{Binding B}" /> 
    <my:C x:Key="c" Prop="{Binding Source={StaticResource b}}" /> 
    <my:C x:Key="d" Prop="{Binding A}" /> 
    <Ellipse x:Key="e" Fill="{Binding A}" /> 
    <Ellipse x:Key="f"> 
     <Ellipse.Fill> 
      <SolidColorBrush Color="{Binding B}" /> 
     </Ellipse.Fill> 
    </Ellipse> 
</Window.Resources> 

私の窓は、データコンテキストは次のように宣言している:

<Window ... DataContext="{my:Context}" ...> 

Cとコンテキストは次のように定義されているカスタムクラス:

public class Context : MarkupExtension 
{ 
    public Brush A { get; } = Brushes.Blue; 
    public Color B { get; } = Colors.Red; 

    public override object ProvideValue(IServiceProvider serviceProvider) => this; 
} 

public class C : DependencyObject 
{ 
    public static readonly DependencyProperty PropProperty = DependencyProperty.Register("Prop", typeof(Brush), typeof(C)); 
    public Brush Prop { get { return (Brush)GetValue(PropProperty); } set { SetValue(PropProperty, value); } } 
} 

ここで、私のデータコンテキストとバインディングを使用する方法は非常に私に似て、まだ私は(ボタンのクリックハンドラ内)

MessageBox.Show("f: " + ((FindResource("f") as Ellipse).Fill?.ToString() ?? "null")); 
MessageBox.Show("e: " + ((FindResource("e") as Ellipse).Fill?.ToString() ?? "null")); 
MessageBox.Show("d: " + ((FindResource("d") as C).Prop?.ToString() ?? "null")); 
MessageBox.Show("c: " + ((FindResource("c") as C).Prop?.ToString() ?? "null")); 
MessageBox.Show("b: " + (FindResource("b") as SolidColorBrush).Color.ToString()); 

次のコードで私のリソースをチェックすると、私はこの結果を得る:

f: #00FFFFFF 
e: null 
d: null 
c: #FFFF0000 
b: #FFFF0000 

はすなわち、最後の二つは一見正しいです。これの理由は何でしょうか?

答えて

1

Strange。

my:Cには明らかにDataContextがないため、何かに直接バインドすることはできません。 DataContextのと

リソースは、リソースの所有者のDataContext(楕円のEとF)

SolidColorBrushの「b」は、保護フィールド/プロパティが「B」のためであるInheritanceContextを呼び出したフォームSystem.Windows.Freezableを導出継承しません。 MainWindowに設定します。私はContext.Bにこのリファレンスを通してアクセスできると思うので、 "b"と "c"が正しい色を表示するのはそのためです。

0

私はこれについて興味があったので、ちょっと試してみることに決めました。私はXAMLの専門家の近くにいるわけではありませんが、私が助けてもらうために私の所見を共有したいと思っていました。 、以下のバインディングのエラーが出力ウィンドウに登場

Ellipse Screenshot

:ここでの結果のスクリーンショットがある

<Ellipse Fill="{StaticResource b}" /> 
<Ellipse Grid.Row="1" Fill="{Binding Source={StaticResource c}, Path=Prop}" /> 
<Ellipse Grid.Row="2" Fill="{Binding Source={StaticResource d}, Path=Prop}" /> 
<ContentControl Grid.Row="3" Content="{StaticResource e}" /> 
<ContentControl Grid.Row="4" Content="{StaticResource f}" /> 

私はページ上のGridに次のXAMLを追加しましたdが記入されていない理由を説明していると思います:

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=A; DataItem=null; target element is 'C' (HashCode=60275915); target property is 'Prop' (type 'Brush')

dのバインディングを解決できない場合があります。その理由は、要素階層内の位置を特定できず、DataContextを解決できないためです。

私がXAMLにコメントした場合、その動作は質問に投稿されたものとまったく同じであることに気付きました。 edの両方がnullでした。これに基づいて、実行時にバインドを解決できるかどうかにかかわらず、リソースの使用が影響を受けるようです。

バインディングがリソース内でどのように機能するかをより深く理解している人から聞くことは素晴らしいことです。

関連する問題