Создает ли привязка двух элементов управления WPF к одному свойству модели общую привязку? - PullRequest
2 голосов
/ 16 февраля 2012

Почему, если я связываю два элемента управления, скажем, 2 TextBox, с одним свойством модели, которая не реализует INotifyPropertyChanged, содержимое двух текстовых полей остается синхронизированным? Как другой TextBox уведомляется о том, что другой обновляет источник?

Модель:

namespace BindingExample
{
    public class PersonModel
    {
        public string Name { get; set; }
    }
}

Вид:

<Window x:Class="BindingExample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:BindingExample"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <local:PersonModel x:Key="person"></local:PersonModel>
        <Style TargetType="TextBox">
            <Setter Property="VerticalAlignment" Value="Center" />
            <Setter Property="Width" Value="100"/>
        </Style>    
    </Window.Resources>
    <Grid DataContext="{StaticResource person}">
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <TextBox Text="{Binding Path=Name, UpdateSourceTrigger=PropertyChanged}" />
        <TextBox Grid.Row="1" Text="{Binding Path=Name, UpdateSourceTrigger=PropertyChanged}"/>
    </Grid>
</Window>

1 Ответ

1 голос
/ 22 апреля 2012

Два текстовых поля в вашем примере используют один и тот же текст данных и фактически совместно используют один и тот же экземпляр объекта .NET PersonModel, поскольку статический ресурс по умолчанию в словаре ресурсов WPF имеет значение shared , т.е. при обращении к статическому ресурсу вы всегда получите один и тот же экземпляр. Подробнее об атрибуте x: Shared в MSDN:

Статья MSDN о x: общий атрибут

Альтернативой этому является установка x: Shared в false, чтобы каждый раз получать новый экземпляр. Кроме того, мне пришлось удалить привязку к текстовому тексту в вашем примере, чтобы по отдельности можно было редактировать значения в текстовых полях по отдельности.

Следующий XAML показывает это:

<Window x:Class="WpfScrollToEndBehavior.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfScrollToEndBehavior"
    Title="MainWindow" Height="350" Width="525">
<Window.Resources>
    <local:PersonModel x:Key="person" x:Shared="false" Name="John Doe"> </local:PersonModel>
    <Style TargetType="TextBox">
        <Setter Property="VerticalAlignment" Value="Center" />
        <Setter Property="Width" Value="100"/>
    </Style>
</Window.Resources>
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
    </Grid.RowDefinitions>
    <TextBox Text="{Binding Path=Name, UpdateSourceTrigger=PropertyChanged, Source={StaticResource person}}" />
    <TextBox Grid.Row="1" Text="{Binding Path=Name, UpdateSourceTrigger=PropertyChanged, Source={StaticResource person}}" />
</Grid>

Причина для x: Shared установлена ​​в true для ресурсов в словаре ресурсов по причинам эффективности. Установив x: Shared для ресурса (например, объекта) в словаре ресурсов в XAML, мы будем получать новые экземпляры каждый раз, когда к ресурсу обращаются и получают к нему доступ. Мне пришлось удалить контекст данных из сетки и установить источник привязки для текстовых полей к статическому ресурсу.

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