1

I haven't found this anywhere. Currently I'm making a WPF app and I ran into a problem. I need one page but data should be different depending on which button summoned the page. It would be kind of easy if not trying to stick with MVVM. I already have a button that passes needed data to the page cs file but I have no idea how to pass that data to the ViewModel.

DetailedViewPage.xaml.cs:

namespace unnamed
{
    public partial class DetailedViewPage : BasePage<DetailedViewViewModel>
    {    
        public DetailedViewPage(string position)
        {    
            InitializeComponent();
        }
    }


    //I'm using similar method to create new View
    private void CreateNewWindow()
    {
        var MainWindow = (MainWindow) Application.Current.MainWindow;
        var MWViewModel = (WindowViewModel) MainWindow.DataContext;
        MWViewModel.CurrentPage = new DetailedViewPage("top");
    }

}

BasePage.cs:

public class BasePage<VM> : Page
        where VM : BaseViewModel, new()
    {

        private VM mViewModel;

        public VM ViewModel
        {
            get { return ViewModel; }
            set
            {
                if (mViewModel == value)
                    return;
                mViewModel = value;
                this.DataContext = mViewModel;
            }
        }

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

DetailedViewViewModel.cs:

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

        public DetailedViewViewModel()
        {                
        }    
    }
}

So my goal here is to get that position variable from the page cs file to the ViewModel and assign to PossitionShown.

jurgis
  • 55
  • 1
  • 6
  • 1
    How do You creating new page? Please provide code for that. – Tatranskymedved May 09 '18 at 11:17
  • It is basicly one line of code that goes like this `((WindowViewModel)((MainWindow)Application.Current.MainWindow).DataContext).CurrentPage = new DetailedViewPage("top");` – jurgis May 09 '18 at 11:22

1 Answers1

1

Your view (DetailedViewPage) has a DataContext, which is the DetailedViewViewModel.

DataContext can be either created automatically via default constructor (when entered in XAML) or it should be created in constructor. Basically, after creation of the view, we can just simply set the value to it.

public DetailedViewPage(string position)
{
    InitializeComponent();

    //optional line, if not set in XAML
    this.DataContext = new DetailedViewViewModel();

    var VM = (this.DataContext as DetailedViewModel);
    VM.PossitionShown = position;
}

Edit: Adding the code to pass the variable at the ViewModel construction.

public DetailedViewPage(string position)
{
    InitializeComponent();
    //Note this line is not "optional" anymore, You must pass the value as a variable.
    this.DataContext = new DetailedViewViewModel(position);
}

public class DetailedViewViewModel : BaseViewModel
{
    public string PossitionShown { get; set; }
    public DetailedViewViewModel(string position)
    {
        PossitionShown = position;
    }
}

As a side note, this is not fully MVVM approach, as You are already passing some arguments via View, and View is considering that there is existing some type of ViewModel.

On this topic, I recommend going through:

Tatranskymedved
  • 4,194
  • 3
  • 21
  • 47
  • Interesting. I've tried quite similar approach but it didn't work, while yours works i'm gonna dig in to that. But I'm not completely satisfied yet. I don't have that variable when I'm initiating `DetailedViewViewModel`, program only sets the value after `DetailedViewViewModelis` done creating, but I need the value in the constructor. – jurgis May 09 '18 at 13:28
  • I get an error while trying to create a viewmodel `'DetailedViewViewModel' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'VM' in the generic type or method 'BasePage'` I believe that I should change something in my BasePage class but not sure what. – jurgis May 11 '18 at 05:40
  • Well it clearly states that `DetailedViewViewModel` must have parameterless constructor, as it is referenced somewhere where it's required (maybe in XAML). – Tatranskymedved May 11 '18 at 07:17
  • Finally works!!! Thank you very much for your help, although it was quite simple stuff but it really helped :) – jurgis May 11 '18 at 08:24