How can i set different names to DataTemplate elements? - wpf

i'm making something like TicTacToeGame, trying to use MVVM and at this point i faced a problem. I can't understand how can i (if it's even possible), set different names to different DataTempalte elements("Buttons" to be exact).
<Window x:Class="TicTacToeCommand.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:TicTacToeCommand"
mc:Ignorable="d"
Title="MainWindow" Height="500" Width="400"
Background="White"
Name="mainW">
<Window.Resources>
<Style x:Key="ButtonsStyle" TargetType="Button">
<Setter Property="Command" Value="{Binding ElementName=mainW, Path=DataContext.GetButtonPressCommand}"></Setter>
<Setter Property="Margin" Value="5"></Setter>
<Setter Property="Background" Value="Black"></Setter>
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="47*"/>
<RowDefinition Height="20*"/>
</Grid.RowDefinitions>
<ItemsControl Grid.Row="0" ItemsSource="{Binding ButtonsList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding Content}"
Name="b1"
Style="{StaticResource ButtonsStyle}"
CommandParameter="{Binding ElementName=b1, Path=Name}">
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="3" Columns="3" Name="uniformGrid1">
</UniformGrid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Grid>
That's my XAML code.
And also, i'm trying to send the name as a Command Parameter in a Command, but im allways getting "b1" name, because they all getting it and i need them all to have different name...
If it is possible how after this I send these names to command?
I will be very grateful for the help, and please excuse me in advance for possible mistakes.

element name, especially in template, doesn't help a lot
<Button Content="{Binding Content}"
Name="b1"
Style="{StaticResource ButtonsStyle}"
CommandParameter="{Binding ElementName=b1, Path=Name}">
button is bound to some item here. why not send that item as CommandParameter?
<Button Content="{Binding Content}"
Style="{StaticResource ButtonsStyle}"
CommandParameter="{Binding Path=.}">
then in view model you can cast to item type and get acces to all its properties (Content, etc)

Related

Swiching the Stackpanel in single ViewModel Using Back/Next Button WPF

I have a WPF, with Form with multiple user required questions. I have created 2 Stackpanels which have similar layout, first form (Stackpanel) will let the user to fill up information.While second form (Stackpanel) would be preview form for the user before he submits.
XAML Code
<Window x:Class="NinjaLIB.View.SSOEMWarrantyButtonExtension"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:NinjaLIB.View"
xmlns:lex="http://wpflocalizeextension.codeplex.com"
lex:LocalizeDictionary.DesignCulture="en"
lex:ResxLocalizationProvider.DefaultAssembly="NinjaLIB"
lex:ResxLocalizationProvider.DefaultDictionary="Resources"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
DataContext="{Binding Path=RMAView, Source={StaticResource Locator}}"
mc:Ignorable="d"
Title="Request RMA" Height="600" Width="1000"
xmlns:mvvmlight="http://www.galasoft.ch/mvvmlight"
xmlns:converter="clr-namespace:NinjaLIB.Converter"
WindowStartupLocation="CenterScreen" ResizeMode="NoResize">
<i:Interaction.Triggers>
<!--<i:EventTrigger EventName="Closed">
<mvvmlight:EventToCommand Command="{Binding GetRMAWindowClosed}" PassEventArgsToCommand="True" />
</i:EventTrigger>-->
<!--<i:EventTrigger EventName="Loaded">
<mvvmlight:EventToCommand Command="{Binding GetWarrantyWindowLoaded}" PassEventArgsToCommand="True" />
</i:EventTrigger>-->
</i:Interaction.Triggers>
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!--Some QUestions asked to the User-->
<Grid Grid.Row="2">
<!--View Form Fill-->
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<StackPanel Orientation="Vertical">
<StackPanel.Style>
<Style TargetType="StackPanel">
<Setter Property="Visibility" Value="Visible"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ViewState}" Value="FormFillViewState">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
**<!--Some QUestions asked to the User-->**
</StackPanel >
</ScrollViewer>
**<!--View Preview Form-->**
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<StackPanel>
<StackPanel.Style>
<Style TargetType="StackPanel">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ViewState}" Value = "PreviewFillState" >
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
**<!--Some QUestions asked to the User-->**
</StackPanel>
</ScrollViewer>
</Grid>
<Grid Grid.Row="3">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!--Buttons-->
<Button Grid.Row="0" Content="Next"
IsEnabled="{Binding IsConnected}"
Command="{Binding NextCommandBtn}"
FontWeight="Normal"
HorizontalContentAlignment="Center"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Height="30"
Width="80"
Margin="780,0,0,2"
Padding="3,0"/>
<Button Grid.Row="0" Content="Back"
IsEnabled="{Binding IsConnected}"
Command="{Binding BackCommandBtn}"
FontWeight="Normal"
HorizontalContentAlignment="Center"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Height="30"
Width="80"
Margin="420,0,0,2"
Padding="3,0"/>
</Window>
==============
View Model Section Code
==============
private RMAViewModel RMAView;
private readonly ResourceManager rm;
public RMAViewModel()
{
rm = new ResourceManager("NinjaLIB.Properties.Resources", Assembly.GetExecutingAssembly());
}
//Properties for the Window (Date and Text) for FormFillViewState
//Properties for the Window (Date and Text) for PreviewFillState
==============
I wanted some help with view Model code, where if I click NextCommandBtn all the data will appear as filled up form from first stackpanel view and when I select BackCommandBtn i can edit the form.
You can think about it like this:
You have two views (StackPanels) and only one can be displayed at a time.
So in your view-model, you need a property that tells you which view is active. A simple bool property for each view would work. Since there are only two views, you could technically just use a single property, but using two will make your XAML data binding a little easier.
Examples:
IsFormActive
IsPreviewActive
In your XAML, you need to control the Visibility property of your two StackPanel controls based on your IsFormActive and IsPreviewActive properties in your view-model. You can do this with a value converter, specifically the BooleanToVisibilityConverter.
<StackPanel Visibility="{Binding IsFormActive,
Converter={StaticResource BooleanToVisibilityConverter}">
...
</StackPanel>
<StackPanel Visibility="{Binding IsPreviewActive,
Converter={StaticResource BooleanToVisibilityConverter}">
...
</StackPanel>
And back in your view-model you can control the state of IsFormActive and IsPreviewActive when the next and back buttons are clicked, etc.
I hope this helps you get an idea of how to proceed.

How to achieve the complex UI using ItemControl in silverlight

I am working on creating a complex report which almost looks like shown in here image
For this I have create a collection where I will store all the descriptions and its corresponding ratings.
This collection is then I am binding to a ItemControl. The collection will be fetched from database depending on criteria's.
Now my problem is how to fragment or separate single ItemControl to look like shown in image. Should I use multiple collections which will be then bind to different ItemControl ? Can I use multiple datagrids?
I am out of ideas... Any suggestions / examples much appreciated.
Definitely do-able. Treat each block (such as Mathmatics, Arts Education etc) as an item, and you're then just dealing with an ItemsCollection. Create a style for how to present each item in that collection, and another style for how to present each property in your block (which will also feature a collection of something.
An example I have of something similar, was blocks which consisted of a heading, and a varied number of checkboxes each with a description. There could be a varying number of these blocks too.
In my view, that displayed these blocks, my xaml looked something like this:
<ScrollViewer VerticalScrollBarVisibility="Visible" MaxHeight="100">
<ItemsControl ItemsSource="{Binding FeatureFlags, Mode=TwoWay}" Style="{StaticResource FlagGroupsAndFlagsItemsControlStyle}" />
</ScrollViewer>
I then had a style for that ItemsControl defined in a resource dictionary somewhere ...
<Style x:Key="FlagGroupsAndFlagsItemsControlStyle" TargetType="ItemsControl">
<Setter Property="Width" Value="Auto" />
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<Grid x:Name="FlagListGrid">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBox Grid.Row="0" Width="{Binding Width, ElementName=FlagListGrid, Mode=OneWay}" IsReadOnly="True" Text="{Binding Name}" />
<ListBox Grid.Row="1" Width="{Binding Width, ElementName=FlagListGrid, Mode=OneWay}" ItemsSource="{Binding Flags}" ScrollViewer.HorizontalScrollBarVisibility="Disabled"
Style="{StaticResource FlagsListBoxItemsStyle}" Background="{Binding IsOptional, Converter={StaticResource YNToOptionalBackgroundColour}}"/>
</Grid>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
And then a style for the items within that templates ListBox ...
<Style x:Key="FlagsListBoxItemsStyle" TargetType="ListBox">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<toolkit:WrapPanel Width="{Binding Width, ElementName=FlagListGrid, Mode=OneWay}" Orientation="Horizontal" ScrollViewer.HorizontalScrollBarVisibility="Disabled" />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox Width="20" Height="18" VerticalAlignment="Top" IsChecked="{Binding IsSelected, Mode=TwoWay}" />
<TextBlock Width="180" MinHeight="18" VerticalAlignment="Center" Text="{Binding Description}" TextWrapping="Wrap" />
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
Unfortunately I can't show you an image of what the finished result looks like, but I hope these pointers could set you on track for your very similar problem

Overriding Style of WPF TreeView Items

I am using the awesome MahAppsMetro WPF control suite. I have a tree view that loads the file system. I also want to display images in the TreeViewItems so I have overridden the metro tree style as follows
<UserControl x:Class="GDE.Tree.TreeView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:Caliburn="http://www.caliburnproject.org"
xmlns:Metro="http://metro.mahapps.com/winfx/xaml/controls"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="300">
<UserControl.Resources>
<HierarchicalDataTemplate x:Key="TreeTemplate" ItemsSource="{Binding Path=Children}"/>
</UserControl.Resources>
<!--TreeView-->
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBox Grid.Row="0"
Margin="5"
IsReadOnly="True"
Text="{Binding SelectedPath, Mode=TwoWay}"/>
<TreeView Grid.Row="1"
Margin="5"
ItemsSource="{Binding RootChildren}"
ItemTemplate="{StaticResource TreeTemplate}">
<TreeView.Resources>
<Style TargetType="{x:Type TreeViewItem}"
BasedOn="{StaticResource MetroTreeViewItem}">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Name="img"
Width="16"
Height="16"
Stretch="Fill"
Source="{Binding Path=Icon, Mode=OneTime}"
VerticalAlignment="Center"
HorizontalAlignment="Center"/>
<TextBlock Text="{Binding DisplayName, Mode=OneTime}"
Margin="5,0,0,0"
VerticalAlignment="Center"
HorizontalAlignment="Left"/>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</TreeView.Resources>
</TreeView>
</Grid>
</UserControl>
But this does not seem to work as intended and I can't figure out why. From this XAML, I get no binding errors and the visuals look like:
I have gone more extensive with the XAML mark up but I am getting the exact same visuals. How can I change the above XAML to give me the Image/TextBlocks as well as the MahApps look and feel?
Thanks for your time.
To sum up comments instead of changing Style you need to move StackPanel from DataTemplate directly into HierarchicalDataTemplate as at the moment used template has no content:
<HierarchicalDataTemplate x:Key="TreeTemplate" ItemsSource="{Binding Path=Children}">
<StackPanel Orientation="Horizontal">
<Image Name="img" ... />
<TextBlock Text="{Binding DisplayName, Mode=OneTime}" ... />
</StackPanel>
</HierarchicalDataTemplate>

List of groups of data with multiple interactive UI elements

I'm currently working on a WPF application, it's my first so I'm learning as I go.
The basics are fine but I've hit a problem with what I'm trying to do at the moment. There seem to be tons of ways that might work but I'm pretty sure that I'm going down the path of making it harder than it needs to be.
What I need is some guidance on the simplest way to implement a piece of UI.
I'm using c# 4, wpf and the MVVM pattern.
The data I'm wanting to display looks like this:
obj1 ----< obj2 ----< obj3
i.e. a single obj1 has many obj2's which has many (specifically 1-3) obj3's
On my screen, I want to see a list/datagrid type view of the obj2 elements with the associated obj3 elements nested underneath.
The obj2 elements need to show a few text values and a check box (that will fire the appropriate command in the view model when toggled).
The obj3 elements need to show an image, possibly some text and be clickable (again, firing the appropriate command to the view model).
At first I looked at creating a custom control for the obj3 element, a custom control based on ItemsControl for a list of obj3 elements, another custom control for the obj2 element and finally another custom control to display a list of obj2 elements.
However, a little way in, I've got the feeling that I've massively over-complicated it.
Can I just use user controls? Do I even need them at all or can I just use the regular List control with a template?
Some pointers would be very welcome.
Thanks.
I spent quite some time getting this working as I wanted so thought I'd share...
The answer turned out to be a nested list control with data templates and associated view models for the items in each list. The list control is so much more flexible in WPF than Winforms that you can do pretty much anything with it.
I've found many different things that have helped on many different sites but the core details came from Dr.WPF: http://drwpf.com/blog/category/collections/
I won't post all the code as it's rather long. The core of it though is to first setup the list view in the user control:
<ListView Name="list" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
HorizontalContentAlignment="Stretch" Focusable="False"
IsSynchronizedWithCurrentItem="True" ItemsPanel="{StaticResource VerticalItemsPanel}"
ItemContainerStyle="{StaticResource Obj2ContainerStyle}" ItemsSource="{Binding Obj2List}">
</ListView>
The keys things here are the ItemsPanel and ItemContainerStyle. These define the properties of the panel that contains all list items and the style for each list item respectively.
They are contained in the resources for the user control.
<ItemsPanelTemplate x:Key="VerticalItemsPanel">
<StackPanel Orientation="Vertical" Focusable="False" HorizontalAlignment="Stretch" />
</ItemsPanelTemplate>
<Style x:Key="Obj2ContainerStyle" TargetType="{x:Type ListViewItem}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Enabled}" Value="False">
<Setter Property="Background" Value="LightSalmon"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Path=Enabled}" Value="True">
<Setter Property="Background" Value="PaleGreen"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
I also have the data templates. The first tells the system to use the second for displaying objects of type Obj2ViewModel
<DataTemplate DataType="{x:Type src:Obj2ViewModel}">
<ContentControl x:Name="Obj2Host" Focusable="False" Content="{Binding}"
ContentTemplate="{StaticResource Obj2ViewTemplate}" />
</DataTemplate>
<DataTemplate x:Key="Obj2ViewTemplate">
<DataTemplate.Resources>
<ItemsPanelTemplate x:Key="HorizontalItemsPanel">
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
<Style x:Key="Obj3ContainerStyle" TargetType="{x:Type ListViewItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Grid>
<Rectangle StrokeThickness="1" Stroke="#FF000000" Margin="0" />
<ContentPresenter x:Name="ContentHost" Margin="{TemplateBinding Padding}"
HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="LabelStyle" TargetType="{x:Type Label}">
<Setter Property="Padding" Value="0,0,4,0" />
<Setter Property="HorizontalAlignment" Value="Left" />
</Style>
<Style x:Key="DataStyle" TargetType="{x:Type TextBlock}">
<Setter Property="Padding" Value="0,0,4,0" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="FontWeight" Value="Bold" />
</Style>
</DataTemplate.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0" Content="{StaticResource Label1Text}" Style="{StaticResource LabelStyle}"/>
<Label Grid.Row="1" Grid.Column="0" Content="{StaticResource Label2Text}" Style="{StaticResource LabelStyle}"/>
<Label Grid.Row="2" Grid.Column="0" Content="{StaticResource Label3Text}" Style="{StaticResource LabelStyle}"/>
<Label Grid.Row="3" Grid.Column="0" Content="{StaticResource Label4Text}" Style="{StaticResource LabelStyle}"/>
<TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Property1}" Style="{StaticResource DataStyle}"/>
<TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding Property2}" Style="{StaticResource DataStyle}"/>
<TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding Property3}" Style="{StaticResource DataStyle}"/>
<TextBlock Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="2" Text="{Binding Property4}" Style="{StaticResource DataStyle}"/>
<ListView Grid.Row="0" Grid.RowSpan="3" Grid.Column="2" Name="Obj3List"
HorizontalAlignment="Right" VerticalAlignment="Center"
IsSynchronizedWithCurrentItem="True"
ItemsPanel="{StaticResource HorizontalItemsPanel}"
ItemsSource="{Binding Obj3s}"
ItemContainerStyle="{StaticResource Obj3ContainerStyle}"
BorderThickness="0"
Background="Transparent">
</ListView>
<CheckBox Grid.Row="0" Grid.RowSpan="4" Grid.Column="3" VerticalAlignment="Center"
IsChecked="{Binding Property5}" IsEnabled="{Binding NotExpired}" >
</CheckBox>
<Image Grid.Row="0" Grid.RowSpan="4" Grid.Column="4" Source="{StaticResource DeleteIcon}" Stretch="None">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseUp">
<cmd:EventToCommand PassEventArgsToCommand="False" Command="{Binding DeleteObj2Command, Mode=OneWay}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Image>
</Grid>
</DataTemplate>
The second data template above contains another list view. This one containing Obj3 items.
The style for these is specified within the DataTemplate's resources section.
Finally, the User control's resources also contains the data templates for the Obj3 elements:
<DataTemplate DataType="{x:Type src:Obj3ViewModel}">
<ContentControl x:Name="Obj3Host" Focusable="False" Content="{Binding}"
ContentTemplate="{StaticResource Obj3ViewTemplate}" />
</DataTemplate>
<DataTemplate x:Key="Obj3ViewTemplate">
<Image Source="{Binding Image}" Stretch="None">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseUp">
<cmd:EventToCommand PassEventArgsToCommand="False" Command="{Binding ToggleEnabledCommand, Mode=OneWay}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Image>
</DataTemplate>
Note that the EventToCommand stuff is thanks to the MVVM Light toolkit. It's not a standard .NET thing.

Data-based template selection in WPF

I have this simple XAML example:
<Window x:Class="DynTemplateTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<DataTemplate x:Key="ItemTemplate">
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Rectangle Width="30" Height="30" Fill="Red"></Rectangle>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Canvas.Left" Value="{Binding Position}"></Setter>
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</DataTemplate>
</Window.Resources>
<DockPanel LastChildFill="True">
<ContentPresenter
Content="{Binding Path=Items}"
ContentTemplate="{StaticResource ItemTemplate}"
>
</ContentPresenter>
</DockPanel>
</Window>
It is rendering my items in the observable collection in MVVM style. Each item is having its horizontal position in a property. Each item also has a property IsSpecial which tells if it wants to be rendered in some special way. I want ordinary items (IsSpecial=false) render as red squares (already in the code) and special items as blue circles with "special" text inside.
What I do not know is how to adjust the XAML code to do the template selection for the items. Is there a way to do that without coding my own ItemTemplateSelector? Will it still work with the canvas positioning based on binding. I think that the solution is to extract the item template to a separate template, create one more template for special items and then somehow play with triggers ... but it is not very easy for me as I am a WPF beginner at the moment.
The other thing is that I quite dislike the way how the Position is passed to the items. Is there some other way?
Are there any other recommendations how to improve the code?
I solved it myself :D
<Window x:Class="DynTemplateTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<DataTemplate x:Key="NormalItem">
<Rectangle Width="30" Height="30" Fill="Red"></Rectangle>
</DataTemplate>
<DataTemplate x:Key="SpecialItem">
<Rectangle Width="30" Height="30" Fill="Red"></Rectangle>
</DataTemplate>
<DataTemplate x:Key="ItemTemplate">
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl Content="{Binding}" ContentTemplate="{StaticResource NormalItem}" x:Name="ItemsContentControl" />
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=IsSpecial}" Value="true">
<Setter TargetName="ItemsContentControl" Property="ContentTemplate" Value="{StaticResource SpecialItem}" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Canvas.Left" Value="{Binding Position}" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</DataTemplate>
</Window.Resources>
<DockPanel LastChildFill="True">
<ContentPresenter
Content="{Binding Path=Items}"
ContentTemplate="{StaticResource ItemTemplate}"
>
</ContentPresenter>
</DockPanel>
</Window>
But still, any thoughts on alternatives or improvements?

Resources