WPF: как мне обработать событие из модели для динамического обновления xaml в MVVM - PullRequest
2 голосов
/ 18 ноября 2010

Я зашел в тупик, пытаясь понять это ... Используя шаблон MVVM в WPF, наша модель C # запускает событие, чтобы сказать, что что-то произошло. Я хочу иметь возможность обрабатывать это событие в моей ViewModel, а затем либо пнуть раскадровку, либо изменить видимость скрытой панели на текущей странице Xaml. Это должно быть обработано без кода.

Я могу синхронизировать событие в моей ViewModel, обновить свойство, чтобы сказать, как называется это событие, и даже запустить NotifyPropertyChanged, но как мне это сделать, чтобы либо запустить раскадровку, либо сопоставить с логическим значением true / false на свойство видимости моей сетки? Свойство, которое я связываю с hs, должно быть именем события, поскольку разные сетки могут отображаться на основе разных событий, поэтому мне нужен способ сопоставить это с логическим значением. Однако идеальным решением было бы начать раскадровку. Я смотрел на DataTriggers, но все они, похоже, связаны со стилями, а не с реальными страницами.

Есть идеи, как мне этого добиться?

Спасибо!

Ответы [ 3 ]

1 голос
/ 18 ноября 2010

Я использовал это в прошлом, чтобы запустить раскадровку в коде позади

Storyboard animation = (Storyboard)this.FindResource("ShowPanelStoryboard");
animation.Begin();

Этот код идет за View, а не в ViewModel.Лично я не возражаю против некоторого кода за моим View, если он связан только с View.В проекте, в котором я использовал это, я добавил слушателя к событию VisibilityChanged, и когда он изменился на Visible, я запустил раскадровку.

Что касается показа вашего всплывающего окна, есть несколько способов.Одним из моих любимых способов было просто добавить свойство IsPopupShown в ViewModel, привязать к нему видимость моей панели и установить его в значение true в любое время, когда должно отображаться всплывающее окно.Затем ViewModel обрабатывает события, которые запускают показ всплывающего окна или нет.

Альтернатива, предложенная Dave White , заключается в использовании конвертера.Если ваше значение не всегда true / false, вы можете создать конвертер, который проверяет, равно ли связанное значение параметру ConverterParameter, и возвращает значение Visibility.

1 голос
/ 19 ноября 2010

Из вашего комментария мне кажется, что вы, возможно, захотите сделать, выставив свойство Event типа object в вашей модели представления. Когда модель представления получает событие, она устанавливает Event для объекта типа, подходящего для этого события. В вашем XAML у вас есть это:

<ContentControl Content="{Binding Event}"/>

и в словаре ресурсов определите DataTemplate для каждого конкретного типа события, которое вы хотите отобразить. Если Event равно нулю, ничего не отображается. Если Event содержит объект, для которого вы определили DataTemplate, он отображается с использованием этого шаблона.

Да, вам нужно создать класс для каждого типа события (если у вас его еще нет).

Другой способ - реализовать селектор шаблонов для бедняков:

<TextBlock Text="This is displayed if Foo contains 'BAR'">
   <TextBlock.Style>
      <Style TargetType="TextBlock">
         <Setter Property="Visibility" Value="Collapsed"/>
         <Style.Triggers>
            <DataTrigger Property="Foo" Value="BAR">
               <Setter Property="Visibility" Value="Visible"/>
            </DataTrigger>
         </Style.Triggers>
      </Style>
   </TextBlock.Style>
</TextBlock>
<TextBlock Text="This is displayed if Foo contains 'BAZ'">
   <TextBlock.Style>
      <Style TargetType="TextBlock">
         <Setter Property="Visibility" Value="Collapsed"/>
         <Style.Triggers>
            <DataTrigger Property="Foo" Value="BAZ">
               <Setter Property="Visibility" Value="Visible"/>
            </DataTrigger>
         </Style.Triggers>
      </Style>
   </TextBlock.Style>
</TextBlock>

Это немного глупо, но это простой способ обработки множества взаимоисключающих опций отображения.

0 голосов
/ 18 ноября 2010

Свяжите свойство Visibility в вашей сетке в Xaml с логическим свойством в вашей ViewModel.

<Grid Visibility="{Binding Path=VisiblePropertyOnViewModel}">

Теперь сделайте все, что вам нужно, в вашей ViewModel и установите свойство.Пока он выполняет INotifyPropertyChanged или является DependencyProperty, он будет работать.

Мне придется больше копать, чтобы понять, как запустить раскадровку, но я не сомневаюсь, что это будет почти так же легко,Я считаю, что PropertyTriggers могут запустить раскадровки.Я оставлю это, чтобы вы начали.

...