簡體   English   中英

Wpf 使用 MvvmCross 的多個嵌套用戶控件

[英]Wpf Multiple nested Usercontrols with MvvmCross

我是MvvmCross的新手,但我正在使用mvvm一段時間。 我知道如何用嵌套的用戶控件組合用戶控件。 現在使用mvvmcross我被困在另一個用戶控件中顯示兩個或多個用戶控件。 除了MvvmCross之外,我不使用任何其他框架。 我的 Rootview 看起來像這樣:

`<views:MvxWpfView
    x:Class="MvvmCrossTest.Wpf.Views.RootView"
    xmlns:views="clr-namespace:MvvmCross.Platforms.Wpf.Views;assembly=MvvmCross.Platforms.Wpf"
    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" 
    mc:Ignorable="d" 
    d:DesignHeight="450" d:DesignWidth="800">

    <DockPanel>  
        <TextBlock Text="Root" DockPanel.Dock="Top"/>
        <ContentControl x:Name="MainMenuVM" Content="{Binding MainMenuVM}" DockPanel.Dock="Top" />
    </DockPanel>
</views:MvxWpfView>`

對應的 ViewModel 如下所示:

using MvvmCross.Commands;
using MvvmCross.Logging;
using MvvmCross.Navigation;
using MvvmCross.ViewModels;

namespace MvvmCrossTest.Core.ViewModels
{
    public class RootViewModel: MvxNavigationViewModel
    {
        private readonly IMvxViewModelLoader _mvxViewModelLoader;
        public RootViewModel(IMvxLogProvider logProvider, IMvxNavigationService navigationService, IMvxViewModelLoader mvxViewModelLoader) : base(logProvider, navigationService)
        {
            _mvxViewModelLoader = mvxViewModelLoader;
            ShowMainMenu();
        }

        private MainMenuViewModel _mainMenuVM;

        public MainMenuViewModel MainMenuVM
        {
            get { return _mainMenuVM; }
            set 
            {
                SetProperty(ref _mainMenuVM, value);
                RaisePropertyChanged(() => MainMenuVM);
            }
        }

         public MvxCommand ShowMainMenuCommand { get; set; }

        public void ShowMainMenu()
        {
            MainMenuVM = (MainMenuViewModel)_mvxViewModelLoader.LoadViewModel(MvxViewModelRequest.GetDefaultRequest(typeof(MainMenuViewModel)), null, null);
        }
    }
}

我想在 contentcontrol 中顯示的簡化視圖如下所示:

<views:MvxWpfView
    x:Class="MvvmCrossTest.Wpf.Views.MainMenuView"
    xmlns:views="clr-namespace:MvvmCross.Platforms.Wpf.Views;assembly=MvvmCross.Platforms.Wpf"
    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" 
    mc:Ignorable="d"
    Background="Aqua"
    d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
            
    </Grid>
</views:MvxWpfView>

還有對應的ViewModel。

using MvvmCross.Logging;
using MvvmCross.Navigation;
using MvvmCross.ViewModels;

namespace MvvmCrossTest.Core.ViewModels
{
    public class MainMenuViewModel : MvxNavigationViewModel
    {
        public MainMenuViewModel(IMvxLogProvider logProvider, IMvxNavigationService navigationService) : base(logProvider, navigationService)
        {

        }
    }
}

我看到的不是 View/ViewModel,而是一條顯示“MvvmCrossTest.Core.ViewModels.MainMenuViewModel”的文本。

我不想使用 Xamarin!

似乎 MvvmCross 正在自動連接 Views 和 ViewModels

我對 MvvmCross 一無所知,但為了“自動”工作,應該有一個協議和規則,例如屬性或匹配名稱(xViewModel <-> xView)。 目前,我看不到什么將MainMenuViewModelviews:MvxWpfView連接起來。

無論如何你所看到的

我看到一條顯示“MvvmCrossTest.Core.ViewModels.MainMenuViewModel”的文字

是由於缺少數據模板而試圖將非控制可視化為文本的視圖。

只需添加數據模板即可輕松修復

<DataTemplate DataType="{x:Type local:MainMenuViewModel}">
    <views:MvxWpfView />
</DataTemplate>

某處(例如進入views:MvxWpfView.Resources )並且將顯示視圖。

我創建了一個項目,向您展示了一些基礎知識。

簡單的

您可以在此處找到示例。

RootView

<views:MvxWpfView xmlns:local="clr-namespace:SomeProject.Views" ...>
     <Grid>
           <Label Content="Hello from RootView" />
           <local:NestedView />    
     </Grid>
</views:MvxWpfView>

NestedView

<views:MvxWpfView ...>
     <Grid>
           <Label Content="Hello from NestedView" />  
     </Grid>
</views:MvxWpfView>

擴展(自定義演示者)

使用此自定義 wpf 演示器,您可以在容器中指定視圖時輕松導航到視圖。 這樣,您可以在使用 mvvmcross 導航服務時從視圖 model 關閉和打開視圖。

我從另一個項目中復制了這個。 您可以在我示例項目中找到整個實現。

RootView

<views:MvxWpfView ...>
      <Grid>
           <Label Content="Hello" />
           <ItemsControl region:MvxContainer.Id="RootViewRegion"/>    
      </Grid>
</views:MvxWpfView>

背后的RootView代碼;

[MvxContentPagePresentation(WrapInNavigationPage = true, NoHistory = false)]
public partial class RootView: MvxWpfView<RootViewModel>
{
     public RootView()
     {
          InitializeComponent();
     }
}

RootViewModel

public class RootViewModel: MvxNavigationViewModel
{
      private readonly IMvxNavigationService _navigationService;

      public IMvxAsyncCommand ShowNestedViewModelCommand { get; protected set; }

      public RootViewModel(IMvxLogProvider logProvider, IMvxNavigationService navigationService) : base(logProvider, navigationService)
      {
            this._navigationService = navigationService;
    
            // navigate to nested view
            this.ShowNestedViewModelCommand = new MvxAsyncCommand(() => this._navigationService.Navigate<NestedViewModel>());

            ShowNestedViewModelCommand.Execute();
      }
}

后面的NestedView代碼;

[MvxWpfPresenter("RootViewRegion", mvxViewPosition.NewOrExsist)]
public partial class NestedView : MvxWpfView<NestedViewModel>
{
    public NestedView()
    {
        InitializeComponent();
    }
}

很高興知道

當您在導航和查看 model 連接時遇到問題時,請使用此代碼。 它加載特定視圖的視圖模型;

[MvxContentPagePresentation(WrapInNavigationPage = true, NoHistory = false)]
public partial class SomeView : MvxWpfView<ViewModels.SomeViewModel>
{
    public SomeView()
    {
         InitializeComponent();
    
         if (!(ViewModel is ViewModels.SomeViewModel))
         {
              if (Mvx.IoCProvider.TryResolve<ViewModels.SomeViewModel>(out var someViewModel))
              {
                   ViewModel = someViewModel;
                   return;
              }
    
              var _viewModelLoader = Mvx.IoCProvider.Resolve<IMvxViewModelLoader>();
              var request = new MvxViewModelInstanceRequest(typeof(ViewModels.SomeViewModel));
              request.ViewModelInstance = _viewModelLoader.LoadViewModel(request, null);
              ViewModel = request.ViewModelInstance as ViewModels.SomeViewModel;
    
              Mvx.IoCProvider.RegisterSingleton<ViewModels.SomeViewModel>(ViewModel);
         }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM