Modal Popup and views communication under MVVM pattern on C#

后端 未结 1 1007
失恋的感觉
失恋的感觉 2021-01-25 02:31

I have a large project coded with VB6 which I\'ve been trying to upgrade to new technologies for a few months. My project consist on 6 administrative modules reunited under a cl

相关标签:
1条回答
  • 2021-01-25 03:10

    I am the author of the linked ModalContentPresenter control so I will attempt to address some of your questions and concerns.

    I need to write the father view XAML and modal XAML on the same view.

    You can actually write both views in separate files. The views can then be loaded dynamically using DataTemplates which will depend on the ViewModel that is bound to either the Content or ModalContent properties.

    See this which describes the general way in which this view switching can be achieved.

    You could have a MainViewModel which has two properties, PrimaryViewModel and SecondaryViewModel which return appropriate view models which provide the properties and commands for the main and modal content.

    You could have the following setup in XAML:

    <DataTemplate DataType="{x:Type FooViewModel}">
        <Controls:FooView />
    </DataTemplate>
    
    <DataTemplate DataType="{x:Type BarViewModel}">
        <Controls:BarView />
    </DataTemplate>
    
    <controls:ModalContentPresenter 
                  Name="modalPresenter"
                  Content={Binding DataContext.PrimaryViewModel}
                  ModalContent={Binding DataContext.SecondaryViewModel} />
    

    When the IsModalproperty is false, only your PrimaryView will be displayed. As soon as you set the IsModal property to true the ModalContentPresenter will display your SecondaryView.

    I cannot have multiple popus from same view.

    I take it you mean you want to be able to display different modal content at different times from the same main view.

    Using the above technique this is as simple as switching the ViewModel that is bound to the ModalContent property (before displaying it by setting IsModal to true). As long as you have a DataTemplate for the ViewModel that is bound (and your MainViewModel implements INotifyPropertyChanged correctly), the correct content will be displayed.

    Some example on where i'd like to use modal popups is:

    Put a button on a view to select a Client. It should open a popup with all possible clients and let the user chose one.

    Add a product popup to a customer order.

    Once you understand the technique described above you should be able to see that the as long as you have a View and ViewModel pair you can cover any scenario you can think of.

    As an example, consider viewModels that have the following interfaces:

    public interface SelectCustomerViewModel : INotifyPropertyChanged {
        event EventHandler CustomerSelected;        
        public ObservableCollection<Customer> Customers { get; }
        public Customer Customer { get; set; }
        public Command CustomerSelectedCommand { get; }
    }
    
    public interface MainViewModel : INotifyPropertyChanged {
        public SelectCustomerViewModel ModalContent { get; }
        public Command SelectCustomerCommand { get; }
        public bool IsSelectingCustomer { get; }
    }
    

    You could have XAML that looks something like this:

    <Window x:Class="ModalContentTest.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="Select a customer">
    
        <DataContext>
            <vm:MainViewModel />
        </DataContext>
    
        <DataTemplate DataType="{x:Type SelectCustomerViewModel}">
            <Controls:SelectCustomerView />
        </DataTemplate>
    
        <c:ModalContentPresenter Name="modalPresenter"
                                 ModalContent={Binding ModalContent}
                                 IsModal={Binding IsSelectingCustomer}>
    
            <!-- This is the primary content! -->
            <Grid>
                <Button Content="Select a customer"
                        Command={Binding SelectCustomerCommand} />
            </Grid>
    
        </c:ModalContentPresenter>
    
    </Window>
    

    Here's how it works:

    1. The IsSelectingCustomer property of the MainViewModel would start off as false.
    2. Clicking the button in the main view would invoke the SelectCustomerCommand object. The command would then tell the MainViewModel to change the IsSelectingCustomer property to true.
    3. The ModalContentPresenter would display the view specified by the data template. The user can now only interact with the 'select customer view'.
    4. Once a customer has been selected, a button can be clicked (which is bound to the CustomerSelectedCommand of the SelectCustomerViewModel) which in turn would raise the CustomerSelected event.
    5. The MainViewModel would have an event handler that would respond to the CustomerSelected event. The handler would then read the SelectedCustomer property from the SelectCustomerViewModel and finally, it would set the IsSelectingCustomer property back to false, causing the modal content to be closed.
    0 讨论(0)
提交回复
热议问题