'How to replicate behavior of standard list elements to instantiate child items in WPF?
I'm creating a Wizard
control based on Selector
. My plan is that it will behave in the similar way to TabControl
, ListBox
, etc. - by having its own child items.
What I already did is:
public class Wizard : Selector
{
// ...
protected override DependencyObject GetContainerForItemOverride() => new WizardPage();
protected override bool IsItemItsOwnContainerOverride(object item) => item is WizardPage;
// ...
The relevant part ControlTemplate for my control looks like this:
<Style TargetType="{x:Type c:Wizard}">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<Grid />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type c:Wizard}">
<DockPanel Background="{TemplateBinding Background}"
Margin="{TemplateBinding Padding}">
<StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal" HorizontalAlignment="Right">
<Button Name="BackButton" MinWidth="75" Command="{x:Static c:WizardCommands.PreviousPage}"
Content="{TemplateBinding BackButtonContent}" Style="{StaticResource WizardButton}">
<Button.Visibility>
<MultiBinding Converter="{StaticResource WizardPageButtonVisibilityConverter}">
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="BackButtonVisibility" />
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="SelectedItem.BackButtonVisibility" />
</MultiBinding>
</Button.Visibility>
</Button>
<Button Name="NextButton" Command="{x:Static c:WizardCommands.NextPage}"
Content="{TemplateBinding NextButtonContent}" Style="{StaticResource WizardButton}">
<Button.Visibility>
<MultiBinding Converter="{StaticResource WizardPageButtonVisibilityConverter}">
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="NextButtonVisibility" />
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="SelectedItem.NextButtonVisibility" />
</MultiBinding>
</Button.Visibility>
</Button>
<Button Name="FinishButton" Command="{x:Static c:WizardCommands.Finish}" Content="{TemplateBinding FinishButtonContent}"
Style="{StaticResource WizardButton}">
<Button.Visibility>
<MultiBinding Converter="{StaticResource WizardPageButtonVisibilityConverter}">
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="FinishButtonVisibility" />
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="SelectedItem.FinishButtonVisibility" />
</MultiBinding>
</Button.Visibility>
</Button>
<Button Name="CancelButton" Command="{x:Static c:WizardCommands.Cancel}" Content="{TemplateBinding CancelButtonContent}"
Style="{StaticResource WizardButton}">
<Button.Visibility>
<MultiBinding Converter="{StaticResource WizardPageButtonVisibilityConverter}">
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="CancelButtonVisibility" />
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="SelectedItem.CancelButtonVisibility" />
</MultiBinding>
</Button.Visibility>
</Button>
</StackPanel>
<ContentPresenter Content="{Binding SelectedItem, RelativeSource={RelativeSource TemplatedParent}}" />
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
However, when I assign an ObservableCollection<BaseViewModel>
along with specific DataTemplate
s...
<c:Wizard Grid.Column="1" ItemsSource="{Binding WizardSteps}">
<c:Wizard.Resources>
<DataTemplate DataType="{x:Type vm:WizardStep1ViewModel}">
<Border Background="Red" />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:WizardStep2ViewModel}">
<Border Background="Green" />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:WizardStep3ViewModel}">
<Border Background="Blue" />
</DataTemplate>
</c:Wizard.Resources>
</c:Wizard>
...then the DataTemplate
s are instantiated and shown properly, but no WizardPage
s are being created in the meantime.
How can I fix it?
Solution 1:[1]
Your ControlTemplate
should include an ItemsPresenter
for a WizardPage
to get created for each item in the source collection, e.g.:
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="c:Wizard">
<ItemsPresenter />
</ControlTemplate>
</Setter.Value>
</Setter>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | mm8 |