Binding ViewModel to multiple windows

后端 未结 4 803
醉话见心
醉话见心 2021-02-14 21:37

I\'m re-writing my windows forms project that does scoring for sheep shearing events (don\'t ask, its a huge sport in New Zealand) from vbnet to wpf c# and have struck a problem

相关标签:
4条回答
  • 2021-02-14 21:52

    Your viewmodel defines a static method to get a single instance but you do not use it to instantiate it. Currently your viewmodel is being created with the default constructor which means the two windows will have separate copies.

    Create your viewmodel in the code behind either below InitializeComponent or in the OnNavigatedToEvent.

    Here's some code to explain further:

    define a ViewModel property like so in both windows

    property SheepViewModel ViewModel { get; set; }
    

    Then your constructor:

    public MainWindow()
    {
        InitializeComponent();
        ViewModel = SheepViewModel.GetDetails(); // include this line
        ScoreScreen SW = new ScoreScreen();
        SW.Show();
    }
    

    also remove the

    <vm:SheepViewModel/>
    

    from the xaml as it's not required.

    0 讨论(0)
  • 2021-02-14 22:07

    I suspect that each window is creating its own instance of the ViewModel. You could try the following:

    public MainWindow()
    {
        InitializeComponent();
    
        SheepViewModel svm = new SheepViewModel();
        this.DataContext = svm;
    
        ScoreScreen SW = new ScoreScreen();
        SW.DataContext = svm;
        SW.Show();        
    }
    
    0 讨论(0)
  • 2021-02-14 22:08

    That's because both windows must share the exact same instance of the ViewModel.

    All your properties are instance properties, like

    public string CurrentEventName { get { // snip
    

    and therefore all values are distinct to each instance. You're creating two instances, one for each window.

    <Window x:Class="Sheep_Score_3._1.MainWindow"
        xmlns:blah="http://inurxamlskippinurschemas.org">
        <Window.DataContext>
            <vm:SheepViewModel/>
        </Window.DataContext>
    

    That's one instance, and here's the other

    <Window x:Class="Sheep_Score_3._1.ScoreScreen"
            xmlns:blah="http://yaddayaddawhocares.derp">
        <Window.DataContext>
            <vm:SheepViewModel/>
        </Window.DataContext>
    

    Remember, xaml is just markup that is deserialized into an object graph. You've got two different markup files, they contain distinct instances of everything described within them.

    There's nothing wrong with this, and nothing wrong with having a view model with instance properties. In fact, that's the preferred way over using statics and static bindings.

    The answer is luckily simple. You need to hand both windows the same instance of your view model.

    First, remove all the <Window.DataContext> nonsense from both of your windows. That's not for you. Now, simply change your constructor to

    public MainWindow()
    {
        var viewModel = new SheepViewModel();
        ScoreScreen SW = new ScoreScreen();
        SW.DataContext = viewModel;
        SW.Show();
        InitializeComponent();
        //NOTICE!  After Init is called!
        DataContext = viewModel;
    }
    

    And you're done.

    0 讨论(0)
  • 2021-02-14 22:08

    I would make the ViewModel as an application resource

    <Application.Resources>
        <VM:ViewModel x:Key="SharedViewModel" />
        ....
    </Application.Resources>
    

    then in the each window you call it like this

    DataContext="{StaticResource MainViewModel}"
    

    I'm still new to this concept, and I'm not sure if this is optimal. It works though!

    0 讨论(0)
提交回复
热议问题