0

私は「モダン UI」アプリケーションに取り組んでいるので、構文は私にとって少し新しいものであり、バインディングを適切に機能させることができないようです。

私の望みは、ViewModel を最初に設計して、アプリ ページで を子としてListView追加しUserViewModel、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/)を1時間ほど検索してみましたが、機能する例を見つけることができませんでした私の場合。

私が間違っていることは何か分かりますか?

4

2 に答える 2

0

ListViewの「UserViewModel」をテキストとして取得するだけです(UserControlは作成されません)

が暗黙的に適用されるように、プロパティを使用して定義し、プロパティを使用せずDataTemplateにニーズを定義します。DataTypex:KeyDataTemplate

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

指定されているDataTypeが指定されていないx:KeyDataTemplate は Implicit DataTemplate です。つまり、WPF が指定されたデータ型のオブジェクトを描画する必要があるときはいつでも暗黙的に使用されます。

プロパティを持つ DataTemplate は、次のx:Keyようにコードでキーによって実際に指定する必要があります。

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

また、質問のタイトル ( 「DataContext for MVVM: where does it go?」 ) がタイプミスかどうかはわかりませんが、質問の本文は について尋ねているようには見えませんがDataContext、私には初心者がいます。理解に苦労している場合に興味があるかもしれないDataContext を説明している私のブログの記事DataContext

于 2013-01-07T15:32:58.597 に答える
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);
}

また、WPF データバインディングの鍵となる INotifyPropertyChange インターフェイスを実装する ViewModel クラスが表示されません。それが完了し、ユーザーをロードしたら、プロパティが更新されていることを 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 に答える