I recently read Josh Smith's post on codeproject which explained how to use a Slider control to dynamically apply a WPF data template a runtime. If you haven't read it, I suggest you read it before continuing.
So I have come up with an alternative solution which is done in pure XAML. This is a technique which I have used on previous projects and it involves creating a "surrogate" data template which simply passes control to another data template via a content presenter. Because a data template is used to do this, it has access to the inheritance context so does not require any freezable hacks to find the slider or other data templates.
Note that in order to make this a pure xaml solution I replaced the data source (which was originally in code) with an XmlDataProvider nested in the XAML document. Hence that lovely Pam girl does not appear in my version, which will probably disappoint most people...
Anyway check it out below, simple copy and paste in XamlPad/Kaxaml to see it working!
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <DockPanel> <DockPanel.Resources> <XmlDataProvider x:Key="Data" XPath="/people"> <x:XData> <people xmlns=""> <person name="Neil" age="29" gender="M" /> <person name="Jane" age="40" gender="F" /> <person name="Jack" age="23" gender="M" /> </people> </x:XData> </XmlDataProvider> <DataTemplate x:Key="LowTemplate"> <TextBlock Text="{Binding XPath=@name}" /> </DataTemplate> <DataTemplate x:Key="MediumTemplate"> <TextBlock> <TextBlock Text="{Binding XPath=@name}" /> <Run>(</Run> <TextBlock Text="{Binding XPath=@age}" Margin="-4,0" /> <Run>)</Run> </TextBlock> </DataTemplate> <DataTemplate x:Key="HighTemplate"> <TextBlock> <TextBlock Text="{Binding XPath=@name}" /> <Run>(</Run> <TextBlock Text="{Binding XPath=@age}" Margin="-4,0" /> <Run>) -</Run> <TextBlock Text="{Binding XPath=@gender}" /> </TextBlock> </DataTemplate> <DataTemplate x:Key="SelectorTemplate"> <Grid> <ContentPresenter x:Name="lowPresenter" Content="{Binding}" ContentTemplate="{StaticResource LowTemplate}" Visibility="Collapsed" /> <ContentPresenter x:Name="mediumPresenter" Content="{Binding}" ContentTemplate="{StaticResource MediumTemplate}" Visibility="Collapsed" /> <ContentPresenter x:Name="highPresenter" Content="{Binding}" ContentTemplate="{StaticResource HighTemplate}" Visibility="Collapsed" /> </Grid> <DataTemplate.Triggers> <DataTrigger Binding="{Binding ElementName=detailLevelSlider, Path=Value}" Value="1"> <Setter TargetName="lowPresenter" Property="Visibility" Value="Visible" /> </DataTrigger> <DataTrigger Binding="{Binding ElementName=detailLevelSlider, Path=Value}" Value="2"> <Setter TargetName="mediumPresenter" Property="Visibility" Value="Visible" /> </DataTrigger> <DataTrigger Binding="{Binding ElementName=detailLevelSlider, Path=Value}" Value="3"> <Setter TargetName="highPresenter" Property="Visibility" Value="Visible" /> </DataTrigger> </DataTemplate.Triggers> </DataTemplate> </DockPanel.Resources> <StackPanel DockPanel.Dock="Bottom" Background="LightGray" Margin="4" Orientation="Horizontal" > <TextBlock Margin="2,0,4,0" Text="Detail Level:" VerticalAlignment="Center" /> <Slider x:Name="detailLevelSlider" DockPanel.Dock="Bottom" Minimum="1" Maximum="3" SmallChange="1" LargeChange="1" IsSnapToTickEnabled="True" TickFrequency="1" Value="0" Width="120" /> </StackPanel> <ScrollViewer> <ItemsControl ItemsSource="{Binding Source={StaticResource Data}, XPath=person}" ItemTemplate="{StaticResource SelectorTemplate}" /> </ScrollViewer> </DockPanel> </Page>
2 comments:
I miss Pam already!! :D
Great post, Neil.
-Josh
Grreat blog post
Post a Comment