Wpf 应用样式时发生XamlParse异常

Wpf 应用样式时发生XamlParse异常,wpf,Wpf,这是第一个使用WPF和样式的项目。 开发工具是VS2010 <Style TargetType="{x:Type TabItem}" x:Key="HTabDBase2" BasedOn="{StaticResource TabItemBase}"> <Setter Property="Header"> <Setter.Value> <StackPanel Orientation="Horizontal"&

这是第一个使用WPF和样式的项目。 开发工具是VS2010

<Style TargetType="{x:Type TabItem}" x:Key="HTabDBase2" BasedOn="{StaticResource TabItemBase}">
    <Setter Property="Header">
        <Setter.Value>
            <StackPanel Orientation="Horizontal">
                <Image Height="14" Source="pack://application:,,,/Images/dbase.png" Width="14" Margin="0,0,0,0" HorizontalAlignment="stretch" VerticalAlignment="stretch" />
                <TextBlock Text="grid view" Margin="2,0,0,0" VerticalAlignment="center" HorizontalAlignment="center" />
            </StackPanel>
        </Setter.Value>
    </Setter>
</Style>
我有以下样式定义:

<!-- Base Style Setting-->
<Style TargetType="{x:Type TabControl}" x:Key="TabControlBase">
    <Setter Property="Height" Value="Auto" />
    <Setter Property="Width"  Value="Auto" />
</Style>

<Style TargetType="{x:Type TabItem}" x:Key="TabItemBase">
    <Setter Property="Cursor" Value="Hand" />
</Style>

<!-- Sub Style Setting-->
<Style TargetType="{x:Type TabItem}" x:Key="LTabEquipment" BasedOn="{StaticResource TabItemBase}">
    <Setter Property="Header">
        <Setter.Value>
            <StackPanel Orientation="Vertical">
                <Image Height="36" Source="pack://application:,,,/Images/gears.png" Width="36" Margin="0,5,0,0" />
                <TextBlock Text="Equipment" Margin="2,0,0,0" VerticalAlignment="Bottom" HorizontalAlignment="Center" />
            </StackPanel>
        </Setter.Value>
    </Setter>
</Style>

<Style TargetType="{x:Type TabItem}" x:Key="LTabHistory" BasedOn="{StaticResource TabItemBase}">
    <Setter Property="Header">
        <Setter.Value>
            <StackPanel Orientation="Vertical">
                <Image Height="36" Source="pack://application:,,,/Images/history.png" Width="36" Margin="0,5,0,0" />
                <TextBlock Text="History" Margin="2,0,0,0" VerticalAlignment="Bottom" HorizontalAlignment="Center" />
            </StackPanel>
        </Setter.Value>
    </Setter>
</Style>

<Style TargetType="{x:Type TabItem}" x:Key="HTabDBase" BasedOn="{StaticResource TabItemBase}">
    <Setter Property="Header">
        <Setter.Value>
            <StackPanel Orientation="Horizontal">
                <Image Height="14" Source="pack://application:,,,/Images/dbase.png" Width="14" Margin="0,0,0,0" HorizontalAlignment="stretch" VerticalAlignment="stretch" />
                <TextBlock Text="grid view" Margin="2,0,0,0" VerticalAlignment="center" HorizontalAlignment="center" />
            </StackPanel>
        </Setter.Value>
    </Setter>    
</Style>
<Style TargetType="{x:Type TabItem}" x:Key="HTabDBase2" BasedOn="{StaticResource TabItemBase}">
    <Setter Property="Header">
        <Setter.Value>
            <StackPanel Orientation="Horizontal">
                <Image Height="14" Source="pack://application:,,,/Images/dbase.png" Width="14" Margin="0,0,0,0" HorizontalAlignment="stretch" VerticalAlignment="stretch" />
                <TextBlock Text="grid view" Margin="2,0,0,0" VerticalAlignment="center" HorizontalAlignment="center" />
            </StackPanel>
        </Setter.Value>
    </Setter>
</Style>

<Style TargetType="{x:Type TabItem}" x:Key="HTabDBase2" BasedOn="{StaticResource TabItemBase}">
    <Setter Property="Header">
        <Setter.Value>
            <StackPanel Orientation="Horizontal">
                <Image Height="14" Source="pack://application:,,,/Images/dbase.png" Width="14" Margin="0,0,0,0" HorizontalAlignment="stretch" VerticalAlignment="stretch" />
                <TextBlock Text="grid view" Margin="2,0,0,0" VerticalAlignment="center" HorizontalAlignment="center" />
            </StackPanel>
        </Setter.Value>
    </Setter>
</Style>

我第一次读的时候没有掌握答案,但在以下内容中找到了最后的线索:

<Style TargetType="{x:Type TabItem}" x:Key="HTabDBase2" BasedOn="{StaticResource TabItemBase}">
    <Setter Property="Header">
        <Setter.Value>
            <StackPanel Orientation="Horizontal">
                <Image Height="14" Source="pack://application:,,,/Images/dbase.png" Width="14" Margin="0,0,0,0" HorizontalAlignment="stretch" VerticalAlignment="stretch" />
                <TextBlock Text="grid view" Margin="2,0,0,0" VerticalAlignment="center" HorizontalAlignment="center" />
            </StackPanel>
        </Setter.Value>
    </Setter>
</Style>

<Style TargetType="{x:Type TabItem}" x:Key="HTabDBase2" BasedOn="{StaticResource TabItemBase}">
    <Setter Property="Header">
        <Setter.Value>
            <StackPanel Orientation="Horizontal">
                <Image Height="14" Source="pack://application:,,,/Images/dbase.png" Width="14" Margin="0,0,0,0" HorizontalAlignment="stretch" VerticalAlignment="stretch" />
                <TextBlock Text="grid view" Margin="2,0,0,0" VerticalAlignment="center" HorizontalAlignment="center" />
            </StackPanel>
        </Setter.Value>
    </Setter>
</Style>
使用Template属性和ControlTemplate,而不是将样式应用于Header属性,可以防止出现问题

<Style TargetType="{x:Type TabItem}" x:Key="HTabDBase2" BasedOn="{StaticResource TabItemBase}">
    <Setter Property="Header">
        <Setter.Value>
            <StackPanel Orientation="Horizontal">
                <Image Height="14" Source="pack://application:,,,/Images/dbase.png" Width="14" Margin="0,0,0,0" HorizontalAlignment="stretch" VerticalAlignment="stretch" />
                <TextBlock Text="grid view" Margin="2,0,0,0" VerticalAlignment="center" HorizontalAlignment="center" />
            </StackPanel>
        </Setter.Value>
    </Setter>
</Style>
修订的样式代码

<Style TargetType="{x:Type TabItem}" x:Key="HTabDBase2" BasedOn="{StaticResource TabItemBase}">
    <Setter Property="Header">
        <Setter.Value>
            <StackPanel Orientation="Horizontal">
                <Image Height="14" Source="pack://application:,,,/Images/dbase.png" Width="14" Margin="0,0,0,0" HorizontalAlignment="stretch" VerticalAlignment="stretch" />
                <TextBlock Text="grid view" Margin="2,0,0,0" VerticalAlignment="center" HorizontalAlignment="center" />
            </StackPanel>
        </Setter.Value>
    </Setter>
</Style>

<Style TargetType="{x:Type TabItem}" x:Key="HTabDBase2" BasedOn="{StaticResource TabItemBase}">
    <Setter Property="Header">
        <Setter.Value>
            <StackPanel Orientation="Horizontal">
                <Image Height="14" Source="pack://application:,,,/Images/dbase.png" Width="14" Margin="0,0,0,0" HorizontalAlignment="stretch" VerticalAlignment="stretch" />
                <TextBlock Text="grid view" Margin="2,0,0,0" VerticalAlignment="center" HorizontalAlignment="center" />
            </StackPanel>
        </Setter.Value>
    </Setter>
</Style>

<Style TargetType="{x:Type TabItem}" x:Key="HTabDBase2" BasedOn="{StaticResource TabItemBase}">
    <Setter Property="Header">
        <Setter.Value>
            <StackPanel Orientation="Horizontal">
                <Image Height="14" Source="pack://application:,,,/Images/dbase.png" Width="14" Margin="0,0,0,0" HorizontalAlignment="stretch" VerticalAlignment="stretch" />
                <TextBlock Text="grid view" Margin="2,0,0,0" VerticalAlignment="center" HorizontalAlignment="center" />
            </StackPanel>
        </Setter.Value>
    </Setter>
</Style>
然而,这不是一个理想的解决方案 使用ControlTemplate将删除原始控件的所有默认样式和操作

<Style TargetType="{x:Type TabItem}" x:Key="HTabDBase2" BasedOn="{StaticResource TabItemBase}">
    <Setter Property="Header">
        <Setter.Value>
            <StackPanel Orientation="Horizontal">
                <Image Height="14" Source="pack://application:,,,/Images/dbase.png" Width="14" Margin="0,0,0,0" HorizontalAlignment="stretch" VerticalAlignment="stretch" />
                <TextBlock Text="grid view" Margin="2,0,0,0" VerticalAlignment="center" HorizontalAlignment="center" />
            </StackPanel>
        </Setter.Value>
    </Setter>
</Style>

仍然在寻找更好的解决方案。

我找到了另一种不触发异常的方法,但也不喜欢这种方法

<Style TargetType="{x:Type TabItem}" x:Key="HTabDBase2" BasedOn="{StaticResource TabItemBase}">
    <Setter Property="Header">
        <Setter.Value>
            <StackPanel Orientation="Horizontal">
                <Image Height="14" Source="pack://application:,,,/Images/dbase.png" Width="14" Margin="0,0,0,0" HorizontalAlignment="stretch" VerticalAlignment="stretch" />
                <TextBlock Text="grid view" Margin="2,0,0,0" VerticalAlignment="center" HorizontalAlignment="center" />
            </StackPanel>
        </Setter.Value>
    </Setter>
</Style>
当HTabDBase样式应用于应用程序中的多个TabItem时,似乎会发生异常

<Style TargetType="{x:Type TabItem}" x:Key="HTabDBase2" BasedOn="{StaticResource TabItemBase}">
    <Setter Property="Header">
        <Setter.Value>
            <StackPanel Orientation="Horizontal">
                <Image Height="14" Source="pack://application:,,,/Images/dbase.png" Width="14" Margin="0,0,0,0" HorizontalAlignment="stretch" VerticalAlignment="stretch" />
                <TextBlock Text="grid view" Margin="2,0,0,0" VerticalAlignment="center" HorizontalAlignment="center" />
            </StackPanel>
        </Setter.Value>
    </Setter>
</Style>
为了证明这一点,我复制/粘贴了两个副本,并将它们的密钥更改为HTabDBase1和HTabDBase2。然后我分别申请了每一项。除了键之外,样式定义是相同的

<Style TargetType="{x:Type TabItem}" x:Key="HTabDBase2" BasedOn="{StaticResource TabItemBase}">
    <Setter Property="Header">
        <Setter.Value>
            <StackPanel Orientation="Horizontal">
                <Image Height="14" Source="pack://application:,,,/Images/dbase.png" Width="14" Margin="0,0,0,0" HorizontalAlignment="stretch" VerticalAlignment="stretch" />
                <TextBlock Text="grid view" Margin="2,0,0,0" VerticalAlignment="center" HorizontalAlignment="center" />
            </StackPanel>
        </Setter.Value>
    </Setter>
</Style>

<Style TargetType="{x:Type TabItem}" x:Key="HTabDBase2" BasedOn="{StaticResource TabItemBase}">
    <Setter Property="Header">
        <Setter.Value>
            <StackPanel Orientation="Horizontal">
                <Image Height="14" Source="pack://application:,,,/Images/dbase.png" Width="14" Margin="0,0,0,0" HorizontalAlignment="stretch" VerticalAlignment="stretch" />
                <TextBlock Text="grid view" Margin="2,0,0,0" VerticalAlignment="center" HorizontalAlignment="center" />
            </StackPanel>
        </Setter.Value>
    </Setter>
</Style>

然后在MainWindow.xaml中:

<Style TargetType="{x:Type TabItem}" x:Key="HTabDBase2" BasedOn="{StaticResource TabItemBase}">
    <Setter Property="Header">
        <Setter.Value>
            <StackPanel Orientation="Horizontal">
                <Image Height="14" Source="pack://application:,,,/Images/dbase.png" Width="14" Margin="0,0,0,0" HorizontalAlignment="stretch" VerticalAlignment="stretch" />
                <TextBlock Text="grid view" Margin="2,0,0,0" VerticalAlignment="center" HorizontalAlignment="center" />
            </StackPanel>
        </Setter.Value>
    </Setter>
</Style>
<TabControl Grid.Row="2" Name="tabLeft" TabStripPlacement="Left">
    <TabItem x:Name="tabLeftEquipment" Style="{StaticResource LTabEquipment}">
        <TabControl Style="{StaticResource TabControlBase}" Name="tabTopEquipment" >
            <TabItem x:Name="tabTopEquipmentGridView" Style="{StaticResource HTabDBase1}">
            </TabItem>
        </TabControl>
    </TabItem>
    <TabItem x:Name="tabLeftHistory" Style="{StaticResource LTabHistory}">
        <TabControl Height="Auto" Name="tabTopHistory" Width="Auto">
            <TabItem x:Name="tabTopHistoryGridView" Style="{StaticResource HTabDBase2}" >
            </TabItem>
        </TabControl>
    </TabItem>

但是这个解决方案似乎在很大程度上挫败了创建风格的初衷
i、 e.我创建样式是为了能够在任何位置重用它,但是在多个位置使用它会导致运行时错误。

您可以通过在包含
图像的样式中使用
x:Shared=“False”
来修复此问题。默认情况下,所有资源都有
x:Shared=“True”
,这意味着WPF只创建每个资源的一个实例。因此,当任何对象使用
StaticResource
或其他方法请求资源时,都会返回该实例,而不是创建新实例。这在您的案例中会导致问题,因为:

<Style TargetType="{x:Type TabItem}" x:Key="HTabDBase2" BasedOn="{StaticResource TabItemBase}">
    <Setter Property="Header">
        <Setter.Value>
            <StackPanel Orientation="Horizontal">
                <Image Height="14" Source="pack://application:,,,/Images/dbase.png" Width="14" Margin="0,0,0,0" HorizontalAlignment="stretch" VerticalAlignment="stretch" />
                <TextBlock Text="grid view" Margin="2,0,0,0" VerticalAlignment="center" HorizontalAlignment="center" />
            </StackPanel>
        </Setter.Value>
    </Setter>
</Style>
<TabItem x:Name="tabTopEquipmentGridView" Style="{StaticResource HTabDBase}">
</TabItem>
再次设置样式,这意味着您将相同的图像实例放在tabItem的视觉树中。但是映像已经有一个父项=>将引发异常,因为
UIElements
只能有一个父项

<Style TargetType="{x:Type TabItem}" x:Key="HTabDBase2" BasedOn="{StaticResource TabItemBase}">
    <Setter Property="Header">
        <Setter.Value>
            <StackPanel Orientation="Horizontal">
                <Image Height="14" Source="pack://application:,,,/Images/dbase.png" Width="14" Margin="0,0,0,0" HorizontalAlignment="stretch" VerticalAlignment="stretch" />
                <TextBlock Text="grid view" Margin="2,0,0,0" VerticalAlignment="center" HorizontalAlignment="center" />
            </StackPanel>
        </Setter.Value>
    </Setter>
</Style>
样式并不用于设置控件的内容。样式应该会更改其属性。但是
x:Shared=False
修复了它:)

<Style TargetType="{x:Type TabItem}" x:Key="HTabDBase2" BasedOn="{StaticResource TabItemBase}">
    <Setter Property="Header">
        <Setter.Value>
            <StackPanel Orientation="Horizontal">
                <Image Height="14" Source="pack://application:,,,/Images/dbase.png" Width="14" Margin="0,0,0,0" HorizontalAlignment="stretch" VerticalAlignment="stretch" />
                <TextBlock Text="grid view" Margin="2,0,0,0" VerticalAlignment="center" HorizontalAlignment="center" />
            </StackPanel>
        </Setter.Value>
    </Setter>
</Style>
另一种更优雅的方式是设置
标题模板
,而不是设置
标题
。因为样式应该更改属性,所以它可以更改内容模板,对吗?是的,它可以。(注意
ContentTemplate
而不是
Template
,它是控件本身的模板。这是您在回答中设置的。如果您只想“设置”内容的样式,则应改为设置ContentTemplate。)示例:

<Style TargetType="{x:Type TabItem}" x:Key="HTabDBase2" BasedOn="{StaticResource TabItemBase}">
    <Setter Property="Header">
        <Setter.Value>
            <StackPanel Orientation="Horizontal">
                <Image Height="14" Source="pack://application:,,,/Images/dbase.png" Width="14" Margin="0,0,0,0" HorizontalAlignment="stretch" VerticalAlignment="stretch" />
                <TextBlock Text="grid view" Margin="2,0,0,0" VerticalAlignment="center" HorizontalAlignment="center" />
            </StackPanel>
        </Setter.Value>
    </Setter>
</Style>
<Setter Property="HeaderTemplate">
    <Setter.Value>
        <DataTemplate>
            <StackPanel Orientation="Vertical">
                <Image Height="36" Width="36" Margin="0,5,0,0" />
                <TextBlock Text="History" Margin="2,0,0,0" VerticalAlignment="Bottom" HorizontalAlignment="Center" />
            </StackPanel>
        </DataTemplate>
    </Setter.Value>
</Setter>


因此,您不再需要
x:Shared
<代码>模板
s不会遇到相同的问题,因为它不是共享的。将为每个元素创建一个新的模板实例。

您确定图像源路径在运行时是正确的吗?到目前为止,我得到的最好线索是它与HTabDBase有关,或者HTabDBase正在多个位置应用。@ashur668我已经按原样使用了您的代码,它工作得非常好。我在
窗口中定义了所有样式。你肯定在代码中做了其他事情。同意,我过度简化了我的原始条目。当在多个TabItem中使用HTabDBase样式时,mainfest会遇到这个问题。我在MainWindow.xaml.Fantastic中修改了上面的代码示例!使用HeaderTemplate非常有效,您对X:Shared的解释也非常好。非常感谢你!
<Style TargetType="{x:Type TabItem}" x:Key="HTabDBase2" BasedOn="{StaticResource TabItemBase}">
    <Setter Property="Header">
        <Setter.Value>
            <StackPanel Orientation="Horizontal">
                <Image Height="14" Source="pack://application:,,,/Images/dbase.png" Width="14" Margin="0,0,0,0" HorizontalAlignment="stretch" VerticalAlignment="stretch" />
                <TextBlock Text="grid view" Margin="2,0,0,0" VerticalAlignment="center" HorizontalAlignment="center" />
            </StackPanel>
        </Setter.Value>
    </Setter>
</Style>