Источник против DataContext в XAML - PullRequest
3 голосов
/ 04 августа 2011

Какой из этих методов лучше?

<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 ]

4 голосов
/ 06 августа 2011

Как и во многих «что лучше» вопросах. Я бы сказал, что «это зависит» от контекста.

Они оба существуют, потому что они оба могут служить цели в разных контекстах. Учитывая только то, что вы показали выше, я бы выбрал Пример 2.

Однако, когда вы устанавливаете DataContext, все его дочерние элементы наследуют этот DataContext. Так что, возможно, вместо этого вы используете кнопку. А внутри вашей кнопки вы хотите немного поднять ее и отобразить текст четыре раза, каждый из которых имеет свой цвет. Как вы можете видеть ниже, я бы тогда выбрал Пример 1.

Пример 1: (обратите внимание, что DataContext находится на кнопке, и TextBlock не нуждается в источнике, как в примере 2)

<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' для одной и той же вещи более чем одной привязки, вам, вероятно, следует просто связать DataContext общего родительского FrameworkElement.

1 голос
/ 04 августа 2011

DataContenxt DependencyProperty позволяет вам легко связать все свойства для DependencyObject.

Source DependenceyProperty привязки позволяет вам указать эту конкретную привязку к нужному источнику, независимо от DataContext.

Это становится действительно полезным, когда вы делаете более сложные привязки для ListViews.Например:

<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 для свойства в 'MyConverter', называемого DisplayValues, однако этот текстовый текст - это то, с чем я работаю в этом комбинированном списке,обрабатывает свойство SelectedItem объекта ListView с именем 'lvwItems'.

Надеюсь, это поможет.

1 голос
/ 04 августа 2011

Я бы сказал, что если бы мне пришлось выбирать между двумя, я бы выбрал метод 2. DataContext действительно больше подходит для привязки данных элемента к более сложному базовому объекту и облегчает привязку данных многих значений данных.

Просто из любопытства, почему ты так делаешь? Меняет ли ваш код значение MyValue в какой-то момент? Нет ли лучшего способа сделать это по какой-то причине?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...