Default datacontext

梦想与她 提交于 2019-12-10 13:48:56

问题


Having the xaml below in MainWindow.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>

And the following code behind 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++;
}

I would have thought that the default DataContext is the code behind. But I'm forced to specify the DataContext. Which DataContext is the default? Null? I would have thought that the code behind would have been (as is the same class).

And as in this sample I'm using the code behind to modify the content of the Label, could I use directly:

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

I will expect that being the code behind, it shouldn't have the UI update problem that you have if the DataContext is in a different class.


回答1:


Yes, the default value of DataContext is null, here is how it's declared in FrameworkElement class -

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

FrameworkPropertyMetadata takes first param for default Value of property.

As it gets inherited by all the child controls your lable's DataContext remains null unless you specify the window data context.

and you can use someLabel.Content = "Counter " + counter++; in codebehind to set labels content; as such it's perfectly fine to access your controls in code behind.




回答2:


Since you are binding a property of a Label, unless you specify a different binding source somehow the binding engine assumes that LabelText is a property on that class. It cannot magically determine that because the Label is a descendant of a MainWindow the binding source should be that window, which is why you need to explicitly declare it.

It's important to note that the concepts of "data context" and "binding source" are distinct: DataContext is one way to specify the binding source, but there are also others.



来源:https://stackoverflow.com/questions/11011990/default-datacontext

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!