这是第一个使用WPF和Styles的项目。 开发工具是VS2010。
我有以下样式定义:
<!-- 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>
然后在我的MainWindow.xaml中包括:
<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 HTabDBase}">
</TabItem>
</TabControl>
</TabItem>
<TabItem x:Name="tabLeftHistory" Style="{StaticResource LTabHistory}">
<TabControl Height="Auto" Name="tabTopHistory" Width="Auto">
<TabItem x:Name="tabTopHistoryGridView" Style="{StaticResource HTabDBase}" >
</TabItem>
</TabControl>
</TabItem>
在设计时,样式提供了我想要的外观,但在运行时我得到一个例外:
&#39;设置属性&#39; System.Windows.FrameworkElement.Style&#39;抛出异常。&#39;
指向哪一行:
<TabItem x:Name="tabTopEquipmentGridView" Style="{StaticResource HTabDBase}">
请帮助找到异常原因...谢谢!
我详细了解了以下内容,但仍然无法确定导致问题纠正的元素。
Message=Specified element is already the logical child of another element. Disconnect it first.
答案 0 :(得分:1)
我第一次读到它时没有掌握解决方案,但找到了最后的线索:
使用Template属性和ControlTemplate,而不是将样式应用于Header属性,可以防止出现问题。
修改后的样式代码
<!-- 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>
<Style TargetType="{x:Type Image}" x:Key="VTabImage">
<Setter Property="Height" Value="36" />
<Setter Property="Width" Value="36" />
<Setter Property="Margin" Value="0,5,0,0" />
</Style>
<!-- Sub Style Setting-->
<Style TargetType="{x:Type TabItem}" x:Key="LTabEquipment" BasedOn="{StaticResource TabItemBase}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<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>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type TabItem}" x:Key="LTabHistory" BasedOn="{StaticResource TabItemBase}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<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>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type TabItem}" x:Key="HTabDBase" BasedOn="{StaticResource TabItemBase}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<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>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
然而,这不是一个理想的解决方案; 因为使用ControlTemplate会删除原始控件的所有默认样式和操作。
仍在寻找更好的解决方案。
答案 1 :(得分:1)
答案 2 :(得分:0)
我找到了另一种不触发异常的方法,但也不喜欢这个。
当HTabDBase样式应用于应用程序中的多个TabItem时,似乎会发生异常。
为了证明这一点,我复制/粘贴了两个副本并将其密钥更改为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>
然后在MainWindow.xaml:
<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>
但是这个解决方案似乎打败了创建风格的大部分目的; 即我创建的样式可以在任何位置重用它,但在多个位置使用它会导致运行时错误。