打开视图并传递数据的最简单方法

问题描述 投票:0回答:1

我有一个用户需求:选择列表中的一个项目。单击一个按钮。对话模式窗口打开,显示该项目的详细信息(后面的窗口不会消失)。

因此,我试图找到从第一个视图打开第二个视图并传递有关在绑定的 DataGrid 中选择哪个项目的信息的最简单方法。我在 Microsoft 网站上找到了一个有关从 ViewModel 打开视图的示例,该示例非常简单here,但它不包含传递 DataGrid 中所选项目的机制。我可以使用此代码,但我不知道如何获取所选项目。

来自 winforms,等效的解决方案可能像这样简单:

EditForm frm = new EditForm(lvw.SelectedItem[0].Text);

目前,我正在寻找一个具有最少数量的库/框架/服务/抽象的解决方案,以便我能够真正理解正在发生的事情。

因此我的问题是,如何在调用 ViewModel 中以最简单的方式提供有关在 DataGrid 中选择哪个项目的信息,并将其传递给辅助 View/ViewModel 对,以便我可以使用它加载模型并将视图绑定到它。

c# wpf mvvm
1个回答
0
投票

将 ViewModel 的数据模板整齐地放置在 App.xaml 中怎么样:

    <DataTemplate DataType="DataType="{x:Type vm:MainViewModel}"">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <Menu IsMainMenu="True" ItemsSource="{Binding MenuItems}">
                <Menu.ItemContainerStyle>
                    <Style TargetType="MenuItem">
                        <Setter Property="Header" Value="{Binding HeaderText}"/>
                        <Setter Property="Command" Value="{Binding ExecuteCommand}"/>
                    </Style>
                </Menu.ItemContainerStyle>
            </Menu>
            <ListView ItemsSource="{Binding People}" Grid.ColumnSpan="2" Grid.Row="1" VirtualizingPanel.IsVirtualizing="True" VirtualizingPanel.VirtualizationMode="Recycling" SelectedItem="{Binding SelectedPerson}">
                <ListView.ItemTemplate>
                    <DataTemplate DataType="{x:Type vm:PersonViewModel}">
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition/>
                                <ColumnDefinition/>
                            </Grid.ColumnDefinitions>
                            <TextBlock Text="{Binding Title}"/>
                            <Button Content="Open Details" Command="{Binding OpenMoreDetailsCommand}" Grid.Column="1"/>
                        </Grid>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
            <ProgressBar Value="{Binding Progress}" Grid.Row="2" Maximum="1" LargeChange="0.1" SmallChange="0.01"/>
            <TextBlock Text="{Binding Progress, StringFormat=\{0:P\}}" Grid.Row="2"/>
            <TextBlock Text="{Binding Progress, StringFormat=\{0:C\}}" Grid.Row="2" HorizontalAlignment="Right"/>
            <Button Content="Populate people" Grid.Column="2" Grid.Row="2" Command="{Binding PopulatePeople}"/>
        </Grid>
    </DataTemplate>  

然后要在窗口中显示您的模板,您只需使用以下命令:

<Window x:Class="WPF_Prototyping.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:WPF_Prototyping"
    xmlns:vm="clr-namespace:WPF_Prototyping.ViewModels"
    xmlns:models="clr-namespace:WPF_Prototyping.Models"
    xmlns:views="clr-namespace:WPF_Prototyping.Views"
    mc:Ignorable="d"
    Title="MainWindow" Height="549" Width="558">
    <ContentControl Content="{Binding .}"/>
</Window>

现在假设这个窗口名为 GenericModalWindow,我们可以在服务中使用它:

public class WindowService : IWindowService
{
    public bool? ShowDialog(BaseViewModel bvm)
    {
        var wnd = new GenericModalWindow
        {
            DataContext = bvm
        };
        return wnd.ShowDialog();
    }
}  

地点:

public interface IWindowService
{
    bool? ShowDialog(BaseViewModel bvm);
}  

现在您看到了,您的 ListView 的 SelectedItem(如数据模板中的 SelectedItem)已绑定其选定项,因此我们可以轻松地在代码中使用它。我们来看看 Person View Model:

public class PersonViewModel : BaseViewModel
{
    public PersonViewModel()
    {
        WindowService = new WindowService();
        OpenMoreDetailsCommand = new DelegateCommand(OpenMoreDetails);
    }

    public PersonViewModel(Person p) : this()
    {
        Person = p;
    }

    private void OpenMoreDetails()
    {
        WindowService.ShowDialog(this);
    }

    private Person _person;

    public Person Person
    {
        get { return _person; }
        set
        {
            _person = value;
            OnPropertyChanged();
        }
    }

    public IWindowService WindowService { get; set; }
    public IDelegateCommand OpenMoreDetailsCommand { get; set; }
}  

正如您所看到的,除了分离此功能之外,实际上没有发生任何事情,因此更容易让人们开始使用名为 WPF 的框架。这是最好的部分,您的通用模态窗口看起来与主窗口完全相同。没有框架,没有额外的依赖项,纯 xaml 和 MvvM,您还可以轻松测试这些视图模型,并使用您想要的任何内容作为该窗口的参数,只要它是基本视图模型即可。尝试一下,看看你能做什么。一旦您了解了 WPF 的功能,您将永远不会以同样的方式回顾 WinForms。还有一个提示,不要在视图模型中放置任何 UI 元素,例如用于所选项目绑定的 ListViewItem 或 ComboBoxItem,因为它不起作用,并且您无法真正测试此类代码。快乐编码:-)

© www.soinside.com 2019 - 2024. All rights reserved.