У меня есть DataGrid
на основе Appointment
объектов. Когда пользователь дважды щелкает по строке, я открываю окно модели для просмотра/редактирования кликнутой встречи. Я делаю это с помощью приведенной ниже команды, связанной с событием мыши LeftDoubleClick
. Обязательные операции и команда правильно выведены.Почему обновление моего представления не изменяется, когда я изменяю свойства viewmodel?
_doubleClickCommand = new DelegateCommand<AppointmentRowViewModel>(async p =>
{
if (BossViewModel.ShowModalCommand.CanExecute(null))
{
var modal = new AppointmentFormWindow();
await modal.ViewModel.Populate(p.Id, Cts.Token);
BossViewModel.ShowModalCommand.Execute(modal);
}
},
p => true
);
Выбранный элемент и параметр команды, p
, является AppointmentRowViewModel
, чисто представление модели для AppointmentDto
объекта, с только свойствами и нулевой логики.
BossViewModel
- это вид модели MainWindow
, отвечающий за управление изображением, и в этом случае для отображения модалов и сообщений. Я возложил на себя эту ответственность, потому что в окне сообщений требуется окно владельца, и это единственная модель просмотра, которая знает о ее представлении. Было просто иметь смысл открывать и управлять другими окнами от MainWindowViewModel
.
Так DoubleClickCommand
создает экземпляр окна, которое он хочет открыть, и XAML для этого окна в этом случае присваивает ему AppointmentFormViewModel
. Команда вызывает Populate
на этой ViewModel, чтобы загрузить назначение и сопоставить его с этой ViewModel:
public override async Task Populate(int? entityId = null, CancellationToken cancellation = new CancellationToken())
{
if (entityId.HasValue)
{
await _apptService.Load(entityId.Value, this, cancellation);
}
IsInitialized = true;
OnAllPropertiesChanged();
}
где я использую INotifyPropertyChanged
как это:
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnAllPropertiesChanged()
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(string.Empty));
}
Тогда BossViewModel.ShowModalCommand
выглядит следующим образом:
_showModalCommand = new DelegateCommand<IModal>(async modal =>
{
modal.ViewModel.BossViewModel = this;
modal.ShowDialog();
},
a => !ModalOpen
);
Все работает нормально, назначение загружается из БД, сопоставлено с его моделью просмотра, которая уже назначена на AppointmentGridWindow
. Модаль открывается, но его viewmodel полностью заполнен, а не поля формы обновляются, чтобы отражать значения свойств viewmodel. Как будто я создаю новое назначение.
Все мои привязки данных с помощью «Mode = TwoWay
, NotifyOnSourceUpdated = True
», так что я бы ожидать, установив значение на ViewModel и повышение PropertyChanged
обновит вид элемента, но вид остается все полностью пустым.
ОБНОВЛЕНИЕ: Вот выдержка XAML с точки зрения, которая остается пустой. Свойства viewmodel, которые они привязаны ко всем, имеют допустимые значения, так как форма отлично работает только для захвата.
<Window.DataContext>
<vm:AppointmentFormViewModel />
</Window.DataContext>
.....
<TextBlock Text="Topic:" />
<TextBox Text="{Binding Topic, Mode=TwoWay}" />
<TextBlock Text="Venue: " />
<TextBox Text="{Binding Venue, Mode=TwoWay}" />
<TextBlock Text="Start Date: " />
<DatePicker SelectedDate="{Binding StartDate, Mode=TwoWay}" />
<ComboBox IsEditable="False" ItemsSource="{Binding TimeList}" SelectedItem="{Binding Path=StartTime, Mode=TwoWay}" />
<TextBlock Text="End Date: "/>
<DatePicker SelectedDate="{Binding EndDate}" />
<ComboBox IsEditable="False" ItemsSource="{Binding Path=TimeList}" SelectedItem="{Binding Path=EndTime, Mode=TwoWay}" />
....
<DataGrid x:Name="TheList" Grid.Row="1" ItemsSource="{Binding Attendees}"....>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding GivenName}" Header="Given Name" />
<DataGridTextColumn Binding="{Binding FamilyName}" Header="Family Name" />
<DataGridTextColumn Binding="{Binding Phone}" Header="Phone" />
<DataGridTextColumn Binding="{Binding EMail}" Header="Email" />
<DataGridTextColumn Binding="{Binding Position}" Header="Position" />
<DataGridTextColumn Binding="{Binding OrgName}" Header="Org." />
<DataGridTextColumn Binding="{Binding BranchName}" Header="Branch" />
</DataGrid.Columns>
ПРОБЛЕМА ПОСТАНОВИЛИ: Внезапно, после долгих инспекции кода, редактирования для указанных кодов отрывками и Гаденыш откатов, мнение о котором идет речь в настоящее время населяет правильно. Я думаю, что он делал привязки TwoWay
, но когда я впервые это сделал, это не сработало. Что-то еще было не так, что, делая все, что нужно, чтобы ответить на комментарии ниже, я как-то восстановил что-то в правильном состоянии.
Благодарим всех вас, комментаторов, за советы и помощь.
Post (части) XAML, и выглядят в окне вывода для ошибок связывания , –
Убедитесь, что вы вызываете свой метод уведомления пользовательского интерфейса из потока пользовательского интерфейса. Здесь много асинхронных операций, и изменения пользовательского интерфейса могут потеряться, если не выполняются в потоке пользовательского интерфейса. –
Кроме того, окно вывода приложения в VS может отображать некоторые ошибки привязки, которые не бросают исключения. Это может быть полезной информацией. –