Wednesday, December 17, 2008

WPF Command.Text

I'm not sure why it never occurred to me before, but this might help clean up some of the code out there where buttons are bound to commands.

The standard way I have been binding to buttons is to set the command and then set the content like one of the following:

<Button x:Name="PlayButton" 
        Command="{Binding PlayCommand}">Play</Button>
<Button x:Name="Help"
        Command="ApplicationCommands.Help" 
        Content="{Binding RelativeSource={RelativeSource Self}, 
                 Path=Command.Text}" />

Which in the first case just repeats the word "Play" three times and in the second case is just plain ugly and not something you would want to reproduce everywhere just to infer the content from the Command when typing "Help" would be easier to type and to read. Yeah obvious, now that I spell it out to myself. I should just set my default style on my buttons to be something like this and include it in my skins/app.xaml

<Style TargetType="Button">
  <!--Default Button content to be the Text provided from the Command.-->
  <Setter Property="Content" 
          Value="{Binding RelativeSource={RelativeSource Self}, 
           Path=Command.Text}"/>
</Style>
Now all buttons will try to set their content to the Command's Text property if it has one (RoutedUICommands do). If the command doesn't expose a Text Property or the button is not bound to a command, well I still was going to have to code some content anyway so no big loss.

3 comments:

Aaron said...

Lee,

Thanks for posting this. I spent the last few hours bashing my face into my desk to get this exact binding correct. So simple yet, for some reason I couldn't see the need to make it relative and instead kept trying to link to the actual static property on the view.

Now to just see about stuffing this into a base class so buttons will pick up the command text by default and I'll be set...

Thank you sir

Lee Campbell said...

Thanks Aaron,
The point of the post was that you don't really need a base class (has everyone gone base-class crazy!?). Remember the principal 'composition over inheritance'.

If you just updated your styles for the app to something like the style in the post you should be fine. Maybe I should update the style to be the full and correct version of a style (ie include BasedOn attribute) see Styles based on Keyless resources

Petr Skaloud said...

Thanks for sharing. It helped me.