2012-06-13 19 views
5

,其具有以下XAML中MainWindow.xaml:默認的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> 

而且在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花費的屬性缺省值第一個參數。

由於它被所有子控件繼承,所以標記的DataContext仍然爲null,除非您指定窗口數據上下文。

並且您可以在代碼隱藏中使用someLabel.Content = "Counter " + counter++;來設置標籤內容;因此,在代碼背後訪問您的控件是完全正確的。

3

由於您綁定的是Label的屬性,除非您指定不同的綁定源,否則綁定引擎會假定LabelText是該類的屬性。它不能神奇地確定,因爲LabelMainWindow的後裔,綁定源應該是該窗口,這就是爲什麼您需要明確聲明它。

需要注意的是「數據上下文」和「綁定源」的概念是截然不同是很重要的:DataContext一種方式指定綁定源,但there arealsoothers

+0

雖然如此,綁定/ datacontext是從父母沒有指定時繼承。否則,在窗口類上設置datacontext將不會產生結果。 –

+0

@MiyamotoAkira:當然,它是繼承的(DataContext的文檔也是這樣說的)。但是你爲什麼期望你的'MainWindow'默認是任何東西的'DataContext'?綁定引擎無法讀取您的想法。 – Jon

+1

我想,因爲我看到'MainWindow'作爲這個程序的層次結構的頂部。但接下來,我不知道wpf在做什麼(但是:-)),並且可能還有其他的東西。 –