2016-11-29 6 views
-1

У меня есть 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, но когда я впервые это сделал, это не сработало. Что-то еще было не так, что, делая все, что нужно, чтобы ответить на комментарии ниже, я как-то восстановил что-то в правильном состоянии.

Благодарим всех вас, комментаторов, за советы и помощь.

+4

Post (части) XAML, и выглядят в окне вывода для ошибок связывания , –

+3

Убедитесь, что вы вызываете свой метод уведомления пользовательского интерфейса из потока пользовательского интерфейса. Здесь много асинхронных операций, и изменения пользовательского интерфейса могут потеряться, если не выполняются в потоке пользовательского интерфейса. –

+1

Кроме того, окно вывода приложения в VS может отображать некоторые ошибки привязки, которые не бросают исключения. Это может быть полезной информацией. –

ответ

0

Я только сделал все привязки TwoWay перед тем, как задать этот вопрос, и к тому времени что-то еще было не так. Я откинулся назад и снова ударил их TwoWay.

Итак, ответ, привязки, которые вы хотите обновлены, когда изменения ViewModel должны быть двухсторонним, например:

Text="{Binding Topic, Mode=TwoWay}"