Почему привязка обновляется без реализации INotifyPropertyChanged? - PullRequest
40 голосов
/ 14 октября 2011

Я создал ViewModel и связал его свойство с двумя текстовыми полями в пользовательском интерфейсе.Значение другого текстового поля изменяется, когда я изменяю значение first и focus вне текстового поля , но я не реализую INotifyPropertyChanged.Как это работает?

Ниже приводится XAML

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <local:ViewModel />
    </Window.DataContext>
    <StackPanel>
        <TextBox Text="{Binding Name}" />
        <TextBox Text="{Binding Name}" />
    </StackPanel>
</Window>

. И вот моя ViewModel

class ViewModel
{
    public string Name { get; set; }
}

Ответы [ 3 ]

49 голосов
/ 14 октября 2011

Я проверял это, вы правы.Теперь я искал его в Интернете и обнаружил this .

Извините, что так долго не отвечал, на самом деле вы столкнулись с еще одним скрытым аспектом WPF , то есть механизм связывания данных WPF будет привязывать данные к экземпляру PropertyDescriptor , который переносит свойство источника, если исходный объект является простым объектом CLR и не реализует интерфейс INotifyPropertyChanged .И механизм привязки данных попытается подписаться на событие измененного свойства с помощью метода PropertyDescriptor.AddValueChanged ().И когда целевой связанный элемент данных изменяет значения свойства, механизм привязки данных вызовет метод PropertyDescriptor.SetValue () для передачи измененного значения обратно в исходное свойство и одновременно вызовет событие ValueChanged для уведомления других подписчиков (в этом случаедругие подписчики будут TextBlocks в ListBox.

И если вы реализуете INotifyPropertyChanged, вы несете полную ответственность за реализацию уведомления об изменении в каждом установщике свойств, которые должны быть данными, связанными с пользовательским интерфейсом.изменение не будет синхронизировано, как вы ожидаете.

Надеюсь, это немного прояснит ситуацию.

Так что в принципе вы можете делать это, пока это простоОбъект CLR. Довольно аккуратный, но совершенно неожиданный - и за последние годы я немного поработал над WPF. Вы никогда не прекращаете изучать новые вещи, верно?

Как подсказал Хасан Хан, вот другая ссылка к довольно интересной статьеs subject.

Примечание работает только при использовании привязки .Если вы обновите значения из кода , об изменении не будет сообщено .[...]

WPF использует гораздо более легкий класс PropertyInfo при связывании.Если вы явно реализуете INotifyPropertyChanged, все, что нужно сделать WPF, - это вызвать метод PropertyInfo.GetValue, чтобы получить последнее значение.Это немного меньше работы, чем получение всех дескрипторов.Дескрипторы в конечном итоге стоят в 4 раза больше памяти классов информации о свойствах.[...]

Реализация INotifyPropertyChanged может быть довольно трудоемкой работой по разработке.Однако вам нужно будет взвесить эту работу в сравнении с объемом времени выполнения (память и ЦП) вашего приложения WPF. Самостоятельное внедрение INPC позволит сэкономить ЦП и память времени выполнения .

1 голос
/ 24 августа 2012

Я только что узнал, что это также работает в WinForms, вроде: /

public class Test
{
    public bool IsEnabled { get; set; }
}

var test = new Test();
var btn = new Button { Enabled = false, Text = "Button" };
var binding = new Binding("Enabled", test, "IsEnabled");
btn.DataBindings.Add(binding);
var frm = new Form();
frm.Controls.Add(btn);
test.IsEnabled = true;
Application.Run(frm);

Как ни странно, кнопка не отключается:

btn.Enabled = false;

Это делает:

test.IsEnabled = false;
1 голос
/ 14 октября 2011

Я могу объяснить, почему свойство обновляется при изменении фокуса: все Binding s имеют свойство UpdateSourceTrigger, которое указывает , когда свойство источника будет обновлено. Значение по умолчанию для этого определяется для каждого DependencyProperty, а для свойства TextBox.Text установлено значение LostFocus, что означает, что свойство будет обновлено, когда элемент управления потеряет фокус.

Я полагаю, что ответ UrbanEsc объясняет, почему значение обновляется вообще

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