In this article I want to extend my ItemsControl.Style, by binding template.

XAML:

<Grid>

	<Grid.Resources>
		<itemsControlItemTemplate:ItemsControlViewModel x:Key="ItemsControlViewModel" />
	</Grid.Resources>

	<ItemsControl DataContext="{StaticResource ItemsControlViewModel}" ItemsSource="{Binding myItemsSource}">

		<ItemsControl.Style>
			<Style TargetType="ItemsControl">
				<Style.Triggers>

					<DataTrigger Binding="{Binding ParentMyItemType}" Value="{x:Static itemsControlItemTemplate:myItemTypes.WrapPanel}">
						<Setter Property="ItemsPanel">
							<Setter.Value>
								<ItemsPanelTemplate>
									<WrapPanel />
								</ItemsPanelTemplate>
							</Setter.Value>
						</Setter>
					</DataTrigger>

					<DataTrigger Binding="{Binding ParentMyItemType}" Value="{x:Static itemsControlItemTemplate:myItemTypes.StackPanel}">
						<Setter Property="ItemsPanel">
							<Setter.Value>
								<ItemsPanelTemplate>
									<StackPanel />
								</ItemsPanelTemplate>
							</Setter.Value>
						</Setter>
					</DataTrigger>

				</Style.Triggers>
			</Style>
		</ItemsControl.Style>

		<ItemsControl.ItemTemplate>
			<DataTemplate>
			
				<DataTemplate.Resources>
					<itemsControlItemTemplate:AnotherModel x:Key="AnotherModel" />
				</DataTemplate.Resources>

				<Label DataContext="{StaticResource AnotherModel}" Content="{Binding myContent}" />

			</DataTemplate>
		</ItemsControl.ItemTemplate>

	</ItemsControl>

</Grid>

Here notice part, for example:

<DataTrigger Binding="{Binding ParentMyItemType}" Value="{x:Static itemsControlItemTemplate:myItemTypes.WrapPanel}">
	<Setter Property="ItemsPanel">
		<Setter.Value>
			<ItemsPanelTemplate>
				<WrapPanel />
			</ItemsPanelTemplate>
		</Setter.Value>
	</Setter>
</DataTrigger>

Where myItemTypes.WrapPanel I declared something like:

public enum myItemTypes
{
	WrapPanel,
	StackPanel
}

and then my view model looks like:

public class ItemsControlViewModel
{
	public IEnumerable<string> myItemsSource { get; set; }

	public myItemTypes ParentMyItemType { get; set; }

	public ItemsControlViewModel()
	{
		myItemsSource = new[] { "Test1", "Test2" };
		this.ParentMyItemType = myItemTypes.WrapPanel;
	}
}

public class AnotherModel
{
	public string myContent { get; set; }

	public AnotherModel()
	{
		myContent = "test2";
	}
}

notice line:

this.ParentMyItemType = myItemTypes.WrapPanel;

with that line I said that I want my style to be with StackPanel.

Example code you can download from here.

I am still learning DataTemplate, but at this moment I would like just to underline (as a note to myself) that it seems that binding for DataTemplate goes to another class.

XAML:

<Window x:Class="ItemsControlItemTemplate.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:itemsControlItemTemplate="clr-namespace:ItemsControlItemTemplate"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>

      <Grid.Resources>
        <itemsControlItemTemplate:ItemsControlViewModel x:Key="ItemsControlViewModel" />
      </Grid.Resources>
      
      <ItemsControl DataContext="{StaticResource ItemsControlViewModel}" ItemsSource="{Binding myItemsSource}">
        <ItemsControl.ItemTemplate>
          <DataTemplate>
            
              <DataTemplate.Resources>
                <itemsControlItemTemplate:AnotherModel x:Key="AnotherModel" />
              </DataTemplate.Resources>
            
              <Label DataContext="{StaticResource AnotherModel}" Content="{Binding myContent}" />
            
          </DataTemplate>
        </ItemsControl.ItemTemplate>
      </ItemsControl>
      
    </Grid>
</Window>

Here note part:

<DataTemplate.Resources>
	<itemsControlItemTemplate:AnotherModel x:Key="AnotherModel" />
</DataTemplate.Resources>

<Label DataContext="{StaticResource AnotherModel}" Content="{Binding myContent}" />

My view model:

public class ItemsControlViewModel
{
	public IEnumerable<string> myItemsSource { get; set; }

	public ItemsControlViewModel()
	{
		myItemsSource = new[] { "Test1", "Test2" };
	}
}

public class AnotherModel
{
	public string myContent { get; set; }

	public AnotherModel()
	{
		myContent = "test";
	}
}

Here notice class:

public class AnotherModel
{
	public string myContent { get; set; }

	public AnotherModel()
	{
		myContent = "test";
	}
}

Which is actually in use in the label under the datatemplate

Example project you can download from here.

In this article I explained how to use user control with datacontext which is defined in the code behind, now I will explain how to use datacontext without code behind.

User control XAML:

<UserControl x:Class="MyUserControl.myControl"
             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" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
      <Label Content="{Binding myContent}"/>
    </Grid>
</UserControl>

Then main window XAML:

<Window x:Class="UserControlDataContext.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:myUserControl="clr-namespace:MyUserControl;assembly=MyUserControl"
        xmlns:viewModel="clr-namespace:UserControlDataContext.ViewModel"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.Resources>
          <viewModel:UserControlDataContextViewModel x:Key="UserControlDataContextViewModel" />
        </Grid.Resources>
        <myUserControl:myControl DataContext="{Binding Source={StaticResource UserControlDataContextViewModel}}"/>
    </Grid>
</Window>

Here notice line: <myUserControl:myControl DataContext="{Binding Source={StaticResource UserControlDataContextViewModel}}"/>

And view model looks like this:

public class UserControlDataContextViewModel
{
	public string myContent { get; set; }

	public UserControlDataContextViewModel()
	{
		myContent = "test";
	}
}

Example project you can download from here.

Playing with ComboBox.

Today I was playing little with ComboBox, and I made some binding, so here is my XAML:

<Window x:Class="TemplateChooser.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:viewModel="clr-namespace:TemplateChooser.ViewModel"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
      
        <Grid.Resources>
            <viewModel:TemplateChooserViewModel x:Key="TemplateChooserViewModel" />
        </Grid.Resources>
      
        <Grid.RowDefinitions>
          <RowDefinition Height="30"/>
          <RowDefinition Height="30"/>
        </Grid.RowDefinitions>
      
        <ComboBox Name="myCombo" DataContext="{StaticResource TemplateChooserViewModel}" ItemsSource="{Binding TemplateItems}" SelectedValue="{Binding TemplateItems[0]}"/>
        <Button Grid.Row="1" Content="{Binding Path=SelectedValue, ElementName=myCombo}"/>
    
    </Grid>
</Window>

Here notice line:

SelectedValue="{Binding TemplateItems[0]}"

After that, notice how I binded button

<Button Grid.Row="1" Content="{Binding Path=SelectedValue, ElementName=myCombo}"/>

I am not sure if this binding is proper, but it is working :)

Here is my view model:

public class TemplateChooserViewModel
{
	public IEnumerable<string> TemplateItems { get; set; }

	public TemplateChooserViewModel()
	{
		TemplateItems = new[] { "Template1", "Template2" };
	}
}

Example project you can download from here.