2012-06-13 17 views
5

Tener la xaml continuación en MainWindow.xaml:defecto 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> 

Y el siguiente código atrás en 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++; 
} 

yo habría pensado que el defecto DataContext es el código detrás. Pero me veo obligado a especificar el DataContext. ¿Cuál DataContext es el valor predeterminado?Null? Hubiera pensado que el código detrás habría sido (como es la misma clase).

Y como en esta muestra que estoy usando el código detrás de modificar el contenido de la etiqueta, podría utilizar directamente:

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

voy a esperar que ser el código detrás, no debería haber el problema de actualización de UI que tiene si el DataContext pertenece a una clase diferente.

Respuesta

5

Sí, el valor por defecto de DataContext es null, aquí es como se declara en la clase 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 ocupa el primer parámetro para el valor predeterminado de la propiedad.

Como es heredado por todos los controles secundarios, DataContext de su etiqueta permanece null a menos que especifique el contexto de datos de la ventana.

y puede usar someLabel.Content = "Counter " + counter++; en código subyacente para establecer el contenido de las etiquetas; como tal, está perfectamente bien acceder a tus controles en código subyacente.

3

Dado que está vinculando una propiedad de Label, a menos que especifique una fuente de enlace diferente de alguna manera, el motor de enlace asume que LabelText es una propiedad de esa clase. No puede determinar mágicamente que debido a que Label es un descendiente de MainWindow, la fuente de enlace debe ser esa ventana, por lo que debe declararla explícitamente.

Es importante tener en cuenta que los conceptos de "contexto de datos" y "origen de enlace" son distintos: DataContextes una forma para especificar el origen de enlace, pero there arealsoothers.

+0

Creo que el enlace/datacontext se hereda del padre cuando no se especifica. De lo contrario, establecer el contexto de datos en la clase de ventana todavía no producirá resultados. –

+0

@MiyamotoAkira: Claro, es heredado (la documentación para 'DataContext' también lo dice). ¿Pero por qué esperas que tu 'MainWindow' sea el' DataContext' de cualquier cosa por defecto? El motor de enlace no puede leer tu mente. – Jon

+1

Supongo porque estoy viendo 'MainWindow' como el tope de la jerarquía para este programa. Pero luego, no sé lo que está haciendo wpf (aún :-)), y probablemente haya otras cosas encima. –