Как правильно связать команду в моем пользовательском элементе управления WPF

Вот мой контроль:

<UserControl.Resources>
    <DataTemplate x:Key="ItemTemplate">
        <Border BorderThickness="0.5" BorderBrush="DarkGray">
            <Grid Height="30">
                <Grid.RowDefinitions>
                    <RowDefinition />
                    <RowDefinition />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>

                <CheckBox Command="{Binding DataContext.CheckCommand, RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}" Content="{Binding Name}" IsChecked="{Binding IsChecked}"  Grid.RowSpan="2" Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" Width="Auto"/>

                <Button Command="{Binding DataContext.UpCommand, RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}"
                                    Grid.Row="0" Grid.Column="1" HorizontalAlignment="Right" Margin="1" ToolTip="Up" BorderBrush="{x:Null}" Background="{x:Null}">
                    <Image Source="/Resources/Icons/sort_up.png"/>
                </Button>

                <Button 
                        Command="{Binding DataContext.DownCommand, RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}"
                        Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right" Margin="1" ToolTip="Down" BorderBrush="{x:Null}" Background="{x:Null}">
                    <Image Source="/Resources/Icons/sort_down.png"/>
                </Button>

            </Grid>
        </Border>
    </DataTemplate>
</UserControl.Resources>

И код в View Model включает это:

/// <summary>
    /// Moves item up in the custom list
    /// </summary>
    private void UpCommandExecuted()
    {
        if (SelectedItem != null)
        {
            StoredProc Proc = SelectedItem;
            int oldLocation = TheList.IndexOf(SelectedItem);
            if (oldLocation > 0)
            {
                if (SelectedItem.IsChecked || (TheList[oldLocation - 1].IsChecked == SelectedItem.IsChecked))
                {
                    TheList.RemoveAt(oldLocation);
                    TheList.Insert(oldLocation - 1, Proc);
                    SelectedItem = Proc;
                }
            }
        }
    }

у меня тоже есть SelectedItem свойство в ВМ, которое является StoredProcedure (типа я сделал) Это работает, но нажатие любой кнопки "Вверх" элемента списка вызывает действие SELECTEDITEM. Я действительно хочу, чтобы элемент списка, в котором я нажимал кнопку, действовал. Как я могу это сделать? Как мне сказать мой UpCommandExecuted() метод, чтобы действовать на ListBoxItem, где я нажал кнопку вверх, а не фактическое SelectedItem?

1 ответ

Решение

Попробуйте добавить CommandParameter={Binding} на ваш <Button>, Это передаст контекст данных выбранного элемента в вашу команду через ICommand.Execute метод.

В противном случае переместите свойства команды в модель, которая представляет элементы, вместо того, чтобы иметь единый набор команд, определенный на корневом уровне. Я лично предпочитаю такой подход. Мне нравится, что мои команды не содержат параметров и всегда действуют в классе модели представления, который содержит команду.

Другие вопросы по тегам