XAML中的Source与DataContext

时间:2011-08-04 19:37:53

标签: wpf data-binding

哪种方法最好?

<Window.Resources>
    <sys:Int16 x:Key="MyValue">123</sys:Int16>
</Window.Resources>

<StackPanel>

    <!-- method 1 -->
    <TextBlock Text="{Binding}" DataContext="{StaticResource MyValue}" />

    <!-- method 2 -->
    <TextBlock Text="{Binding, Source={StaticResource MyValue}}" />

</StackPanel>

3 个答案:

答案 0 :(得分:4)

与许多“哪个更好”的问题一样。我会说“这取决于”背景。

它们都存在,因为它们都可以在不同的环境中起作用。只给出上面显示的内容,我会选择示例2。

但是,当您设置DataContext时,它的所有子项都将继承该DataContext。所以也许您正在使用Button。在你的按钮中,你想要将它加了一点,然后用不同的颜色显示四次文本。如下所示,我将选择示例1。

示例1 :(注意DataContext在按钮上,而TextBlocks不像示例2中那样需要Source)

<Button DataContext="{StaticResource MyValue}" Height="Auto" Width="Auto" HorizontalAlignment="Center" VerticalAlignment="Center">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding}" Foreground="Red" />
        <TextBlock Grid.Row="1" Grid.Column="0" Text="{Binding}" Foreground="Blue" />
        <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding}" Foreground="Yellow"/>
        <TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding}" Foreground="Green" />
    </Grid>
</Button>

示例2:

<Button Height="Auto" Width="Auto" HorizontalAlignment="Center" VerticalAlignment="Center">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding, Source={StaticResource MyValue}}" Foreground="Red" />
        <TextBlock Grid.Row="1" Grid.Column="0" Text="{Binding, Source={StaticResource MyValue}}" Foreground="Blue" />
        <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding, Source={StaticResource MyValue}}" Foreground="Yellow"/>
        <TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding, Source={StaticResource MyValue}}" Foreground="Green" />
    </Grid>
</Button>

当您绑定到一个只有一个像Int16这样的表示的简单对象时,您可能只会绑定并显示该值一次,因此选项2最有意义。

一个好的经验法则...如果你发现自己将“Source”设置为同一个多个绑定,你应该只绑定一个公共父FrameworkElement的DataContext。

答案 1 :(得分:1)

我想说如果我必须在两者之间做出选择,我会选择方法2. DataContext实际上更多的是将项目数据绑定到更复杂的底层对象,并简化了许多数据值的数据绑定。

出于好奇,你为什么这样做?您的代码在某些时候是否会更改MyValue的值?你出于某种原因没有更好的办法吗?

答案 2 :(得分:1)

DataContenxt DependencyProperty允许您轻松绑定DependencyObject的所有proeprties。

Binding的Source DependenceyProperty允许您将该特定绑定指向您想要的源,而不管DataContext。

当您为ListView执行更复杂的绑定时,这将变得非常有用。例如:

<Window.Resources>
  <local:MyConverter x:Key="MyConverter" />
</Window.Resources>
<Grid>
  <ComboBox ItemsSource="{Binding Source={StaticResource MyConverter}, Path=DisplayValues}" DataContenxt={Binding ElementName=lvwItems Path=SelectedItem} SelectedItem="{Binding Converter={StaticResource MyConverter}"/>
<ListView Name="lvwItems"......

上面的例子只是展示我将itemssource设置为名为DisplayValues的'MyConverter'中的属性,datacontext就是我在那个组合框上工作的,它处理的是SelectedItem属性。 ListView名为'lvwItems'。

希望这有帮助。