You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF MVVM下新建View并向ViewModel传递参数的技术问题

Solution for Passing Parameter from View to ViewModel in WPF MVVM

First, let's fix a critical bug in your BasePage class that would cause a stack overflow: the ViewModel property's getter is returning itself instead of the backing field mViewModel. Here's the corrected version:

public class BasePage<VM> : Page where VM : BaseViewModel, new() {
    private VM mViewModel;
    public VM ViewModel {
        get { return mViewModel; } // Fixed: return the backing field, not the property itself
        set {
            if (mViewModel == value) return;
            mViewModel = value;
            this.DataContext = mViewModel;
        }
    }

    public BasePage() {
        this.Resources = ((MainWindow)Application.Current.MainWindow).Resources;
        this.ViewModel = new VM();
    }

    // Optional: Add a constructor to accept a pre-initialized ViewModel
    public BasePage(VM viewModel) {
        this.Resources = ((MainWindow)Application.Current.MainWindow).Resources;
        this.ViewModel = viewModel;
    }
}

Now, let's tackle passing the position parameter to your DetailedViewViewModel's PossitionShown property. Here are two clean approaches:

Approach 1: Directly Assign the Property in the View's Constructor

This is the simplest solution for your current setup. Since the BasePage constructor already initializes the ViewModel, you can just set the property right after calling InitializeComponent:

namespace unnamed {
    public partial class DetailedViewPage : BasePage<DetailedViewViewModel> {
        public DetailedViewPage(string position) : base() {
            InitializeComponent();
            // Assign the position directly to the ViewModel's property
            ViewModel.PossitionShown = position;
        }
    }

    // Your existing window creation code stays the same
    private void CreateNewWindow() {
        var MainWindow = (MainWindow) Application.Current.MainWindow;
        var MWViewModel = (WindowViewModel) MainWindow.DataContext;
        MWViewModel.CurrentPage = new DetailedViewPage("top");
    }
}

Approach 2: Initialize the ViewModel with a Parameter (More MVVM-Friendly)

If you prefer to keep ViewModel initialization logic within the ViewModel itself, add a parameterized constructor to DetailedViewViewModel and use the overloaded BasePage constructor we added earlier:

Step 1: Update the ViewModel with a Parameterized Constructor

namespace unnamed {
    public class DetailedViewViewModel : BaseViewModel {
        public string PossitionShown { get; set; }

        // Add a constructor that accepts the position parameter
        public DetailedViewViewModel(string position) {
            PossitionShown = position;
        }

        // Keep the default constructor if you still need it for other cases
        public DetailedViewViewModel() {}
    }
}

Step 2: Modify the View to Use the Pre-Initialized ViewModel

namespace unnamed {
    public partial class DetailedViewPage : BasePage<DetailedViewViewModel> {
        public DetailedViewPage(string position) 
            : base(new DetailedViewViewModel(position)) { // Pass the initialized VM to BasePage
            InitializeComponent();
        }
    }
}

Both approaches work well—choose the one that fits your project's structure. The second approach is more aligned with MVVM principles since it lets the ViewModel handle its own initialization, while the first is quicker for simple scenarios.


内容的提问来源于stack exchange,提问作者jurgis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:37:50