WPF - window 的数据上下文中的命令和用户控件中列表视图中的命令参数

WPF - Command in datacontext of the window and commandparameter from listview in user control

我在按照 MVVM 模式获取 WPF 应用程序中的命令绑定时遇到了一些麻烦。

我目前拥有的:

带有 DataContext MainWindowViewModel 的主窗口。 具有 DataContext SecondPageView 模型的 SecondPage(用户控件)。

用户控件仅包含一个名为 StudentListView 的列表视图,绑定到 SecondPageViewModel 中的可观察集合。

主 window 有一个文本框,在其中按回车键将触发我的命令,称为 ReturnPressCommand,它位于 MainWindowViewModel 中。主 window 还包含一个 SecondPage 用户控件的实例。

我想做的是能够使用用户控件中的 StudentListView 作为我 Main window.

中命令 ReturnPressCommand 的命令参数

我该如何完成?

主要window:

<Window x:Class="MVVMTEST.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:MVVMTEST.ViewModels"
        xmlns:control="clr-namespace:MVVMTEST.Views"
        mc:Ignorable="d"
        Title="MainWindow" Height="800" Width="1600" WindowStartupLocation="CenterScreen">
    <Window.DataContext>
        <local:MainWindowViewModel />
    </Window.DataContext>

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>

        <TextBox Grid.Column="0" Grid.Row="0" Width="120" Height="20">
            <TextBox.InputBindings>
                <KeyBinding Key="Return" 
                            Command="{Binding Path=ReturnPressCommand}" 
                            CommandParameter="{}"/>
            </TextBox.InputBindings>
        </TextBox>

        <control:SecondPage x:Name="SecondPageX" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2" Width="auto" Visibility="Visible"></control:SecondPage>
    </Grid>
</Window>

主要的视图模型window

using MVVMTEST.Commands;
using System.Windows.Input;

namespace MVVMTEST.ViewModels
{
    class MainWindowViewModel
    {
        public MainWindowViewModel()
        {
            
        }

        private ICommand _returnPressCommand = null;
        public ICommand ReturnPressCommand
        {
            get
            {
                if (_returnPressCommand == null)
                    _returnPressCommand = new ReturnPressCommand();
                return _returnPressCommand;
            }
        }
    }
}

我要执行的命令

namespace MVVMTEST.Commands
{
    class ReturnPressCommand : CommandBase
    {
        public override bool CanExecute(object parameter)
        {
            return true;
        }

        public override void Execute(object parameter)
        {
            // Do operations with the observable collection
        }
    }
}

用户控件

<UserControl x:Class="MVVMTEST.Views.SecondPage"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:MVVMTEST.ViewModels"
             mc:Ignorable="d" 
             d:DesignHeight="400" d:DesignWidth="1600">

    <UserControl.DataContext>
        <local:SecondPageViewModel />
    </UserControl.DataContext>

    <Grid Background="Green">
        <ListView Grid.Column="0" Grid.Row="0" x:Name="StudentListView" ItemsSource="{Binding Students}">
            <ListView.View>
                <GridView>
                    <GridViewColumn DisplayMemberBinding="{Binding Name}" Header="Name"></GridViewColumn>
                    <GridViewColumn DisplayMemberBinding="{Binding Age}" Header="Age"></GridViewColumn>
                    <GridViewColumn DisplayMemberBinding="{Binding Gpa}" Header="Gpa"></GridViewColumn>
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>
</UserControl>

用户控件的视图模型

using System.Collections.Generic;
using System.Collections.ObjectModel;
using MVVMTEST.Models;

namespace MVVMTEST.ViewModels
{
    public class SecondPageViewModel
    {
        public IList<Student> Students { get; } = new ObservableCollection<Student>();
        public SecondPageViewModel()
        {
            Students.Add(new Student { Name = "Firstname Lastname", Age = 25, Gpa = 0.0 });
        }
    }
}

我希望文本框始终可见,但将来我计划添加更多用户控件,它们的可见性将根据用户在应用程序中的操作而改变。现在我想实现一个搜索功能来过滤位于用户控件的视图模型中的可观察集合中的学生。然后用户控件将列出这些过滤的学生。

您可以通过用户控件的名称将 CommandParameter 绑定到集合。

<TextBox Grid.Column="0" Grid.Row="0" Width="120" Height="20">
            <TextBox.InputBindings>
                <KeyBinding Key="Return" 
                            Command="{Binding Path=ReturnPressCommand}" 
                            CommandParameter="{Binding DataContext.Students, ElementName=SecondPageX}" />
            </TextBox.InputBindings>
</TextBox>