WPF: CommandParameters for injecting bindings

One of the things I really like about WPF is the extent to which my views can be built declaratively, i.e. using XAML, not code.

Now I am actually looping through InputBindings because their CommandParameters do not accept bindings. I guess my case is pretty general and simple, but I don't see how I can do this without resorting to the 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>

      

It won't work because the binding expression for the MouseBinding CommandParameter is illegal.

I ask myself: what is the point of adding mouse gestures to the list if I cannot navigate to the selected value?

This can be easily solved with a code-behind event handler, of course, or if the user of the command retrieves the identifier from the source of the command, but there are several reasons why this is not desirable. Aside from the fact that code-flawed code jumps (some of them) target WPF in the first place, this makes UI designers working in Expression Blend less empowered. And dammit, my command parameter should be id, not some UI element !!

Subjective: After looking at SO for a while, I'm amazed at the amount of code I see in WPF related questions. I feel like developers are sticking to our old habits and happily cracking the code file instead of trying a new approach to creating the UI that WPF is supposed to represent. What do you think?

But most importantly : can someone show me a workaround for this seemingly trivial problem? It is advisable that no terrible hacks like this one .

+2


source to share


2 answers


I wrote an extension that allows you to bind InputBinding

Command

:

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

      

Your situation is a bit different since you want to bind CommandParameter

, but you can probably adapt my code to suit your case. Note that this code uses private reflection, which only works in full trust and may be broken in later versions of WPF (in fact, 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 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 property binding Command

, but could probably be adapted for binding CommandParameter

...

+3


source


A new way to solve this problem is to use Expression Triggers / Actions , which allow you to customize keyboard shortcuts on arbitrary controls that do custom actions (like launching a command).



+1


source







All Articles