Silverlight MVVM将用户控件与视图模型连接起来

3

我对一件可能非常简单的事情感到困惑。

我进行了搜索,但未能找到我需要的确切答案。

问题如下。

我正在自学Silverlight MVVM。

目前,我正在编写一个使用1个主页和2个用户控件的应用程序。

正如您所想象的那样,有3个视图模型。

目前在我的XAML中:

mainpage.xaml

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:newFileupload.ViewModel"
xmlns:vw="clr-namespace:newFileupload.View"

<UserControl.DataContext>
    <vm:MainPageViewModel />
</UserControl.DataContext>

<Grid x:Name="LayoutRoot" Background="White">
    <vw:PicturesOverviewView />
</Grid>

PicturesOverviewView.xaml

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

<Grid x:Name="LayoutRoot" Background="White">

</Grid>

在mainpage.xaml中,我在xaml中设置了数据上下文,然后在网格中调用用户控件,如下所示:

<vw:PicturesOverviewView />

这让我遇到了以下错误:
Error   1   Cannot create an instance of "PicturesOverviewView".    C:\Programming\C#\newFileUpload\newFileupload\MainPage.xaml 16  9   newFileupload

我完全不知道是什么原因导致了这个问题,其次...

我该如何将视图模型绑定到适当的用户控件上?

我需要为每个用户控件声明视图命名空间,然后像主页面一样设置它的数据上下文吗?

感谢您花时间阅读,希望能够尽快继续 :)


将您的视图绑定到vm,然后将控件等绑定到驻留在viewmodel中的数据。因此,如果uc1是ListBox,请将其绑定到驻留在MainPageViewModel上的客户列表。 - Derek Beattie
@Derek Beattie:我想为我的用户控件使用不同的视图模型(除非真的不可能),但它仍然无法清除我得到的错误。我甚至无法加载用户控件 :( - Joey Roosing
我复制了你的示例(根据给定的细节猜测每个组件的内容),并且可以编译和运行。 你能提供更多的代码/Xaml吗? "Cannot Create" 可能是 PicturesOverviewView 而不是主页面的问题,但你也没有说它在哪里被创建。 - iCollect.it Ltd
请发布主窗口和用户控件的所有XAML。 - Derek Beattie
@Derek Beattie和HiTech Mahic,我刚刚发布了XAML。想知道是什么原因导致了错误,以及如何将ViewModel绑定到PicturesOverviewView。如果我像在MainPage.xaml中那样绑定它,它会生成另一个错误。 - Joey Roosing
那段代码不可能是正确的。你正在 PicturesOverviewView 中创建一个 PicturesOverviewView。 - iCollect.it Ltd
1个回答

3
如果代码正确,你正在尝试在PicturesOverviewView控件内创建一个PicturesOverviewView控件。这将导致编译错误。(我猜测你可能复制并粘贴了两次相同的Xaml)。
绑定方面: 您想将子控件绑定到主视图模型上的属性,这些属性本身就是视图模型。
例如:
namespace newFileupload.ViewModel
{
    public class MainPageViewModel
    {
        public ChildViewModel1 ChildViewModel1 { get; set; }
        public ChildViewModel2 ChildViewModel2 { get; set; }

        public MainPageViewModel()
        {
            this.ChildViewModel1 = new ChildViewModel1() { SomeProperty = "hello"};
            this.ChildViewModel2 = new ChildViewModel2() { SomeProperty = "there" };
        }
    }
}

然后,主页面绑定如下:
<Grid x:Name="LayoutRoot" Background="White">
    <vw:PicturesOverviewView DataContext="{Binding Path=ChildViewModel1}" />
    <vw:PicturesOverviewView DataContext="{Binding Path=ChildViewModel2}" />
</Grid>

在某些地方,需要使用正确的数据创建视图模型。把子级挂载到父视图模型上是有意义的。

我建议你考虑使用IOC注入(例如使用Unity),因为这听起来像是你可能只想创建单例并在不同级别引用它们。问题在于,如果在子级视图中硬编码数据上下文,那么就无法重用它们。


你说得对,我在那里犯了一个错误。我不是试图在同一个视图中创建一个视图。对此感到抱歉。另外,我想为MainPage和PicturesOverviewView创建单独的ViewModel。在WPF中它可以正常工作,但在Silverlight中却不行。我正在使用4.0版本。 - Joey Roosing
他们可以拥有自己的,但如果您将每个视图的静态成员作为视图模型的一部分创建,则与使用代码后台没有太大区别。这实际上是关于在哪里挂它们。对于简单的MVVM,请将子视图模型嵌套在父视图模型中作为属性,并将子控件绑定到子视图模型。我正在尝试更新我的答案以涵盖此内容。您可能需要检查您发布的Xaml,因为它两次相同。 - iCollect.it Ltd
啊,我明白你在 View Model 绑定方面的想法了。谢谢 ^^ 现在解决错误,以便我可以在设计器中实际看到自己在做什么。我又更新了一下我的帖子。对于造成的混淆,非常抱歉。 - Joey Roosing
啊啊啊...原来是这样设置数据上下文。非常感谢! :) 这对我帮助很大。顺便说一句,这也清除了错误。我已将您的答案标记为正确答案。再次感谢。我终于可以继续了 :) - Joey Roosing
我正在从记忆中完成我的示例的绑定部分,但如果有任何问题,请告诉我,我会进行更新。 - iCollect.it Ltd
你的记忆没有让你失望。现在一切都按照预期运行。感谢你提供关于IoC的信息。之前听说过,但不认为它是必要的。这应该是一个相对简单的东西。一个由我编写的文件上传器,用于学习Silverlight,在我的ASP.NET MVC CMS中实现 :) - Joey Roosing

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接