Reputation: 35637
I want to create a menu item but the displayed text depends on a property of the view model.
If the property IsPlaying
is true, the MenuItem text should be "Pause", else it should be "Play".
Without this condition, the MenuItem should be something like:
<MenuItem Header="_Play" Command="{Binding Path=PlayCommand}" />
But, "Play" and "Pause" should interchange (and if possible PlayCommand should interchange with PauseCommand too, but this can be worked by having both the logic of PlayCommand and PauseCommand in PlayCommand)
Upvotes: 3
Views: 2887
Reputation: 9153
In WPF you can use a DataTrigger to change the content based on state in your viewmodel (you could even use this technique to swap out the template). Another alternative is to use the VisualStateManager (the distant cousin of datatriggers created for Silverlight's absence thereof that was then backported to WPF as well) to do a similar change from one state (IsPlaying) to the next (!IsPlaying).
I would love to give a more detailed example but it's past my bedtime. Maybe later today.
Upvotes: 1
Reputation: 49965
The best thing for this is a converter. Your code will look something like this:
<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>
and in the converter:
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";
}
}
}
I've used a TextBlock
to display the concept behind the binding, all you have to do is use the same binding syntax on the appropriate property of the MenuItem. I'm also returning literal text from the converter which is not optimal (personally i like my text converters to retrieve their values from a string resource file so that my app is culture aware), but you get the idea.
Upvotes: 1
Reputation: 74842
A couple of ways to do this:
Upvotes: 1
Reputation: 14608
The simplest way to do this is first you should bind the Header
to a string Caption
property in your viewmodel which returns Play or Pause based on the value of IsPlaying
and implement INotifyPropertyChanged
. After this, just throw change notification for Caption
also when IsPlaying
is changed.
Although you can use a converter, but in this case it will be an overkill.
Upvotes: 3