如何并排绑定两个视图

时间:2017-12-21 00:59:35

标签: c# wpf xaml mvvm

我一直关注这个Walkthrough,它可以解释两个视图之间的切换,以及更多。

我正在尝试调整项目的方法是,不是在两个视图之间切换,而是并排显示两个视图。

Andy在他的MainWindowViewModel中设置了以下内容,将ViewModel放入OC:

public class MainWindowViewModel : NotifyUIBase
{
    public ObservableCollection<ViewVM> Views {get;set;}

    public MainWindowViewModel()
    {
        ObservableCollection<ViewVM> views = new ObservableCollection<ViewVM>
        {
            new ViewVM{ ViewDisplay="Customers", ViewType = typeof(CustomersView), ViewModelType = typeof(CustomersViewModel)},
            new ViewVM{ ViewDisplay="Products", ViewType = typeof(ProductsView), ViewModelType = typeof(ProductsViewModel)}
        };
        Views = views;
        RaisePropertyChanged("Views");
        views[0].NavigateExecute();
    }
}

在MainWindow.xaml.cs导航中调用ShowUserControl()来设置视图

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        // Apply default form level font style
        Style = (Style)FindResource(typeof(Window));
        Messenger.Default.Register<NavigateMessage>(this, (action) => ShowUserControl(action));
        this.DataContext = new MainWindowViewModel();
    }

    private void ShowUserControl(NavigateMessage nm)
    {
        EditFrame.Content = nm.View;
    }
}

我的代码:

我不会在OC中需要它们而且我不会在视图之间切换,它们将同时并排显示。所以我在想我需要做的是

public class MainWindowViewModel : NotifyUIBase
{
    private ViewVM m_MobileDeviceRequestsVM;
    private ViewVM m_AuthorizedMobileDevicesVM;

    public ViewVM MobileDeviceRequestsVM
    {
        get { return m_MobileDeviceRequestsVM; }
    }

    public ViewVM AuthorizedMobileDevicesVM
    {
        get { return m_AuthorizedMobileDevicesVM; }
    }

    public MainWindowViewModel()
    {
        m_MobileDeviceRequestsVM = new ViewVM { ViewDisplay = "MobileDeviceRequests", ViewType = typeof(MobileDeviceRequestsView), ViewModelType = typeof(MobileDeviceRequestsViewModel) };
        m_AuthorizedMobileDevicesVM = new ViewVM { ViewDisplay = "AuthorizedMobileDevices", ViewType = typeof(AuthorizedMobileDevicesView), ViewModelType = typeof(AuthorizedMobileDevicesViewModel) };
    }
}

我面临的问题是如何将这些ViewModel视图绑定到我的网格中,尝试使用一些ContentControl,但这不起作用。 我怎么能做到这一点?

<Window x:Class="MobileDeviceAuthenticator.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:MobileDeviceAuthenticator"
        Title="Device Authorization" Height="381" Width="879">
    <Grid>
        <Grid Margin="0,25,0,0">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>

            <Label Content="Authorized Devices" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Left" Margin="20,10,0,0" VerticalAlignment="Top" />
            <ContentControl Grid.Row="1" Grid.Column="0" Content="{Binding AuthorizedMobileDevicesVM.View}" />

            <Label Content="Device Requests" Grid.Row="0" Grid.Column="1" HorizontalAlignment="Left" Margin="20,10,0,0" VerticalAlignment="Top" />
            <ContentControl Grid.Row="1" Grid.Column="1" Content="{Binding MobileDeviceRequestsVM.View}" />
        </Grid>
    </Grid>
</Window>

1 个答案:

答案 0 :(得分:1)

在我对我对该方法的保留做出评论后,我再次查看了该示例的ViewVM类。忽略其中任何一项并假设您未修改下面示例的ViewVM代码:

 public class ViewVM
    {
        public string ViewDisplay { get; set; }
        public Type ViewType { get; set; }
        public Type ViewModelType { get; set; }
        public UserControl View { get; set; }
        public RelayCommand Navigate { get; set; }
        public ViewVM()
        {
            Navigate = new RelayCommand(NavigateExecute);
        }
        public void NavigateExecute()
        {
            if(View == null && ViewType != null)
            {
                View = (UserControl)Activator.CreateInstance(ViewType);
            }
            var msg = new NavigateMessage { View = View, ViewModelType = ViewModelType, ViewType = ViewType };
            Messenger.Default.Send<NavigateMessage>(msg);
        }
    }

问题是View属性仅在调用NavigateExecute时分配给via反射。绑定到AuthorizedMobileDevicesVM.View时,它尚未实例化。您可以将反射代码移动到您的案例的构造函数中,并且它可以正常工作。当然,这意味着如果您在其他地方使用ViewVM进行页面导航,它会增加应用程序的内存使用量 - 看起来它的设计意味着只在必要时创建视图。