如何基于MvxViewModelRequest为UWP创建视图?
Hey there! Let's tackle this problem you're facing with MvvmCross in UWP. I’ve worked with exactly these versions of MvvmCross and UWP before, so here’s a practical solution to replicate that WPF-style view creation behavior:
MvxViewModelRequest in UWP with MvvmCross 5.6.3 Unlike WPF, UWP doesn’t have a built-in IMvxSimpleWpfViewLoader, but we can build a equivalent by leveraging MvvmCross’s core view-model mapping and view loading systems. Here’s step-by-step how to do it:
1. Create a Custom View Loader Interface and Implementation
First, we’ll make a reusable loader that mimics the WPF behavior, returning a FrameworkElement (which all UWP views inherit from):
public interface IMvxSimpleUwpViewLoader { FrameworkElement CreateView(MvxViewModelRequest request); } public class MvxSimpleUwpViewLoader : IMvxSimpleUwpViewLoader { public FrameworkElement CreateView(MvxViewModelRequest request) { // Step 1: Get the corresponding view type for the view model var viewsContainer = Mvx.Resolve<IMvxViewsContainer>(); var viewType = viewsContainer.GetViewType(request.ViewModelType); if (viewType == null) throw new MvxException($"No matching view found for {request.ViewModelType.Name}"); // Step 2: Instantiate the view var view = Activator.CreateInstance(viewType) as FrameworkElement; if (view == null) throw new MvxException($"Failed to create instance of view type {viewType.Name}"); // Step 3: Load the view model and link it to the view var viewModelLoader = Mvx.Resolve<IMvxViewModelLoader>(); var viewModel = viewModelLoader.LoadViewModel(request, null); // Use MvvmCross's built-in view interface if available (most UWP views inherit from MvxWindowsPage/UserControl) if (view is IMvxWindowsView mvxView) { mvxView.ViewModel = viewModel; } else { // Fallback to setting DataContext directly for custom views view.DataContext = viewModel; } return view; } }
2. Register the Loader in Your Setup Class
Open your Setup.cs file (usually in your UWP project) and register the loader in the final initialization step:
protected override void InitializeLastChance() { base.InitializeLastChance(); Mvx.RegisterSingleton<IMvxSimpleUwpViewLoader>(new MvxSimpleUwpViewLoader()); }
3. Use It Just Like the WPF Implementation
Now you can call it exactly the way you did in WPF:
var request = new MvxViewModelRequest( viewModelType, parameterBundle, presentationBundle, null); var view = Mvx.Resolve<IMvxSimpleUwpViewLoader>().CreateView(request); // Add the view to your UWP page/container as needed // Example: MyGrid.Children.Add(view);
Key Notes for Your Environment
- Naming Conventions: Make sure your view and view model follow MvvmCross’s default naming rules (e.g.,
HomeViewModelmaps toHomePageorHomeView). If you need custom mappings, overrideGetViewTypein yourSetupclass or use the[MvxViewModel(typeof(YourViewType))]attribute on your view model. - ViewModel Initialization: Any parameters in
parameterBundlewill automatically be passed to your view model’sInitializemethod (if it implementsIMvxViewModel<TParameter>orIMvxAsyncViewModel). - Lifecycle: If your view inherits from
MvxWindowsPageorMvxWindowsUserControl, MvvmCross will handle lifecycle events likeViewAppearingandViewDisappearingautomatically once the view is added to the visual tree.
内容的提问来源于stack exchange,提问作者mazury

