通过MVVM将视图输出到另一个视图中

时间:2013-09-25 20:19:31

标签: c# xaml windows-phone-7 mvvm windows-phone-8

我是Windows Phone上MVVM集成的初学者。我有2个不同的视图(TilesView [xaml + cs]和MainPage [xaml + cs])和2个ViewModels(MainViewModel.cs和TilesViewModel.cs)然后我的MainPage.xaml。 我想在按下MainPage上的主页按钮时将TilesView输出到我的MainPage中。 TilesView包含一个Canvas,它有我的瓷砖。我应该使用MainView中的哪个控件,因此它将包含TilesView? 每当我想在按下MainPage中的HomeButton后将视图输出到MainPage中时,我想要一个名为LaodTiles的函数被调用。我如何定义该功能以及在哪里?

我主要集成了MVVM结构,以便能够更好地管理我的资源并使MainPage尽可能轻,因此在我的应用程序启动时,通过控制应首先启动哪些设计组件以及应该延迟什么,它会加载得更快。 Tiles视图是我从MainPage中删除并稍后加载的,当关闭它时会释放一些资源。

所以我设法以这种方式在VMLocator中进行MVVM连线(如果不是这样的话,请纠正我):

...
public ViewModelLocator()
    {
        ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
        SimpleIoc.Default.Register<MainViewModel>();
        SimpleIoc.Default.Register<TilesHomeViewModel>();
    }

    public MainViewModel Main
    {
        get
        {
            return ServiceLocator.Current.GetInstance<MainViewModel>();
        }
    }

    public TilesHomeViewModel TilesVM
    {
        get
        {
            return ServiceLocator.Current.GetInstance<TilesHomeViewModel>();
        }
    }
...

我的TilesView具有以下通用结构:

<phone:PhoneApplicationPage x:Class="myAppName.Views.TilesHomeView" ... >
    <Grid x:Name="HomeGrid" ...>
        <Canvas x:Name="TilesCanvas" >
        ...

在我的TilesHomeViewModel中,我将它设置为INotifyPropertyChanged(同样,我是MVVM的初学者,所以我对如何解决这个问题的理解可能会失效)。以下是它的定义方式:

public class TilesHomeViewModel : INotifyPropertyChanged
{
    private string loadHomeContent;
    public string LoadHomeContent
    {
        get
        {
            return loadHomeContent;
        }
        set
        {
            loadHomeContent = value;
            NotifyPropertyChanged("LoadHomeContent");
        }
    }

    public TilesHomeViewModel()
    {

    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(String propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (null != handler)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

}

我的MainPage.xaml有一个点,其中网格定义了网格。 Gridrow = 0已经为TilesView保留了,所以当TilesView弹出/加载到MainPage中时,它将填充该gridrow部分。如果保留一个gridrow空间不是解决方案或不是必需的,我会很高兴听到其他一些提示/解决方案。也许还有另一种方法可以让TilesView在代码隐藏中被调用时重新定位。

前面提到的那些问题的任何提示,代码或教程链接都会有所帮助。感谢

1 个答案:

答案 0 :(得分:0)

我在大型Windows Phone应用程序(MapQuest)上工作,其他开发人员和我自己设计的设计理念是使用MVVM,但只有一个视图/页面,只需加载所有视图(在这种情况下作为控件)通过根据需要设置他们的可见性,最终用户似乎逐步浏览页面。

话虽如此,没有一种做事方式,你的方式可能和任何人一样有效。我建议你做一些类似于上面提到的事情并保持一个页面,但继续使用多个ViewModel,或者根据需要使用所有数据的一个视图模型,但交换出可见的视图。

关于处理视图,在主页代码中执行此操作以转换每个视图/控件。

或者让每个控件(视图)绑定到viewmodel上的枚举,该枚举提供视图状态。每个控件(您的视图)将获取枚举返回的内容,并根据状态知道是否使其自身可见。

您需要在该枚举的目标用户控件/视图上放置依赖项属性。我建议将这些片段从Helpful Silverlight Snippets(不要担心我已经将它们用于Silverlight,WPF和WP8代码)安装到visual studio中。您需要为上面的枚举添加一个值类型依赖项属性和更改处理程序,并在更改处理程序中打开或关闭控件。

不要过于担心MVVM,它只是一种更好的方式,可以实现将业务逻辑与视图逻辑和处理逻辑分离的3层架构。主要的是绑定到VM并在VM上执行大部分处理以获取数据,但不执行直接视图逻辑,除了打开或关闭View上绑定的数据以进行该处理。