Passing value from child window to parent window using WPF and MVVM pattern

后端 未结 2 645
独厮守ぢ
独厮守ぢ 2021-01-15 15:27

I have parent window which has textBox called \"SchoolName\", and a button called \"Lookup school Name\".

That Button opens a child window with list of school names.

相关标签:
2条回答
  • 2021-01-15 16:15

    My solution is to bind both the windows to the same ViewModel, then define a property to hold the resulting value for codes, lets call it CurrentSchoolCodes, Bind the label to this property. Make sure that CurrentSchoolCodes raises the INotifyPropertyChanged event. then in the DoUseSelectedSchoolNameItem set the value for CurrentSchoolCodes.

    For properties in your models I suggest you to load them as they are required(Lazy Load patttern). I this method your property's get accessor checks if the related field is still null, loads and assigns the value to it. The code would be like this code snippet:

    private ObservableCollection<SchoolModel> _schoolList;
    public ObservableCollection<SchoolModel> SchoolList{
        get {
            if ( _schoolList == null )
                _schoolList = LoadSchoolList();
            return _schoolList;
        }
    }
    

    In this way the first time your WPF control which is binded to this SchoolList property tries to get the value for this property the value will be loaded and cached and then returned.

    Note: I have to say that this kind of properties should be used carefully, since loading data could be a time consuming process. And it is better to load data in a background thread to keep UI responsive.

    0 讨论(0)
  • 2021-01-15 16:27

    The Solution Sam suggested here is a correct one. What you didn't get is that you should have only one instance of you viewmodel and your main and child page should refer to the same one. Your viewmodel should be instanciated once: maybe you need a Locator and get the instance there... Doing like this the code in your ctor will fire once, have a look at the mvvmLight toolkit, I think it will be great for your usage, you can get rid of those Classes implementing ICommand too... You can find a great example of using that pattern here: http://blogs.msdn.com/b/kylemc/archive/2011/04/29/mvvm-pattern-for-ria-services.aspx basically what happens is this:

    you have a Locator

    public class ViewModelLocator 
    {
        private readonly ServiceProviderBase _sp;
    
        public ViewModelLocator()
        {
            _sp = ServiceProviderBase.Instance;
    
            // 1 VM for all places that use it. Just an option
            Book = new BookViewModel(_sp.PageConductor, _sp.BookDataService); 
        }
    
        public BookViewModel Book { get; set; }
        //get { return new BookViewModel(_sp.PageConductor, _sp.BookDataService); }
    
        // 1 new instance per View 
        public CheckoutViewModel Checkout
        {
            get { return new CheckoutViewModel(_sp.PageConductor, _sp.BookDataService); }
        }
    }
    

    that Locator is a StaticResource, in App.xaml

    <Application.Resources>
            <ResourceDictionary>
            <app:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
            </ResourceDictionary>
        </Application.Resources>
    

    in your views you refer you viewmodels trough the Locator:

       DataContext="{Binding Book, Source={StaticResource Locator}}"
    

    here Book is an instance of BookViewModel, you can see it in the Locator class

    BookViewModel has a SelectedBook:

     private Book _selectedBook;
            public Book SelectedBook
            {
                get { return _selectedBook; }
                set
                {
                    _selectedBook = value;
                    RaisePropertyChanged("SelectedBook");
                }
            }
    

    and your child window should have the same DataContext as your MainView and work like this:

    <Grid Name="grid1" DataContext="{Binding SelectedBook}"> 
    
    0 讨论(0)
提交回复
热议问题