如何从ListBox.ItemTemplate DataTemplate内部调用Button命令来传递参数而不选择ListBox项?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何从ListBox.ItemTemplate DataTemplate内部调用Button命令来传递参数而不选择ListBox项?相关的知识,希望对你有一定的参考价值。

我有一个问题,我已经面对了几个小时。在我的xaml视图中,我有一个ListBox,它定义DataTemplate如下:

<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>

在模板<!--Row 1-->里面我有一个按钮,它应该在我的ViewModel命令中触发命令,在TextBox中键入文本之后应该是trigerred:

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;
            }
        }

这有两个问题。首先,该命令根本没有触发,我相信,我应该使用RelativeSource以某种方式绑定命令,但直到现在我还没有设法做到这一点。

另一件事是,CommandParameter绑定到SelectedIndex,因此在按下按钮时必须选择ListBox项目,以使绑定成为现实。在没有选择项目的情况下,我找不到任何其他解决方案来进行绑定。也许你还有其他选择吗?

感谢您的时间和帮助。

答案

你可以这样做,需要指定AncestorType

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

另一答案

如果在视图模型中定义了该命令,则可以像这样绑定它:

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

如果在视图模型中需要SelectedIndex,则应定义源属性并将ListBoxSelectedIndex属性绑定到此属性,而不是使用CommandParameter

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

然后命令的Execute方法可以直接访问index属性:

int index = this.YourIndexProperty;

另一个选项可能是将引用传递给当前项本身,而不是使用索引作为命令的参数:

CommandParameter="{Binding}"

以上是关于如何从ListBox.ItemTemplate DataTemplate内部调用Button命令来传递参数而不选择ListBox项?的主要内容,如果未能解决你的问题,请参考以下文章

如何在自定义用户控件中为 ListBox ItemTemplate 属性设置适当的上下文

将ListBlock置于ListBox.ItemTemplate中

如何将ListBox项绑定到用户控件上?

如何将字符串列表数据绑定到 WPF/WP7 中的 ListBox?

windows phone listbox的点击事件

关于 ListBox 自动换行