Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF Some styles not applied on DataTemplate controls

I am trying to learn something about WPF and I am quite amazed by its flexibility.

However, I have hit a problem with Styles and DataTemplates, which is little bit confusing. I have defined below test page to play around a bit with styles etc and found that the Styles defined in <Page.Resources> for Border and TextBlock are not applied in the DataTemplate, but Style for ProgressBar defined in exactly the same way is applied.

Source code (I just use Kaxaml and XamlPadX to view the result)

<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> 

I suspect it has something to do with default styles etc, but more puzzling is why some Styles are applied and some not. I cannot find an easy explanation for above anywhere and thus would like to ask if someone would be kind enough to explain this behaviour in lamens' terms with possible links to technical description, i.e. to MSDN or so.

Thanks in advance for you support!

like image 804
Martin Avatar asked Mar 19 '10 09:03

Martin


2 Answers

I discovered a simple workaround for this. For any elements that are not able to search outside the data template encapsulation boundary (i.e. are not being implicitly styled), you can just declare an empty style within the data template for that element type and use the BasedOn attribute of the style to find the correct implicit style outside the data template to apply.

In the example below, the TextBox is able to search outside the data template encapsulation boundary (because it inherits from Control?), but the TextBlock is not able to, so I declare the empty style for it which can search outside the data template.

<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> 
like image 89
Brian Hinchey Avatar answered Oct 09 '22 02:10

Brian Hinchey


This is actually by design. Elements that do not derive from Control will not pick up implicit Styles, unless they are in the application resources.

This link explains this in more detail, or you can view the Connent bug report.

like image 29
CodeNaked Avatar answered Oct 09 '22 03:10

CodeNaked