2012-06-13 16 views
5

XAML unten in MainWindow.xaml Mit:Standard Datacontext

<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> 

Und der folgende Code hinter in 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++; 
} 

Ich hätte gedacht, dass die Standard-DataContext ist der Code dahinter. Aber ich bin gezwungen, die DataContext anzugeben. Welche DataContext ist die Standardeinstellung?Null? Ich hätte gedacht, dass der Code dahinter wäre (wie es die gleiche Klasse ist).

Und wie in diesem Beispiel hinter dem Code Ich bin mit dem Inhalt des Etiketts zu ändern, konnte ich direkt verwenden:

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

ich, dass der Code hinter sein werde erwartet, sollte es nicht hat Das UI Update-Problem, das Sie haben, wenn die DataContext in einer anderen Klasse ist.

Antwort

5

Ja, der Standardwert von DataContext ist null, hier ist, wie es in FrameworkElement Klasse deklariert wird -

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

FrameworkPropertyMetadata nimmt ersten param für Standardwert der Immobilie.

Da es von allen untergeordneten Steuerelementen geerbt wird, bleibt DataContextnull Ihres Etiketts, es sei denn Sie spezifizieren den Fensterdatenkontext.

und Sie können someLabel.Content = "Counter " + counter++; in Codebehind verwenden, um Beschriftungsinhalt festzulegen; als solches ist es vollkommen in Ordnung, auf Ihre Steuerelemente im Code dahinter zuzugreifen.

3

Da Sie eine Eigenschaft einer Label binden, vorausgesetzt, dass Sie eine andere Bindungsquelle irgendwie angeben, nimmt die Bindungs-Engine an, dass LabelText eine Eigenschaft für diese Klasse ist. Es kann nicht magisch feststellen, dass, weil die Label ein Nachkomme von MainWindow ist, sollte die Bindungsquelle dieses Fenster sein, weshalb Sie es explizit deklarieren müssen.

Es ist wichtig, dass die Begriffe „Datenkontext“ zu beachten und „Bindungsquelle“ sind verschieden: DataContext ist ein Weg die Bindungsquelle angeben, aber there arealsoothers.

+0

ich, dass der binding/datacontext von der übergeordneten geerbt wird, wenn nicht angegeben. Andernfalls führt das Festlegen des Datenkontexts für die Fensterklasse immer noch nicht zum Ergebnis. –

+0

@MiyamotoAkira: Sicher, es ist geerbt (die Dokumentation für 'DataContext' sagt das auch). Aber warum erwartest du, dass dein MainWindow standardmäßig der 'DataContext' ist? Die Bindemaschine kann Ihre Gedanken nicht lesen. – Jon

+1

Ich nehme an, weil ich "MainWindow" als oberste Hierarchie für dieses Programm sehe. Aber dann weiß ich nicht, was WPF unter der Haube macht (noch :-)), und wahrscheinlich gibt es noch andere Dinge dazu. –