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