Wpf 找不到名为';X';,为什么不呢?

Wpf 找不到名为';X';,为什么不呢?,wpf,xaml,mvvm,Wpf,Xaml,Mvvm,我想为库存管理创建一个向导UI。xaml中的相关行是: “当前”是当前活动的视图模型,是可用的InventoriesViewModel、GroupsViewModel、NewArticlesViewModel和ResultViewModel之一。我定义的DataTemplateSelector如下: 使用系统诊断; 使用System.Windows; 使用System.Windows.Controls; 使用Centron.WPF.WarehousingExtension.Inventory

我想为库存管理创建一个向导UI。xaml中的相关行是:


“当前”是当前活动的视图模型,是可用的InventoriesViewModel、GroupsViewModel、NewArticlesViewModel和ResultViewModel之一。我定义的DataTemplateSelector如下:

使用系统诊断;
使用System.Windows;
使用System.Windows.Controls;
使用Centron.WPF.WarehousingExtension.InventoryModule.ViewModels.WizardViewModels;
命名空间Centron.WPF.WarehousingExtension.InventoryModule.UI.DataTemplateSelectors
{
公共类清单DataTemplateSelector:DataTemplateSelector
{
公共数据模板可用数据类型{get;set;}
公共数据模板GroupsDatatype{get;set;}
公共数据模板NewDatatype{get;set;}
公共数据模板ResultDatatype{get;set;}
公共资源清册DataTemplateSelector()
{
Debug.WriteLine(“”);
}
公共覆盖数据模板SelectTemplate(对象项,DependencyObject容器)
{
如果(项目可用InventoriesViewModel)
返回可用的状态类型;
else if(项目为GroupsViewModel)
返回组数据类型;
else if(项目为NewArticlesViewModel)
返回NewDatatype;
否则返回ResultDatatype;
}
}
}
然后创建DataTemplates的实例和选择器,如下所示:


我在InventoryDatatemplateSelector的构造函数中设置了一个断点,可以单步执行,但在下一个调试步骤中,显然当它试图设置该选择器实例的第一个属性时,我立即得到一个内部异常的异常:

找不到名为“availableInventoriesDatatype\”的资源。资源名称区分大小写


这是怎么回事,为什么在明确定义资源时找不到它?

好的,我找到了解决方案。唯一的错误是必须首先设置资源的“Key”属性。因此,不是:

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

我需要:

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

我知道你发现了问题,但有一种更简单的方法可以解决这个问题,我想你应该知道。由于每个DataTemplates都在不同的类上工作,因此不需要构建DataTemplateSelector来实现这一点。如果只声明数据模板而不使用以下键:

<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>
然后,将为
Current
设置为的任何类型选择适当的数据模板

这是一个更干净的解决方案,不需要自定义选择器

WPF功能强大且非常灵活,但要想让你的脑袋紧紧围绕着它,可能会很有挑战性。但一旦你明白了它能做什么,我想你会改变你对这件事的看法


希望这能有所帮助。

这是我的案例-我在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>
        <!-- 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不是很愚蠢吗?:):)

我给出了嵌套组件样式的更多细节。在本例中,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>

0,0,0,10
10
#005C9D
#E3672B
#777777
#E4
现在,如果您交换声明序列,使MainWindowGrid最后一个,它将工作。(外部范围,最后一个)


0,0,0,10
10
#005C9D
#E3672B
#777777
#E4

这太愚蠢了。我非常讨厌xaml。xaml太棒了,你的评论无效。我不知道你为什么还要费心使用静态资源,而你本可以在数据模板选择器中内联定义它们。还有,你这样做有点奇怪。内容控件将自动在资源中搜索具有给定类型的第一个数据模板,因此如果每个模板都与特定类型匹配,则您可能已经放弃了选择器type@Will我试过你的方法。我从DataTemplates中删除了Key属性,并且在ContentPresenter上没有使用任何选择器。现在,ContentPresenter中显示的所有内容都是Current.ToString(),而不是实际控件。如果我将数据模板放在ContentPresenter.Resources中,也会发生这种情况。这看起来确实很愚蠢。属性顺序在XML中并不重要,因为XAML是基于XML的,我不认为属性顺序会有什么影响。对我来说,XAML有VB6环,我已经做了大量的这两件事。有几件事你可能不知道导致了这个问题。首先,xaml(除了极少数例外)从上到下解析并转换为对象图。这意味着秩序是重要的。其次,DataTemplates的设计使它们能够根据
数据类型为自己分配一个键,这(本质上)取代了x:Key属性。因此,如果您想使用数据类型(在使用时完全不需要)和x:Key来定义一个数据模板,那么必须首先放置x:Key。是的,令人困惑,但这是使DTs更易于使用的结果。您能否提供将多个数据模板分配给单个ContentPresenter的完整基本代码?我已尝试将多个DataTemplates分配给ContentPresenter.ContentTemplate属性,但只能设置一次。这给了我一个错误:
<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>
<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>