2013-03-21 13 views
5

在庫管理のウィザードUIを作成したいと考えています。 XAMLで該当する行は次のとおりです。「X」という名前のリソースが見つかりません。どうしてですか?

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

"現在"、現在アクティブなビューモデル、AvailableInventoriesViewModel、GroupsViewModel、NewArticlesViewModel、ResultViewModelの一つです。

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のインスタンスと、このようなセレクタの作成:

<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のコンストラクタにブレークポイントを設定し、ステップ実行することができますが、私はそのように定義しているDataTemplateSelectorそれは次のデバッグステップで明らかにセレクタインスタンスの最初のプロパティを設定しようとすると、すぐに内部例外を持つ例外が発生します。

Cannot find resource named \"availableInventoriesDatatype\". Resource names are case sensitive.

どうしたのですか?明確に定義されているリソースが見つからないのはなぜですか?

+1

この問題を引き起こしたことがわからないことがいくつかあります。最初に、xamlは上から下に解析され(非常に例外を除いて)、オブジェクトグラフに変換されます。つまり、**注文は重要です**。第2に、DataTemplateは、(基本的に)x:Keyプロパティに取って代わる「DataType」に基づいてKeyを割り当てるように設計されています。したがって、DataTemplate(それを使用するにまったく必要ない)とx:Keyの両方を持つDataTemplateを定義する場合は、まずx:Keyを配置する必要があります。 DTを使いやすくした結果、混乱しました。 – Will

答えて

17

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

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

私が必要:

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

これはとてもダムです。私は復讐してxamlが嫌いです。 – Hackworth

+6

Xamlは素晴らしいです、あなたのコメントは無効です。私はあなたのデータテンプレートセレクタでインラインで定義できる場合、あなたの静的リソースを使用することがなぜ迷っているのかよくわかりません。また、あなたはこれをやっている方法がちょっと奇妙です。コンテンツコントロールは、特定のタイプの最初のデータテンプレートのリソースを自動的に検索します。したがって、各テンプレートが特定のタイプ – Will

+0

に一致する場合は、セレクタを間違える可能性があります。私はDataTemplatesからKeyプロパティを削除し、ContentPresenterではセレクタを使用しませんでした。現在、ContentPresenterに表示されるのは、実際のコントロールではなく、Current.ToString()です。 DataTemplatesをContentPresenter.Resourcesに配置すると、これも発生します。 – Hackworth

7

私はあなたの問題を発見したけど、私はあなたが知っておくべきと思っているこの問題を解決するための簡単な方法があります。それぞれのDataTemplateは異なるクラスで動作しているため、これを行うには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> 

、そのようContentTemplateSelectorを指定せずに、あなたのContentPresenterを宣言します。そして、適切なDataTemplateをはどんなタイプCurrentのために選択されます

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

に設定されています。

これははるかにクリーンな解決策であり、カスタムセレクターの必要性を排除します。

WPFは強力で非常に柔軟性がありますが、あなたの頭を包み込むことは難しいかもしれません。しかし、あなたができることを理解すれば、あなたはその問題に関するあなたの意見を変えると思います。

これが役に立ちます。ここで

+0

複数のDataTemplateを1つのContentPresenterに割り当てるための完全な基本コードを提供できますか?私はContentPresenter.ContentTemplateプロパティに複数のDataTemplatesを割り当てようとしましたが、一度しか設定できません。これは私にエラーを与える:<のContentPresenter> Hackworth

+0

あなたのContentPresenterに 'DataTemplate'を割り当てる必要はありません。 'DataTemplate'宣言のキーを離しておくと、' ContentPresenter'は 'DataType'に自動的に一致する' DataTemplate'を使用します。 –

+0

私はそれをあなたの方法で試しました。私はDataTemplatesからKeyプロパティを削除し、ContentPresenterではセレクタを使用しませんでした。現在、ContentPresenterに表示されるのは、実際のコントロールではなく、Current.ToString()です。 DataTemplatesをContentPresenter.Resourcesに配置すると、これも発生します。 – Hackworth

0

は、私の場合だった - 私は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 [email protected]}"/> 
      </DataTemplate>   
</Grid.Resources> 

その後、私はちょうど順序を変更し、怒鳴るようにリストボックスの前にGrid.Resourcesを入れて、今も元気にすべて!

<Grid.Resources> 
     <!-- Name item template --> 
     <DataTemplate x:Key="nameItemTemplate"> 
      <Label Content="{Binding [email protected]}"/> 
     </DataTemplate>   
    </Grid.Resources> 

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

XAMLはとても愚かではありませんか? :) :)

0

ネストされたコンポーネントのスタイリングの場合は、さらに詳しく説明します。この例では、MainWindowGridにUserControlGridとPanelGridが含まれています。

次のコードは機能しません。

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:local="clr-namespace:XeerSoft.UX.Themes"> 
    <Thickness x:Key="PanelRowMargin">0,0,0,10</Thickness> 
    <Thickness x:Key="PanelPadding">10</Thickness> 

    <Color x:Key="Primary">#005C9D</Color> 
    <SolidColorBrush x:Key="PrimaryBrush" Color="{StaticResource Primary}"></SolidColorBrush> 

    <Color x:Key="Accent">#E3672B</Color> 
    <SolidColorBrush x:Key="AccentBrush" Color="{StaticResource Accent}"></SolidColorBrush> 

    <Color x:Key="DarkGray">#777777</Color> 
    <SolidColorBrush x:Key="DarkGrayBrush" Color="{StaticResource DarkGray}"></SolidColorBrush> 

    <Color x:Key="LightGray">#E4E4E4</Color> 
    <SolidColorBrush x:Key="LightGrayBrush" Color="{StaticResource LightGray}"></SolidColorBrush> 

    <Style x:Key="MainWindowGrid" 
      BasedOn="{StaticResource {x:Type Grid}}" 
      TargetType="Grid"> 
     <Setter Property="Background" Value="{StaticResource LightGrayBrush}"/> 
    </Style> 

    <Style x:Key="GridPanel" 
      BasedOn="{StaticResource {x:Type Grid}}" 
      TargetType="Grid"> 
     <Setter Property="Background" Value="White"/> 
    </Style> 

    <Style x:Key="UserControlPanel" 
      BasedOn="{StaticResource {x:Type UserControl}}" 
      TargetType="UserControl"> 
     <Setter Property="Background" Value="White"/> 
     <Setter Property="BorderBrush" Value="{StaticResource DarkGrayBrush}"/> 
     <Setter Property="BorderThickness" Value="1"/> 
    </Style> 

</ResourceDictionary> 

ここで、宣言シーケンスをスワップすると、MainWindowGridが最後に実行されるようになります。 (外側のスコープは最後になります)

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:local="clr-namespace:XeerSoft.UX.Themes"> 
    <Thickness x:Key="PanelRowMargin">0,0,0,10</Thickness> 
    <Thickness x:Key="PanelPadding">10</Thickness> 

    <Color x:Key="Primary">#005C9D</Color> 
    <SolidColorBrush x:Key="PrimaryBrush" Color="{StaticResource Primary}"></SolidColorBrush> 

    <Color x:Key="Accent">#E3672B</Color> 
    <SolidColorBrush x:Key="AccentBrush" Color="{StaticResource Accent}"></SolidColorBrush> 

    <Color x:Key="DarkGray">#777777</Color> 
    <SolidColorBrush x:Key="DarkGrayBrush" Color="{StaticResource DarkGray}"></SolidColorBrush> 

    <Color x:Key="LightGray">#E4E4E4</Color> 
    <SolidColorBrush x:Key="LightGrayBrush" Color="{StaticResource LightGray}"></SolidColorBrush> 


    <Style x:Key="GridPanel" 
      BasedOn="{StaticResource {x:Type Grid}}" 
      TargetType="Grid"> 
     <Setter Property="Background" Value="White"/> 
    </Style> 

    <Style x:Key="UserControlPanel" 
      BasedOn="{StaticResource {x:Type UserControl}}" 
      TargetType="UserControl"> 
     <Setter Property="Background" Value="White"/> 
     <Setter Property="BorderBrush" Value="{StaticResource DarkGrayBrush}"/> 
     <Setter Property="BorderThickness" Value="1"/> 
    </Style> 

    <Style x:Key="MainWindowGrid" 
      BasedOn="{StaticResource {x:Type Grid}}" 
      TargetType="Grid"> 
     <Setter Property="Background" Value="{StaticResource LightGrayBrush}"/> 
    </Style> 
</ResourceDictionary> 
関連する問題