12

在庫管理用のウィザードUIを作成したい。xamlの関連する行は次のとおりです。

<ContentPresenter Content="{Binding Current}" ContentTemplateSelector="{StaticResource inventorySelector}"/>

「現在」は、現在アクティブなビューモデルであり、AvailableInventoriesViewModel、GroupsViewModel、NewArticlesViewModel、ResultViewModelのいずれかです。私がそのように定義したDataTemplateSelector:

using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using Centron.WPF.WarehousingExtension.InventoryModule.ViewModels.WizardViewModels;

namespace Centron.WPF.WarehousingExtension.InventoryModule.UI.DataTemplateSelectors
{
    public class InventoryDatatemplateSelector : DataTemplateSelector
    {
        public DataTemplate AvailableDatatype { get; set; }
        public DataTemplate GroupsDatatype { get; set; }
        public DataTemplate NewDatatype { get; set; }
        public DataTemplate ResultDatatype { get; set; }

        public InventoryDatatemplateSelector()
        {
            Debug.WriteLine("");
        }

        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            if (item is AvailableInventoriesViewModel)
                return AvailableDatatype;
            else if (item is GroupsViewModel)
                return GroupsDatatype;
            else if (item is NewArticlesViewModel)
                return NewDatatype;
            else return ResultDatatype;
        }
    }
}

次に、次のようなDataTemplatesとSelectorのインスタンスを作成します。

<base:InventoryViewBase.Resources>
    <DataTemplate DataType="viewModels:AvailableInventoriesViewModel" x:Key="availableInventoriesDatatype">
        <controls:AvailableInventoriesView />
    </DataTemplate>
    <DataTemplate DataType="viewModels:GroupsViewModel" x:Key="groupsDatatype">
        <controls:GroupsView />
    </DataTemplate>
    <DataTemplate DataType="viewModels:NewArticlesViewModel" x:Key="newArticlesDatatype">
        <controls:NewArticlesView />
    </DataTemplate>
    <DataTemplate DataType="viewModels:ResultViewModel" x:Key="resultDatatype">
        <controls:ResultView/>
    </DataTemplate>
    <selector:InventoryDatatemplateSelector
            x:Key="inventorySelector" 
            AvailableDatatype="{StaticResource availableInventoriesDatatype}"
            GroupsDatatype="{StaticResource groupsDatatype}"
            NewDatatype="{StaticResource newArticlesDatatype}"
            ResultDatatype="{StaticResource resultDatatype}"/>
</base:InventoryViewBase.Resources>

InventoryDatatemplateSelectorのコンストラクターにブレークポイントを設定し、それをステップスルーできますが、次のデバッグステップで、明らかにそのセレクターインスタンスの最初のプロパティを設定しようとすると、すぐに内部例外を含む例外が発生します。

\"availableInventoriesDatatype\"という名前のリソースが見つかりません。リソース名では大文字と小文字が区別されます。

取引は何ですか、明確に定義されているのにリソースが見つからないのはなぜですか?

4

4 に答える 4

27

わかりました、私は解決策を見つけました。唯一のエラーは、リソースの「Key」プロパティを最初に設定する必要があることでした。したがって、代わりに:

    <DataTemplate DataType="viewModels:AvailableInventoriesViewModel" x:Key="availableInventoriesDatatype" >
        <controls:AvailableInventoriesView />
    </DataTemplate>

私は欲しい:

    <DataTemplate x:Key="availableInventoriesDatatype" DataType="viewModels:AvailableInventoriesViewModel" >
        <controls:AvailableInventoriesView />
    </DataTemplate>
于 2013-03-21T17:26:55.370 に答える
8

あなたが問題を見つけたことは知っていますが、これを解決するためのより簡単な方法があります。各 DataTemplates は異なるクラスで動作するため、これを行うために DataTemplateSelector を構築する必要はありません。次のようなキーなしで DataTemplates を宣言するだけの場合:

<DataTemplate DataType="{x:Type viewModels:AvailableInventoriesViewModel}">
    <controls:AvailableInventoriesView />
</DataTemplate>
<DataTemplate DataType="{x:Type viewModels:GroupsViewModel}">
    <controls:GroupsView />
</DataTemplate>
<DataTemplate DataType="{x:Type viewModels:NewArticlesViewModel}">
    <controls:NewArticlesView />
</DataTemplate>
<DataTemplate DataType="viewModels:ResultViewModel">
    <controls:ResultView/>
</DataTemplate>

次のようContentPresenterに指定せずに宣言します。ContentTemplateSelector

<ContentPresenter Content="{Binding Current}" />

Current次に、Typeが設定されているものに応じて、適切な DataTemplate が選択されます。

これはよりクリーンなソリューションであり、カスタム セレクターが不要になります。

WPF は強力で非常に柔軟性がありますが、理解するのが難しい場合があります。しかし、それができることを理解すれば、この問題についての意見が変わると思います。

お役に立てれば。

于 2013-03-21T17:54:53.690 に答える
1

これが私のケースでした-DataTemplateの前にItemTemplateを宣言しました:

<ListBox Name="peopleListBox" Grid.Column="1" Grid.Row="2" 
     ItemsSource="{Binding Source={StaticResource ExpenseDataSource}, XPath=Person}"
     ItemTemplate="{StaticResource nameItemTemplate}">
    </ListBox>

<Grid.Resources>
            <!-- Name item template -->
            <DataTemplate x:Key="nameItemTemplate">
                <Label Content="{Binding XPath=@Name}"/>
            </DataTemplate>          
</Grid.Resources>

次に、順序を変更して、次のようにリストボックスの前に Grid.Resources を配置します。すべて問題ありません!!!

<Grid.Resources>
        <!-- Name item template -->
        <DataTemplate x:Key="nameItemTemplate">
            <Label Content="{Binding XPath=@Name}"/>
        </DataTemplate>          
    </Grid.Resources>

<ListBox Name="peopleListBox" Grid.Column="1" Grid.Row="2" 
     ItemsSource="{Binding Source={StaticResource ExpenseDataSource}, XPath=Person}"
     ItemTemplate="{StaticResource nameItemTemplate}">
    </ListBox>

XAML ってそんなにばかじゃないの?:) :)

于 2015-03-16T15:57:18.443 に答える