Как сделать содержимое WPF условным для некоторых связанных данных? - PullRequest
2 голосов
/ 16 февраля 2011

Я хочу создать пункт меню, но отображаемый текст зависит от свойства модели представления.Если свойство IsPlaying имеет значение true, текст MenuItem должен быть «Пауза», в противном случае это должно быть «Воспроизведение».

Без этого условия MenuItem должен выглядеть примерно так:

<MenuItem Header="_Play" Command="{Binding Path=PlayCommand}" />

Но «Play» и «Pause» должны взаимозаменяться (и, если возможно, PlayCommand должен также поменяться PauseCommand, но это может быть достигнуто при наличии в PlayCommand логики PlayCommand и PauseCommand)

Ответы [ 4 ]

3 голосов
/ 16 февраля 2011

Самый простой способ сделать это - сначала связать Header со свойством string Caption в вашей модели представления, которое возвращает Play или Pause на основе значения IsPlaying и реализует INotifyPropertyChanged.После этого просто добавьте уведомление об изменении для Caption также при изменении IsPlaying.

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

1 голос
/ 16 февраля 2011

В WPF вы можете использовать DataTrigger для изменения содержимого в зависимости от состояния в вашей модели представления (вы даже можете использовать эту технику для замены шаблона). Другой альтернативой является использование VisualStateManager (дальний родственник устройств сбора данных, созданный для его отсутствия в Silverlight, который затем был также перенесен в WPF), чтобы сделать подобное изменение от одного состояния (IsPlaying) к следующему (! IsPlaying ).

Я бы хотел привести более подробный пример, но он уже не спит. Может быть позже сегодня.

1 голос
/ 16 февраля 2011

Несколько способов сделать это:

  1. Использовать триггер.Установите триггер на IsPlaying = True и установите для заголовка и команды значение Pause и PauseCommand соответственно.
  2. У вас есть два пункта меню, Play и Pause, и используйте пару триггеров, чтобы установить их видимость в соответствии с IsPlaying.(Вы также можете связать Visibility с привязкой данных, но использование триггеров избавляет от необходимости определять BooleanToInvisibilityConverter.)
1 голос
/ 16 февраля 2011

Лучшая вещь для этого - конвертер. Ваш код будет выглядеть примерно так:

<UserControl xmlns:myConverters="MyRandomNamespace">
    <UserControl.Resources>
        <myConverters:MyMenuTextConverter x:Key="MyMenuTextConverter" />
    </UserControl.Resources>

    <Grid x:Name="LayoutRoot">
        <TextBlock Text="{Binding IsPlaying, Converter={StaticResource MyMenuTextConverter }}" />
    </Grid>

</UserControl>

и в конвертере:

namespace MyRandomNamespace 
{
    public class MyMenuTextConverter : IValueConverter 
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
        {
            if ((bool) value == true)
               return "Pause";

            return "Play";
        }
    }
}

Я использовал TextBlock для отображения концепции привязки, все, что вам нужно сделать, это использовать тот же синтаксис привязки в соответствующем свойстве MenuItem. Я также возвращаю текстовый конвертер из конвертера, который не является оптимальным (лично мне нравятся мои текстовые конвертеры для извлечения их значений из файла строковых ресурсов, чтобы мое приложение учитывало культуру), но вы поняли идею.

...