我想为库存管理创建一个向导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的构造函数中设置了一个断点,并且可以逐步执行它,但在下一个Debug步骤中,显然当它尝试设置该选择器实例的第一个属性时,我立即得到一个带有内部异常的异常:
找不到名为“availableInventoriesDatatype”的资源。资源名称区分大小写。
什么是交易,为什么在明确定义时找不到资源?
答案 0 :(得分:18)
好的,我找到了解决方案。唯一的错误是必须首先设置资源的“Key”属性。所以而不是:
<DataTemplate DataType="viewModels:AvailableInventoriesViewModel" x:Key="availableInventoriesDatatype" >
<controls:AvailableInventoriesView />
</DataTemplate>
我需要:
<DataTemplate x:Key="availableInventoriesDatatype" DataType="viewModels:AvailableInventoriesViewModel" >
<controls:AvailableInventoriesView />
</DataTemplate>
答案 1 :(得分:7)
我知道你发现了你的问题,但有一种更简单的解决方法,我认为你应该知道。由于每个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
设置为什么,都将选择适当的DataTemplate。
这是一个更清洁的解决方案,无需自定义选择器。
WPF非常强大且非常灵活,但是让你的脑袋缠绕它可能具有挑战性。但是一旦你明白它能做什么,我想你会改变你对此事的看法。
希望这有帮助。
答案 2 :(得分: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 XPath=@Name}"/>
</DataTemplate>
</Grid.Resources>
然后我只是更改顺序并将Grid.Resources放在Listbox之前,如下所示,现在一切都很好!!!
<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不是那么愚蠢吗? :):)
答案 3 :(得分: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>