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

问题描述

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

我目前拥有的:

带有 DataContext MainWindowviewmodel 的 MainWindow。 带有 DataContext SecondPageviewmodel 的 SecondPage(用户控件)。

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

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

我想要做的是能够使用用户控件中的 StudentListView 作为我的主窗口中命令 ReturnPressCommand 的命令参数。

我该如何实现?

主窗口:

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

主窗口的视图模型

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>

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...