2012-06-13 6 views
5

のDataContextデフォルト:MainWindow.xamlに以下のXAMLを持つ

<Window x:Class="TestDependency.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525" 
     DataContext="{Binding RelativeSource={RelativeSource Self}}"> 
    <Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition></RowDefinition> 
     <RowDefinition></RowDefinition> 
     <RowDefinition></RowDefinition> 
    </Grid.RowDefinitions> 
    <Label Name="someLabel" Grid.Row="0" Content="{Binding Path=LabelText}"></Label> 
    <Button Grid.Row="2" Click="Button_Click">Change</Button> 
    </Grid> 
</Window> 

そしてMainWindow.xaml.csでの背後にある次のコード:

public static readonly DependencyProperty LabelTextProperty = DependencyProperty.Register("LabelText", typeof(String), typeof(MainWindow)); 

public int counter = 0; 

public String LabelText 
{ 
    get 
    { 
    return (String)GetValue(LabelTextProperty); 
    } 

    set 
    { 
    SetValue(LabelTextProperty, value); 
    } 
} 

private void Button_Click(object sender, RoutedEventArgs e) 
{ 
    LabelText = "Counter " + counter++; 
} 

は私が思っているだろうというデフォルトDataContextコードの背後にある。しかし、私は強制的にDataContextを指定します。 デフォルトはDataContextですか?Null?私は、後ろのコードが(同じクラスのように)あったと思っていたでしょう。

そして、このサンプルのように、私はラベルの内容を変更することの背後にあるコードを使用しています、私が直接使用することができます

someLabel.Content = "Counter " + counter++; 

私は背後にあるコードであること、それは持つべきではないことを期待していますDataContextが別のクラスに含まれている場合のUI更新の問題

答えて

5

はい、DataContextのデフォルト値は、ここでは、nullであることがFrameworkElementクラスで宣言されています方法です -

public static readonly DependencyProperty DataContextProperty = 
    DependencyProperty.Register("DataContext", typeof(object), 
    FrameworkElement._typeofThis, 
    (PropertyMetadata) new FrameworkPropertyMetadata((object)null, 
     FrameworkPropertyMetadataOptions.Inherits, 
     new PropertyChangedCallback(FrameworkElement.OnDataContextChanged))); 

FrameworkPropertyMetadataは、プロパティのデフォルト値のための最初のパラメータを取ります。

すべての子コントロールによって継承されるので、ウィンドウデータコンテキストを指定しない限り、lableのDataContextnullのままです。

コードビハインドでsomeLabel.Content = "Counter " + counter++;を使用すると、ラベルの内容を設定できます。したがって、コードの背後にあるコントロールにアクセスするのはまったく問題ありません。

3

Labelのプロパティをバインドしているので、バインディングエンジンは別のバインディングソースを指定しない限り、LabelTextはそのクラスのプロパティであるとみなします。 LabelMainWindowの子孫であるため、バインディングソースはそのウィンドウである必要があるため、明示的に宣言する必要があると魔法の元で判断することはできません。

それは「データコンテキスト」と「バインディングソース」の概念が異なっていることに注意することが重要です:DataContext1バインディングソースを指定する方法が、there arealsoothersです。

+0

しかし、binding/datacontextは、指定されていない場合は親から継承されます。それ以外の場合は、ウィンドウクラスのdatacontextを設定しても結果は生成されません。 –

+0

@MiyamotoAkira:確かに、それは継承されています( 'DataContext'のドキュメントもそうです)。しかし、なぜあなたの 'MainWindow'がデフォルトで何かの' DataContext'であると期待していますか?バインディングエンジンはあなたの心を読むことができません。 – Jon

+1

私はこのプログラムの階層のトップとして 'MainWindow'を見ていると思います。しかし、その後、wpfが何をしているのかはわかりません(まだ:-))、おそらくそれの上に他のものがあります。 –

関連する問題