gpt4 book ai didi

mvvm - ViewModel 之间的通信

转载 作者:行者123 更新时间:2023-12-03 10:50:45 25 4
gpt4 key购买 nike

关于 ViewModel 之间的通信,我有两个问题。

我正在开发一个客户管理程序。我正在使用 Laurent Bugnion 的 MVVM Light 框架。

  • 在主页上,有一个客户列表。单击每个客户时,会显示一个子窗口,其中包含有关该客户的信息。用户应该能够同时打开多个子窗口并比较客户之间的信息。如何以 MVVM 友好的方式将客户对象从主页的 ViewModel 传递到子窗口的 ViewModel?
  • 在显示客户信息的子窗口中,有许多选项卡,每个选项卡显示不同的信息区域。我为每个选项卡创建了单独的 ViewModel。您如何在每个选项卡的 View 模型之间共享当前的客户信息?

  • 非常感谢!

    最佳答案

    在我的项目中,我也将 ViewModels 传递给子窗口。我在后面的子窗口代码中为 ViewModel 创建了一个依赖属性,在这个属性的 setter 中,我将 ViewModel 传递给我的子窗口的 ViewModel。这意味着您正在为您的子窗口创建一个单独的 ViewModel 类。

    要回答您的第二个问题,您可以让子窗口的 ViewModel 包含每个选项卡关心的属性,但它们的数据上下文仍然与子窗口的数据上下文相同,因此它们可以访问共享属性。这实际上非常简单,因为它们会自动获取子窗口的数据上下文。

    这是一个说明上述两个概念的示例。

    子窗口 View 详细信息Window.xaml (请注意,我已经养成了将子窗口 View 命名为 *Window.xaml 而不是 *View.xaml 的习惯)

    <controls:ChildWindow x:Class="DetailsWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
    xmlns:Views="clr-namespace:Views"
    Title="Details"
    DataContext="{Binding DetailsWindowViewModel, Source={StaticResource Locator}}"
    >
    <Grid>
    <sdk:TabControl>
    <sdk:TabItem Header="First Tab" Content="{Binding FirstTabContent}" />
    <sdk:TabItem Header="Second Tab" Content="{Binding SecondTabContent}" />
    </sdk:TabControl>
    </Grid>
    </controls:ChildWindow>

    后面的子窗口 View 的代码详细信息Window.xaml.cs 及其接口(interface) IDetailsWindow.cs
    public partial class DetailsWindow : ChildWindow, IDetailsWindow
    {
    private IDetailsWindowViewModel ViewModel
    {
    get { return this.DataContext as IDetailsWindowViewModel; }
    }

    public DetailsWindow()
    {
    InitializeComponent();
    }

    #region Customer dependency property

    public const string CustomerViewModelPropertyName = "Customer";

    public ICustomerViewModel Customer
    {
    get
    {
    return (ICustomerViewModel)GetValue(CustomerViewModelProperty);
    }
    set
    {
    SetValue(CustomerViewModelProperty, value);
    if (ViewModel != null)
    {
    ViewModel.Customer = value;
    }
    }
    }

    public static readonly DependencyProperty CustomerViewModelProperty = DependencyProperty.Register(
    CustomerViewModelPropertyName,
    typeof(ICustomerViewModel),
    typeof(CustomerDetailsWindow),
    null);

    #endregion
    }

    public interface IDetailsWindow
    {
    ICustomerViewModel Customer { get; set; }
    void Show();
    }

    子窗口 View 模型 详细信息WindowViewModel.cs 及其接口(interface) IDetailsWindowViewModel
    public class DetailsWindowViewModel : ViewModelBase, IDetailsWindowViewModel
    {
    public DetailsWindowViewModel(IMessenger messenger)
    : base(messenger)
    {
    }

    #region Properties

    #region Customer Property

    public const string CustomerPropertyName = "Customer";

    private ICustomerViewModel _customer;

    public ICustomerViewModel Customer
    {
    get { return _customer; }
    set
    {
    if (_customer == value)
    return;

    var oldValue = _customer;
    _customer = value;
    RaisePropertyChanged(CustomerPropertyName, oldValue, value, true);
    }
    }

    #endregion

    #region FirstTabContent Property

    public const string FirstTabContentPropertyName = "FirstTabContent";

    private FrameworkElement _firstTabContent;

    public FrameworkElement FirstTabContent
    {
    get { return _firstTabContent; }
    set
    {
    if (_firstTabContent == value)
    return;

    _firstTabContent = value;
    RaisePropertyChanged(FirstTabContentPropertyName);
    }
    }

    #endregion

    #region SecondTabContent Property

    public const string SecondTabContentPropertyName = "SecondTabContent";

    private FrameworkElement _secondTabContent;

    public FrameworkElement SecondTabContent
    {
    get { return _secondTabContent; }
    set
    {
    if (_secondTabContent == value)
    return;

    _secondTabContent = value;
    RaisePropertyChanged(SecondTabContentPropertyName);
    }
    }

    #endregion

    #endregion
    }

    public interface IDetailsWindowViewModel
    {
    ICustomerViewModel Customer { get; set; }
    FrameworkElement FirstTabContent { get; set; }
    FrameworkElement SecondTabContent { get; set; }

    void Cleanup();
    }

    您可以从您的 中显示子窗口MainPageViewModel.cs 像这样。
    public class MainViewModel : ViewModelBase, IMainViewModel
    {
    private readonly IDetailsWindow _detailsWindow;

    public MainViewModel(IMessenger messenger, IDetailsWindow DetailsWindow)
    : base(messenger)
    {
    _detailsWindow = DetailsWindow;
    }

    private void DisplayCustomerDetails(ICustomerViewModel customerToDisplay)
    {
    _detailsWindow.Customer = customerToDisplay;
    _detailsWindow.Show();
    }
    }

    请注意,我为所有 View 模型和子窗口创建接口(interface),并在 ViewModelLocator 中使用 DI/IoC 容器,以便为我注入(inject)所有 ViewModel 的依赖项。你不必这样做,但我喜欢它的工作方式。

    关于mvvm - ViewModel 之间的通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3808901/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com