2012-06-13 13 views
5

Avere il codice XAML di seguito in MainWindow.xaml:predefinito 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> 

E il seguente codice dietro 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++; 
} 

avrei pensato che il default DataContext è il codice dietro. Ma sono costretto a specificare lo DataContext. Quale DataContext è il valore predefinito?Null? Avrei pensato che il codice dietro sarebbe stato (come è la stessa classe).

E come in questo esempio sto usando il codice sottostante per modificare il contenuto dell'etichetta, potrei usare direttamente:

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

farò aspettare che essendo il codice dietro, non dovrebbe avere il problema di aggiornamento dell'interfaccia utente che hai se lo DataContext si trova in una classe diversa.

risposta

5

Sì, il valore predefinito di DataContext è null, ecco come è dichiarato nel FrameworkElement classe -

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

FrameworkPropertyMetadata è al primo param per valore predefinito di proprietà.

Come viene ereditato da tutti i controlli figlio, l'etichetta DataContext rimane null a meno che non venga specificato il contesto dati della finestra.

ed è possibile utilizzare someLabel.Content = "Counter " + counter++; in codebehind per impostare il contenuto delle etichette; come tale è perfettamente bene accedere ai tuoi controlli nel codice sottostante.

3

Poiché si sta vincolando una proprietà di Label, a meno che non si specifichi un'origine di associazione diversa in qualche modo il motore di associazione presuppone che LabelText sia una proprietà su quella classe. Non è possibile determinare magicamente che poichéè un discendente di MainWindow, la sorgente di associazione deve essere quella finestra, motivo per cui è necessario dichiararla esplicitamente.

E 'importante notare che i concetti di "contesto dati" e "fonte vincolante" sono distinti: DataContext è un modo per specificare l'origine vincolante, ma there arealsoothers.

+0

Io tuttavia, che il binding/datacontext è ereditato dal padre quando non specificato. In caso contrario, l'impostazione del datacontext sulla classe della finestra non produrrà ancora risultato. –

+0

@MiyamotoAkira: Certo, è ereditato (la documentazione per 'DataContext 'lo dice anche tu). Ma perché ti aspetti che la 'MainWindow' sia il' DataContext' di qualcosa di default? Il motore di associazione non può leggere la tua mente. – Jon

+1

Suppongo perché vedo 'MainWindow' come la parte superiore della gerarchia per questo programma. Ma poi, non so cosa stia facendo wpf sotto il cofano (ancora :-)), e probabilmente ci sono altre cose su di esso. –

Problemi correlati