2010-03-19 31 views
25

我想了解一些关于WPF的内容,我很惊讶它的灵活性。WPF一些样式不适用于DataTemplate控件

但是,我遇到了Style s和DataTemplate s的问题,这有点令人困惑。 我在下面的测试页定义为与周围风格等有点玩,发现<Page.Resources>定义的Style S代表BorderTextBlock没有在DataTemplate应用,但Style在完全相同的方式定义ProgressBar应用。

的源代码(我只是用Kaxaml和XamlPadX查看结果)

<Page 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 

    <Page.Resources> 

    <Style TargetType="{x:Type Border}"> 
     <Setter Property="Background" Value="SkyBlue"/> 
     <Setter Property="BorderBrush" Value="Black"/> 
     <Setter Property="BorderThickness" Value="2"/> 
     <Setter Property="CornerRadius" Value="5"/> 
    </Style> 

    <Style TargetType="{x:Type TextBlock}"> 
     <Setter Property="FontWeight" Value="Bold"/> 
    </Style> 

    <Style TargetType="{x:Type ProgressBar}"> 
     <Setter Property="Height" Value="10"/> 
     <Setter Property="Width" Value="100"/> 
     <Setter Property="Foreground" Value="Red"/> 
    </Style> 

    <XmlDataProvider x:Key="TestData" XPath="/TestData"> 
     <x:XData> 
     <TestData xmlns=""> 
      <TestElement> 
      <Name>Item 1</Name> 
      <Value>25</Value> 
      </TestElement> 
      <TestElement> 
      <Name>Item 2</Name> 
      <Value>50</Value> 
      </TestElement> 
     </TestData> 
     </x:XData> 
    </XmlDataProvider> 

    <HierarchicalDataTemplate DataType="TestElement"> 
     <Border Height="45" Width="120" Margin="5,5"> 
     <StackPanel Orientation="Vertical" Margin="5,5" VerticalAlignment="Center" HorizontalAlignment="Center"> 
      <TextBlock HorizontalAlignment="Center" Text="{Binding XPath=Name}"/> 
      <ProgressBar Value="{Binding XPath=Value}"/> 
     </StackPanel> 
     </Border> 
    </HierarchicalDataTemplate> 

    </Page.Resources> 

    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center"> 
    <StackPanel Orientation="Vertical" VerticalAlignment="Center"> 
     <Border Height="45" Width="120" Margin="5,5"> 
     <StackPanel Orientation="Vertical" VerticalAlignment="Center" HorizontalAlignment="Center"> 
      <TextBlock HorizontalAlignment="Center" Text="Item 1"/> 
      <ProgressBar Value="25"/> 
     </StackPanel> 
     </Border> 
     <Border Height="45" Width="120" Margin="5,5"> 
     <StackPanel Orientation="Vertical" VerticalAlignment="Center" HorizontalAlignment="Center"> 
      <TextBlock HorizontalAlignment="Center" Text="Item 2"/> 
      <ProgressBar Value="50"/> 
     </StackPanel> 
     </Border> 
    </StackPanel> 
    <ListBox Margin="10,10" Width="140" ItemsSource="{Binding Source={StaticResource TestData}, XPath=TestElement}"/> 
    </StackPanel> 
</Page> 

我怀疑它是与默认样式等,但更令人费解的是,为什么被应用于一些Style S和一些不。我无法在上面找到一个简单的解释,因此想问一下,如果有人愿意用拉曼的话来解释这种行为,并且可能与技术描述(即MSDN)等有关。

在此先感谢您的支持!

回答

27

这实际上是通过设计。除非它们在应用程序资源中,否则不从Control派生的元素不会选取隐式样式。

link更详细地解释了这一点,或者您可以查看Connent bug report

+0

感谢您的链接! 它解释了发生了什么,但仍然链接到官方文档将很好,只是我知道在哪里寻找这样的事情。 – Martin 2010-03-20 06:34:04

+0

添加链接到Microsoft的Connect站点上的错误报告,不确定是否有任何官方文档描述此行为。 – CodeNaked 2010-03-24 15:37:08

+0

现在这两个链接都死了。找到[第一个wayback链接](https://web.archive.org/web/20170201072114/http://www.11011.net/archives/000692.html)。如果你喜欢,请将它添加到你的答案中。 – itsho 2017-09-27 07:25:37

3

我也研究过这个,我个人认为这是一个错误。我注意到,如果你的名字你的风格,像这样的样式设置:

<Style x:Key="BorderStyle" TargetType="{x:Type Border}"> 
etc... 

,并明确设置您的DataTemplate使用这些样式:

<HierarchicalDataTemplate DataTemplate="TestElement"> 
    <Border Height="45" Width="120" Margin="5,5", Style="{StaticResource BorderStyle}"> 

我认为,这可能是对的DataTemplates(也可能是ControlTemplates),它们默认为具有空样式,除非您明确设置它们。

这对我来说并不意味着发生 - 它不是WPF的工作逻辑的方式...

0

这是因为列表框是你的DataTemplate项目的逻辑父,现在还记得,所有属性这些都是“可继承“像字体,前景色等等,都是从逻辑父项派生而来,而ListBox已经在它自己的默认样式中重写了它,这就是为什么这不起作用。然而,在这种情况下,你可以使用戴夫先生建议的命名样式,但我认为如果它不起作用,那么这是列表框等的已知问题,你可以参考我的问题here, i had similar problem in listbox,并在答案中我的问题更详细。

23

我发现了一个简单的解决方法。对于任何无法在数据模板封装边界之外进行搜索的元素(即未隐式设计),可以在数据模板中为该元素类型声明一个空样式,并使用该样式的BasedOn属性来查找更正数据模板外部的隐式样式以应用。

在下面的例子中,TextBox能够在数据模板封装边界之外进行搜索(因为它继承自Control?),但是TextBlock不能,所以我声明它的空格式,其中可以在数据模板之外搜索。

<ItemsControl.ItemTemplate> 
    <DataTemplate> 
     <DataTemplate.Resources> 
      <Style TargetType="TextBlock" BasedOn="{StaticResource {x:Type TextBlock}}" /> 
     </DataTemplate.Resources> 
     <DockPanel> 
      <TextBlock Text="{Binding Name}" /> 
      <TextBox Text="{Binding Value}" /> 
     </DockPanel> 
    </DataTemplate> 
</ItemsControl.ItemTemplate> 
相关问题