0

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

我的愿望是首先设计一个 ViewModel,以便在我的应用程序页面上,我可以做一些事情,比如ListView将 aUserViewModel作为子级添加,并自动找到 DataTemplate 以创建 UserView 并绑定到提供的 UserViewModel。

我为为 Win 7 桌面编写的不同应用程序做了类似的事情,它只是工作,但对于我的生活,我无法弄清楚为什么它在这里不起作用。我只是将我的 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>

和 :

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

我已经尝试通过各种示例(例如http://joshsmithonwpf.wordpress.com/a-guided-tour-of-wpf/)搜索一个小时左右,但无法找到有效的示例就我而言。

知道我做错了什么吗?

4

2 回答 2

0

可能是错字,但当您通过 WCF 服务获取用户时,您似乎没有更新“_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");
}
于 2013-01-07T03:27:05.247 回答
0

我只是以文本形式进入我的 ListView“UserViewModel”(未创建 UserControl)

您的DataTemplate需求由DataType属性和无x:Key属性定义,以便DataTemplate隐式应用

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

具有DataType指定但没有指定x:Key的 DataTemplate 是隐式 DataTemplate,这意味着只要 WPF 需要绘制指定数据类型的对象,就会隐式使用它。

具有x:Key属性的 DataTemplate 需要在您的代码中通过键实际指定,例如

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

另外,我不确定您的问题的标题(“MVVM 的 DataContext:它去哪儿了?”)是否是错字,因为您的问题主体似乎没有询问DataContext,但是我有一个初学者我博客上的文章解释了您可能感兴趣的 DataContext,如果您难以理解DataContext

于 2013-01-07T15:32:58.597 回答