DermFrench
DermFrench

Reputation: 4057

Button Command Binding

I have a button inside a listbox. I want to bind the command to the DataContext of the Main Grid. I'm not sure who to do this, below is my attempt.

I want to bind to ViewModel.SelectionEditorSelectionSelectedCommand on my view model, which the main grid is bound to, I don't want to bind to the actual filteredSelection.SelectionEditorSelectionSelectedCommand

Here is my XAML

<Grid Name="MainGrid">
   .....
    <ListBox x:Name="MarketsListBox"  Height="Auto" MaxHeight="80" ItemsSource="{Binding Path=FilteredMarkets}" Margin="5" Width="Auto" HorizontalAlignment="Stretch"
                 >
          ListBox.ItemTemplate>
                    <DataTemplate>
                        <WrapPanel Orientation="Horizontal">
                            <Button Height="Auto" 
                                    Content="{Binding FinishingPosition,Converter={StaticResource FinishingPositionToShortStringConverter1}}" 
                                    Foreground="{Binding Path=FinishingPosition, Converter={StaticResource FinishingPositionToColourConverter1}}" 
                                    Margin="2" Width="20"
                                    Command="{Binding ElementName=MainGrid.DataContext, Path=SelectionEditorSelectionSelectedCommand}" 
                                    CommandParameter="{Binding}"
                                    />
    .....

Upvotes: 1

Views: 6445

Answers (3)

nmclean
nmclean

Reputation: 7734

Binding to the grid using ElementName should work, but you have made a small error in the binding syntax. ElementName must include the name only, not a property. You simply need to include DataContext in the Path:

Command="{Binding ElementName=MainGrid,
                  Path=DataContext.SelectionEditorSelectionSelectedCommand}"

Upvotes: 2

sircodesalot
sircodesalot

Reputation: 11439

So based on this line:

Command="{Binding ElementName=MainGrid.DataContext ... }

I'm assuming you have something like this:

<Grid Name="MainGrid">
    <Grid.DataContext>
        <lol:GridViewModel /> <!--Some kind of view model of sorts-->
    </Grid.DataContext>
    ... content
</Grid>

Then all you would have to do is on the ViewModel class create a public property that returns some sort of ICommand, such as:

class GridViewModel {
    public ICommand SelectionEditorSelectionSelectedCommand { 
        get { return new TestCommand(); } 
    }
}

Where TestCommand would be some kind of class implementing ICommand as in:

class TestCommand : ICommand {
    public event EventHandler CanExecuteChanged { get; set; }

    public bool CanExecute(object parameter)
    {
        return true; // Expresses whether the command is operable or disabled.
    }

    public void Execute(object parameter)
    {
         // The code to execute here when the command fires.
    }
}

Basically, for ICommand you just need to define what happens when the command Executes, how to determine whether or not it CanExecute and then supply an event handle for when CanExecuteChanged. Once you have this setup, all you have to do is wire up your button like this:

<Button Command="{Binding SelectionEditorSelectionSelectedCommand}" />

And that's it. Basically the binding will automatically check your ViewModel class for a property called SelectionEditorSelectionSelectedCommand, that implements ICommand. When it reads the property it will instantiate an instance of TestCommand, and WPF will handle it from there. When the button is clicked Execute will be fired like clockwork.

Upvotes: 1

trinaldi
trinaldi

Reputation: 2950

You should try as I did in a similar situation:

<Button Command="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type Grid}}, Path=DataContext.YOURCOMMANDHERE}" />

I had a button inside a TabItem Header and it worked Ok! The thing is, your Command is a Property of the DataContext, so your path should indicate it.

Good Luck!

EDIT: Elementname might work as well.

Upvotes: 0

Related Questions