Язык программирования C#9 и платформа .NET5
private readonly IList<Car> _cars =new ObservableCollection<Car>();Снова запустите приложение и щелкните на кнопке Add Car. Новые записи будут должным образом появляться.
Реализация флага изменения
Еще одним преимуществом наблюдаемых моделей является способность отслеживать изменения состояния. Отслеживать флаги изменения (т.е. когда изменяется одно и более значений объекта) в WPF довольно легко. Добавьте в класс
свойство типаCarпо имениbool. Внутри его блокаIsChangedвызовите методset, как поступали с другими свойствами классаOnPropertyChanged().Carprivate bool _isChanged;public bool IsChanged {get => _isChanged;set{if (value == _isChanged) return;_isChanged = value;OnPropertyChanged();}}Свойство
необходимо устанавливать вIsChangedвнутри методаtrue. Важно не устанавливать свойствоOnPropertyChanged()вIsChangedв случае изменения его самого, иначе сгенерируется исключение переполнения стека! Модифицируйте методtrueследующим образом (здесь используется описанная ранее операцияOnPropertyChanged()):nameofprotected virtual void OnPropertyChanged([CallerMemberName] string propertyName = ""){if (propertyName != nameof(IsChanged)){IsChanged = true;}PropertyChanged?.Invoke(this,new PropertyChangedEventArgs(propertyName));}Откройте файл
и добавьте вMainWindow.xamlдополнительный элементDetailsGrid. Поместите в конец элементаRowDefinitionпоказанную ниже разметку, которая содержит элементы управленияGridиLabel, привязанные к свойствуCheckbox:IsChanged<Label Grid.Column="0" Grid.Row="5" Content="Is Changed"/><CheckBox Grid.Column="1" Grid.Row="5" VerticalAlignment="Center"Margin="10,0,0,0" IsEnabled="False" IsChecked="{Binding Path=IsChanged}" />Если вы запустите приложение прямо сейчас, то увидите, что каждая отдельная запись отображается как измененная, хотя пока ничего не изменялось! Дело в том, что во время создания объекта устанавливаются значения свойств, а установка любых значений приводит к вызову метода
, который и устанавливает свойствоOnPropertyChanged()объекта. Чтобы устранить проблему, установите свойствоIsChangedвIsChangedпоследним в коде инициализации объекта. Откройте файлfalseи модифицируйте код создания списка:MainWindow.xaml.cs_cars.Add(new Car {Id = 1, Color = "Blue", Make = "Chevy",PetName = "Kit", <b>IsChanged = false</b>});_cars.Add(new Car {Id = 2, Color = "Red", Make = "Ford",PetName = "Red Rider", <b>IsChanged = </b><b>false</b>});Снова запустите приложение, выберите автомобиль и щелкните на кнопке Change Color. Флажок Is Changed (Изменено) становится отмеченным наряду с изменением цвета.
Обновление источника через взаимодействие с пользовательским интерфейсом
Во время выполнения приложения можно заметить, что при вводе в текстовых полях флажок Is Changed не становится отмеченным до тех пор, пока фокус не покинет элемент управления, где производился ввод. Причина кроется в свойстве
привязок элементовUpdateSourceTrigger.TextBoxСвойство
определяет, какое событие (изменение значения, переход фокуса и т.д.) является основанием для обновления пользовательским интерфейсом лежащих в основе данных. ПеречислениеUpdateSourceTriggerпринимает значения, описанные в табл. 28.1.UpdateSourceTriggerСтандартным событием обновления для элементов управления
являетсяTextBox. Измените его наLostFocus, модифицировав привязку для элементаPropertyChanged, который отвечает за ввод цвета:TextBox<TextBox Grid.Column="1" Grid.Row="2" Text="{Binding Path=Color,UpdateSourceTrigger=PropertyChanged}" />Если вы запустите приложение и начнете ввод в текстовом поле Color (Цвет), то флажок Is Changed немедленно отметится. Может возникнуть вопрос о том, почему для элементов управления
в качестве стандартного выбрано значениеTextBox. Дело в том, что проверка достоверности (рассматриваемая вскоре) для модели запускается в сочетании сLostFocus. В случаеUpdateSourceTriggerэто может потенциально вызывать ошибки, которые будут постоянно возникать до тех пор, пока пользователь не введет корректное значение. Например, если правила проверки достоверности не разрешают вводить в элементеTextBoxменее пяти символов, тогда сообщение об ошибке будет отображаться при каждом нажатии клавиши, пока пользователь не введет пять или более символов. В таких случаях с обновлением источника лучше подождать до момента, когда пользователь переместит фокус из элементаTextBox(завершив изменение текста).TextBox
