views:

1283

answers:

2

Hi

One of the things I really like with WPF is the extent to which my views can be built declaratively, ie. using XAML rather than code-behind.

Now I'm really stumped by InputBindings, because their CommandParameters don't accept bindings. I imagine my case is pretty generic and straightforward, but I cannot see how I can do it without resorting to code-behind. Consider:

<ListBox Name="casingsListBox" ItemsSource="{Binding Path=Casings}" SelectedValuePath="Id">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Path=Title}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
    <ListBox.InputBindings>
        <!-- Doesn't work: -->
        <MouseBinding Gesture="LeftDoubleClick"
                      Command="ApplicationCommands.Open"
                      CommandParameter="{Binding RelativeSource={RelativeSource Self} Path=SelectedValue}"/>
    </ListBox.InputBindings>
</ListBox>

This will not work, since the binding expression for the MouseBinding's CommandParameter is illegal.

I ask myself: what's the point of adding a mouse-click gesture to a listbox if I cannot get to the selected value?

This can be easily solved using a code-behind event handler, of course, or by having the command consumer extract the id from the command source, but there are several reasons why this is undesirable. Apart from the fact that droves of code-behind code defeats (some of) the purpose of WPF in the first place, it makes the UI designers working in Expression Blend less empowered. And dammit, my command parameter shall be an id, not some UI element!!

Subjective: Having browsed SO for a while, I'm struck by the amount of code I see in the WPF-related questions. I get the feeling we developers stick to our old habits and happily hack away in the code-behind file rather than trying to utilize the fresh take on UI building that WPF is supposed to represent. What do you think?

But most importantly: can anyone show me a code-free workaround for this seemingly trivial problem? Preferably without terrible hacks like this one.

+1  A: 

The new way to solve this problem is by using Expression Triggers / Actions (http://electricbeach.org/?p=148) which allow you to set up keyboard shortcuts on arbitrary controls that do custom actions (like firing a Command)

Paul Betts
+3  A: 

I wrote a markup extension that allows an InputBinding's Command to be databound :

<KeyBinding Modifiers="Control" Key="E" Command="{input:CommandBinding EditCommand}"/>

Your situation is slightly different since you want to bind the CommandParameter, but you can probably adapt my code to fit your case. Note that this code uses private reflection, which only works in full-trust, and can be broken in later versions of WPF (actually it is broken in WPF 4.0... I can post a modified version if you need it).

Another option is to use the CommandReference class that can be found in the MVVM toolkit :

<Window.Resources>
    <c:CommandReference x:Key="EditCommandReference" Command="{Binding EditCommand}"/>
</Window.Resources>

...

<KeyBinding Modifiers="Control" Key="E" Command="{StaticResource EditCommandReference}"/>

Again, this is for binding the Command property, but can probably be adapted to bind the CommandParameter...

Thomas Levesque