bakunet
bakunet

Reputation: 197

How do I call Button command from inside of ListBox.ItemTemplate DataTemplate, to pass parameter without selecting ListBox item?

I have a problem, that I am facing for a few hours already. Inside of my xaml view I am having a ListBox, that defines DataTemplate as follows:

<DataTemplate>
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height ="30"/>
                            <RowDefinition Height ="30"/>
                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="*" />
                        </Grid.ColumnDefinitions>

                        <!--Row 0-->
                        <TextBlock Grid.Column="0"
                                       Grid.Row="0"
                                       Style="{StaticResource racetblk}">
                                    Horse name
                        </TextBlock>
                        <TextBlock Grid.Column="1"
                                       Grid.Row="0"
                                       Style="{StaticResource racetblk}">
                                    Horse DOB
                        </TextBlock>

                        <!--Row 1-->
                        <StackPanel Orientation="Horizontal"
                                    Grid.Row="1"
                                    Grid.Column="0">
                            <TextBox Text="{Binding Path=HorseName, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"
                                 Style="{StaticResource tableItem}"
                                 Height="20"
                                     Width="150"/>
                            <Button Width="50"
                                Margin="5"
                                Height="20"
                                Content="Pick"
                                Background=" #a1c883 "
                                Foreground="White"
                                Command="{Binding PickHorseDataCommand}"
                                CommandParameter="{Binding ElementName=lbHorseList, Path=SelectedIndex}"/>
                        </StackPanel>
                        <TextBox Text="{Binding Path=Birth, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"
                                 Grid.Row="1"
                                 Grid.Column="1"
                                 Style="{StaticResource tableItem}"
                                 Height="20"/>
                    </Grid>

                </DataTemplate>

Inside of the template <!--Row 1--> I have a button, that supposed to trigger command inside of my ViewModel command supposed to be trigerred after typing text inside of a TextBox:

private ICommand pickHorseDataCommand;
        public ICommand PickHorseDataCommand
        {
            get
            {
                if (pickHorseDataCommand == null)
                    pickHorseDataCommand = new RelayCommand(
                    o =>
                    {
                        int horseIndex = (int)o;
                        HorseDataWrapper horse = Horses[horseIndex];
                        LoadedHorse horseFromList = allHorses.Where(i => i.Name == horse.HorseName).FirstOrDefault();
                        horse.Birth = horseFromList.Birth.ToString();
                        var dupa = horse;
                    });
                return pickHorseDataCommand;
            }
        }

There are two problems with this. First of all, the command is not trigerred at all, I belive, that I supposed to bind the command somehow using RelativeSource, but until now I did not managed to do it.

Another thing is, that CommandParameter is binded to SelectedIndex, so the ListBox item have to be selected when pushing the button, to make the binding come true. I could not find any other solution to do the binding without selecting the item. Maybe you have any alternatives?

I appreciate your time and help.

Upvotes: 0

Views: 349

Answers (2)

mm8
mm8

Reputation: 169390

If the command is defined in the view model, you could bind to it like this:

Command="{Binding DataContext.PickHorseDataCommand, RelativeSource={RelativeSource AncestorType=ListBox}}"

If you need the SelectedIndex in the view model, you should define a source property and bind the ListBox's SelectedIndex property to this one instead of using a CommandParameter:

<ListBox SelectedIndex="{Binding YourIndexProperty}" ... />

The Execute method of the command can then access the index property directly:

int index = this.YourIndexProperty;

Another option may be to pass a reference to the current item itself, instead of using the index, as a parameter to the command:

CommandParameter="{Binding}"

Upvotes: 1

Avinash Reddy
Avinash Reddy

Reputation: 937

You can do something like this AncestorType need to be specified

Command="{Binding DataContext.pickHorseDataCommand,RelativeSource={RelativeSource AncestorType=,Mode=FindAncestor}}"

Upvotes: 0

Related Questions