2

現在、WPF の柔軟性をテストするアプリケーションを作成しています。ViewModelに関しては、非常に透過的であることを目的としたユーザーコントロールがいくつかあります。透明とは、ViewModel がそのユーザー コントロール内のコントロールにバインドされる必要なすべてのプロパティを持っている場合、ユーザー コントロールが任意のタイプの ViewModel を使用できることを意味します。これを行うには、ViewModel を特定のユーザー コントロールのデータ コンテキストとして割り当てます。

これは、ユーザー コントロールが 2 つしかない場合に機能します (1 つは ViewModelLocator にアクセスでき、もう 1 つは前者からの datacontext 宣言が必要です)。ユーザー コントロールが 3 層以上になるとどうすればよいかわかりません。ViewModelLocator にアクセスできるユーザー コントロールに存在するユーザー コントロール内にユーザー コントロールのデータ コンテキストを設定する方法はありますか?

以下は、私の質問を明確にするコードです。

このコードは親ユーザー コントロールです。これは、MAF を利用するアプリケーションで使用することを目的としていました。非静的 ViewModelLocator を使用して、各プラグイン インスタンスが ViewModelLocator の異なるインスタンスを使用するようにし、プラグインが独自の app.xaml を持たない (したがってグローバル リソースがない) ためです。ご覧のとおり、別のアセンブリからユーザー コントロールをグリッドに配置し、そのデータ コンテキストを宣言して、ユーザー コントロールが親ユーザー コントロールの ViewModelLocator と対話するようにしました。

<UserControl x:Class="TestApp.Inventory.Common.Views.MaterialsNewView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:vm="clr-namespace:TestApp.Inventory.Common.ViewModel"
             xmlns:views="clr-namespace:TestApp.Inventory.Common.Views"
             xmlns:viewsSupp="clr-namespace:TestApp.Supplier.Common.Views;assembly=TestApp.Supplier.Common"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" Height="607" Width="616" Loaded="UserControl_Loaded">

    <UserControl.Resources>
        <vm:ViewModelLocator x:Key="Locator" />
    </UserControl.Resources>

    <UserControl.DataContext>
        <Binding Path="MaterialsNewView" Source="{StaticResource Locator}" />
    </UserControl.DataContext>

    <Grid>
        <views:SupplierView x:Name="supplierView" Margin="145,306,0,0" HorizontalAlignment="Left" Width="328" Height="258" VerticalAlignment="Top" DataContext="{Binding Source={StaticResource Locator}, Path=SupplierView}" />
    </Grid>
</UserControl>

次に、子ユーザーコントロールのコードがあります。先に述べたように、子ユーザー コントロールは ViewModel に関して透過的であることを意図していました。そのため、毎回親ユーザー コントロールでデータ コンテキストを宣言する必要があります。

<UserControl x:Class="TestApp.Supplier.Common.Views.SupplierView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:ignore="http://www.ignore.com"
        mc:Ignorable="d ignore" Height="289" Width="352" 
        xmlns:my="clr-namespace:TestApp.Lookup.Common.Views;assembly=TestApp.Lookup.Common">

    <Grid>
        <my:MaterialTypeListView Height="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Grid, AncestorLevel=1}, Path=ActualHeight}" HorizontalAlignment="Left" Name="materialTypeListView1" VerticalAlignment="Top" Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Grid, AncestorLevel=1}, Path=ActualWidth}" />
    </Grid>
</UserControl>

私の問題は、子ユーザーコントロールに独自の子ユーザーコントロールがある場合です。親ユーザーコントロールからデータコンテキストを宣言する方法がわかりません。目的は、ユーザーコントロールのレイヤーがいくつあっても、親ユーザーコントロールの ViewModelLocator と対話する必要があることです。

4

1 に答える 1

2

DependencyPropertyMaterialTypeList という名前の UserControl SupplierView に を追加します。

public partial class SupplierView
{
    public List<string> MaterialTypeList
    {
        get { return (List<string>)GetValue(MaterialTypeListProperty); }
        set { SetValue(MaterialTypeListProperty, value);}
    }

    public static readonly DependencyProperty MaterialTypeListProperty =
            DependencyProperty.Register("MaterialTypeList", typeof(string), typeof(SupplierView),
            new PropertyMetadata(null));
}

SupplierView の UserControl MaterialNewView のバインディングを MaterialTypeList に追加します。

 <UserControl x:Class="TestApp.Supplier.Common.Views.SupplierView"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:ignore="http://www.ignore.com"
            mc:Ignorable="d ignore" Height="289" Width="352" 
            xmlns:my="clr-namespace:TestApp.Lookup.Common.Views;assembly=TestApp.Lookup.Common">

        <Grid>
            <my:MaterialTypeListView 
DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl, AncestorLevel=1}, Path=MaterialTypeList}"
Height="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Grid, AncestorLevel=1}, Path=ActualHeight}" HorizontalAlignment="Left" Name="materialTypeListView1" VerticalAlignment="Top" Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Grid, AncestorLevel=1}, Path=ActualWidth}" />
        </Grid>
    </UserControl>

MaterialTypeListView の UserControl SupplierView のバインディングを MaterialTypeList に追加します。

    <UserControl x:Class="TestApp.Inventory.Common.Views.MaterialsNewView"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:vm="clr-namespace:TestApp.Inventory.Common.ViewModel"
                 xmlns:views="clr-namespace:TestApp.Inventory.Common.Views"
                 xmlns:viewsSupp="clr-namespace:TestApp.Supplier.Common.Views;assembly=TestApp.Supplier.Common"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 mc:Ignorable="d" Height="607" Width="616" Loaded="UserControl_Loaded">

        <UserControl.Resources>
            <vm:ViewModelLocator x:Key="Locator" />
        </UserControl.Resources>

        <UserControl.DataContext>
            <Binding Path="MaterialsNewView" Source="{StaticResource Locator}" />
        </UserControl.DataContext>

        <Grid>
            <views:SupplierView x:Name="supplierView" Margin="145,306,0,0" 
MaterialTypeList="{Binding [HERE YOUR LIST OF MATERIALTYPE]}"
HorizontalAlignment="Left" Width="328" Height="258" VerticalAlignment="Top" DataContext="{Binding Source={StaticResource Locator}, Path=SupplierView}" />
        </Grid>
    </UserControl>
于 2013-04-22T13:46:33.360 に答える