Я пытаюсь узнать что-то о WPF, и я вполне поражен его гибкостью.
Однако я поразил проблему с Style
s и DataTemplate
s, который немного сбивает с толку. Я определил ниже тестовой страницы для проигрывания вокруг немного со стилями и т.д. и нашел что Style
s определенный в <Page.Resources>
для Border
и TextBlock
не применяются в 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 применяются и некоторые нет. Я не могу найти легкое объяснение вышеупомянутого нигде и таким образом хотел бы спросить, будет ли кто-то достаточно любезен для объяснения этого поведения в терминах lamen с возможными ссылками на техническое описание, т.е. на MSDN или около этого.
Заранее спасибо за Вас поддерживает!
Это на самом деле задумано. Элементы, которые не являются производными от Control, не будут использовать неявные стили, если они не находятся в ресурсах приложения.
Эта ссылка объясняет это более подробно, или вы можете просмотреть отчет об ошибке Connent .
Я тоже разбирался в этом, и лично считаю, что это ошибка. Я заметил, что стиль устанавливается, если вы назовете свои стили так:
<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 ...
Это происходит потому, что ListBox является логическим родителем элементов шаблона данных, теперь помните, что все свойства, которые "наследуются", такие как font, forecolor и т.д., являются производными от логического родителя, а ListBox уже переопределяет их в своем собственном стиле по умолчанию, поэтому это не сработает. Однако в этом случае вы можете использовать именованные стили, как предложил г-н Дейв, но я думаю, что если это не работает, то это известная проблема в случае ListBox и т.д. Вы можете обратиться к моему вопросу здесь, у меня была подобная проблема в Listbox, и ответы в моем вопросе более подробны.