C# MVVM的数据模板:它去哪里了?

C# MVVM的数据模板:它去哪里了?,c#,xaml,mvvm,windows-8,C#,Xaml,Mvvm,Windows 8,我正在开发一个“现代UI”应用程序,因此语法对我来说有点新,我似乎无法让绑定正常工作 我的愿望是拥有一个ViewModel first设计,这样在我的应用程序页面上,我就可以做一些事情,比如拥有一个列表视图,然后作为一个孩子添加一个UserViewModel,并自动找到DataTemplate来创建一个UserView并绑定到提供的UserViewModel 我为Win 7 desktop编写的另一个应用程序做了类似的事情,它可以正常工作,但就我的一生而言,我不明白为什么它不能在这里工作。我只是

我正在开发一个“现代UI”应用程序,因此语法对我来说有点新,我似乎无法让绑定正常工作

我的愿望是拥有一个ViewModel first设计,这样在我的应用程序页面上,我就可以做一些事情,比如拥有一个
列表视图
,然后作为一个孩子添加一个
UserViewModel
,并自动找到DataTemplate来创建一个UserView并绑定到提供的UserViewModel

我为Win 7 desktop编写的另一个应用程序做了类似的事情,它可以正常工作,但就我的一生而言,我不明白为什么它不能在这里工作。我只是以文本的形式进入我的ListView“UserViewModel”(没有创建UserControl)

这里唯一的另一个区别是,这是我第一次使用异步函数,因为Win 8开发几乎是强制使用异步函数的,这是我从WCF服务获取数据的方法

下面是我的视图模型的一个示例:

 public class UserViewModel
{
    private UserDTO _user { get; set; }

    public UserViewModel(UserDTO user)
    {
        _user = user;
    }

    public UserViewModel(int userId)
    {
        SetUser(userId);
    }

    private async void SetUser(int userId)
    {
        ServiceClient proxy = new ServiceClient();
        UserDTO referencedUser = await proxy.GetUserAsync(userId);
    }

    public string FirstName
    {
        get
        {
            return _user.FirstName;
        }
    }

    public string LastName
    {
        get
        {
            return _user.LastName;
        }
    }

    public string Email
    {
        get
        {
            return _user.email;
        }
    }
}
该视图应为所有XAML,并粘合在应用程序资源中,如下所示:

<UserControl x:Class="TaskClient.Views.UserView" ...
    xmlns:root="using:TaskClient"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="30"
    d:DesignWidth="200">
    <StackPanel Orientation="Horizontal" Margin="5, 0, 0 ,0" DataContext="{Binding}">
        <TextBlock x:Name="FirstNameLabel" Text="{Binding FirstName}"/>
        <TextBlock x:Name="LastNameLabel" Text="{Binding LastName}"/>
        <TextBlock x:Name="EmailLabel" Text="{Binding Email}"/>
    </StackPanel>
</UserControl>

以及:

)并且没有找到一个适合我的例子


知道我做错了什么吗?

可能是打字错误,但在通过WCF服务获取用户时,您似乎没有更新“\u user”字段。您可能需要更改以下内容:

private async void SetUser(int userId)
{
    ServiceClient proxy = new ServiceClient();
    UserDTO referencedUser = await proxy.GetUserAsync(userId);
}
为此:

private async void SetUser(int userId)
{
    ServiceClient proxy = new ServiceClient();
    _user = await proxy.GetUserAsync(userId);
}
另外,我没有看到ViewModel类实现INotifyPropertyChange接口,它是WPF数据绑定的关键。完成此操作并加载用户后,需要通知WPF正在更新的属性:

private async void SetUser(int userId)
{
    ServiceClient proxy = new ServiceClient();
    _user = await proxy.GetUserAsync(userId);
    NotifyOfPropertyChange();
}

private void NotifyOfPropertyChange() 
{
    NotifyChanged("FirstName"); //This would raise PropertyChanged event.
    NotifyChanged("LastName");
    NotifyChanged("Email");
}
我只是以文本的形式进入我的ListView“UserViewModel”(没有创建UserControl)

您的
DataTemplate
需要使用
DataType
属性和no
x:Key
属性定义,才能隐式应用
DataTemplate

<DataTemplate DataType="{x:Type vm:UserViewModel}">
    <vw:UserView />
</DataTemplate>

此外,我不确定您的问题的标题(“MVVM的DataContext:它去哪里了?”)是否是打字错误,因为您的问题主体似乎没有询问有关
DataContext
,但是,如果您正在努力理解
DataContext

现代UI应用程序没有x:Type属性,您可能会对我的问题感兴趣。我不知道该怎么办。@Mike我没意识到。您可以使用DataTemplateSelector吗?在Silverlight添加对隐式数据模板的支持之前,我在Silverlight中就是这样使用的。也许像这样的东西会管用?嗨,是的,那可能管用。无论如何,在数据绑定之前,我必须解决异步加载的一些问题。请参阅相关问题的答案:。实际上,我现在在viewmodels上有一个“初始化”任务属性。当您创建其中一个时,您将等待初始化的任务,以便加载所有WCF内容并分配属性。我在初始化视图的任务中也做了类似的事情,只是在它们的末尾,我将它们绑定到它们刚刚初始化的东西上,看起来效果很好。此外,我认为您可能对Silverlight的做法是正确的。我似乎记得有人抱怨说,在使用现代用户界面时,有些东西已经过时了。我通常会制作1-2个窗口报告应用程序,这样大多数事情都会隐藏在代码背后,所以我不必经常做很多复杂的MVVM结构。看起来捆绑更痛苦。此外,您也不能再直接连接到数据库,我听说您需要使用服务。
<DataTemplate DataType="{x:Type vm:UserViewModel}">
    <vw:UserView />
</DataTemplate>
<ListView ItemTemplate="{StaticResource MyKey}" ... />