简体   繁体   English

用于MVVM的DataTemplate:它去哪里了?

[英]DataTemplate for MVVM: where does it go?

I'm working on a "Modern UI" application so the syntax is a bit new for me and I just can't seem to get my bindings to work properly. 我正在使用“现代UI”应用程序,因此语法对我来说有点新,而且我似乎无法使绑定正常工作。

My desire is to have a ViewModel first design so that on my apps pages I can just do things like have a ListView and add a UserViewModel as a child, and have the DataTemplate be found automatically to create a UserView and bind to the supplied UserViewModel. 我的愿望是首先设计一个ViewModel,以便在我的应用程序页面上执行诸如拥有ListView并添加UserViewModel作为子项的任务,并自动找到DataTemplate来创建UserView并绑定到提供的UserViewModel。

I do something similar for a different app written for Win 7 desktop and it just works but for the life of me I can't figure out why it doesn't work here. 对于为Win 7桌面编写的其他应用程序,我做了类似的事情,它虽然可以正常工作,但是对于我一生来说,我不知道为什么它在这里不起作用。 I just get in my ListView "UserViewModel" as text (no UserControl created). 我只是以文本形式进入ListView“ UserViewModel”(未创建UserControl)。

The only other difference here is it is the first time I'm using async functions since it pretty much is forced on you for Win 8 development, and that is the methods I get from the WCF service I'm pulling my data from. 唯一的不同是这是我第一次使用异步函数,因为这几乎迫使您进行Win 8开发,这就是我从WCF服务中获取数据的方法。

Here's an example of my view model: 这是我的视图模型的示例:

 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;
        }
    }
}

The view is supposed to be all XAML and glued together in the application resources as follows: 该视图应该全部为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>

and : 和:

<Application x:Class="TaskClient.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TaskClient"
xmlns:localData="using:TaskClient.Data" 
xmlns:vm="using:ViewModels"
xmlns:vw="using:TaskClient.Views">

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>

            <!-- 
                Styles that define common aspects of the platform look and feel
                Required by Visual Studio project and item templates
             -->
            <ResourceDictionary Source="Common/StandardStyles.xaml"/>
        </ResourceDictionary.MergedDictionaries>

        <!-- Application-specific resources -->

        <x:String x:Key="AppName">TaskClient</x:String>

        <DataTemplate x:Key="vm:UserViewModel">
            <vw:UserView />
        </DataTemplate>
    </ResourceDictionary>
</Application.Resources>

I've tried searching for an hour or so now through various examples (eg. http://joshsmithonwpf.wordpress.com/a-guided-tour-of-wpf/ ) and haven't been able to find an example that works in my case. 我现在尝试通过各种示例(例如http://joshsmithonwpf.wordpress.com/a-guided-tour-of-wpf/ )搜索一个小时左右,但找不到合适的示例就我而言。

Any idea what I'm doing wrong? 知道我在做什么错吗?

Could be a typo but you don't seem to update the "_user" field when you fetch a user via WCF service. 可能是拼写错误,但通过WCF服务获取用户时,似乎没有更新“ _user”字段。 You probably need to change this: 您可能需要更改此设置:

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

To this: 对此:

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

Also I don't see your ViewModel class implementing INotifyPropertyChange interface which is the key to WPF databinding. 我也看不到您的ViewModel类实现INotifyPropertyChange接口,这是WPF数据绑定的关键。 Once that's done and you have loaded a user, you need to notify WPF about properties being updated: 完成此操作并加载用户后,您需要通知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");
}

I just get in my ListView "UserViewModel" as text (no UserControl created) 我只是以文本形式进入ListView“ UserViewModel”(未创建UserControl)

Your DataTemplate needs be defined with the DataType property and no x:Key property, for the DataTemplate to get applied implicitly 您需要使用DataType属性和没有x:Key属性定义您的DataTemplate ,以便隐式应用DataTemplate

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

A DataTemplate with a DataType specified but no x:Key is an Implicit DataTemplate, meaning it will be used implicitly anytime WPF needs to draw an object of the specified data type. 指定了DataType但没有x:Key的DataTemplate是一个隐式Da​​taTemplate,这意味着WPF需要绘制指定数据类型的对象时将隐式使用它。

A DataTemplate with an x:Key property needs to actually be specified in your code by key, such as 实际上,需要在代码中通过键来指定具有x:Key属性的DataTemplate,例如

<ListView ItemTemplate="{StaticResource MyKey}" ... />

Also, I'm not sure if the title of your question ( "DataContext for MVVM: where does it go?" ) is a typo or not since your question body doesn't appear to be asking about the DataContext , however I have an beginners article on my blog explaining the DataContext that you may be interested in if you're struggling to understand the DataContext 此外,我不确定您的问题的标题( “ MVVM的DataContext:它去哪里了?” )是否是错字,因为您的问题正文似乎没有在问DataContext ,但是我有一个我的博客上的初学者文章,介绍了您在努力理解DataContext可能感兴趣的DataContext

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM