Given these types
public class TestTypeBase
{
public string Name { get; set; }
}
public class TestTypeToggle : TestTypeBase
{
}
public class TestType : TestTypeBase
{
public bool Enabled { get; set; } = false;
}
this data context
public class vm
{
public ObservableCollection<TestTypeBase> TestTypes { get; } = new ObservableCollection<TestTypeBase> { new TestTypeToggle { Name = "Don't Test" }, new TestTypeToggle { Name = "Always Test" }, new TestType { Name = "qwert", Enabled = true }, new TestType { Name = "qwert", Enabled = true } };
}
(xaml)
<Page.DataContext>
<local:vm />
</Page.DataContext>
and this view
<ComboBox Width="120" ItemsSource="{Binding TestTypes}">
<ComboBox.Resources>
<DataTemplate x:Key="a" x:DataType="local:TestType">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" />
<CheckBox IsChecked="{Binding Enabled}" />
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="b" x:DataType="local:TestTypeToggle">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
</ComboBox.Resources>
</ComboBox>
i was hoping that the ItemTemplate would be selected based on the item types but all i get are the type names as string.
This solution seems promising but i cannot figure how to give the type hint.
(I'm basically having the same problems as in this question but in a UWP context)
Is this possible or do i have to use a ItemTemplateSelector
?
CodePudding user response:
Yes, UWP is different from WPF. You have to use a ItemTemplateSelector
in UWP.
Here are the official documents for your reference.
Page.xaml
<Page.Resources>
<DataTemplate x:Key="NormalItemTemplate" x:DataType="x:Int32">
<Button HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="{ThemeResource SystemChromeLowColor}">
<TextBlock Text="{x:Bind}" />
</Button>
</DataTemplate>
<DataTemplate x:Key="AccentItemTemplate" x:DataType="x:Int32">
<Button HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="{ThemeResource SystemAccentColor}">
<TextBlock Text="{x:Bind}" />
</Button>
</DataTemplate>
<local:MyDataTemplateSelector x:Key="MyDataTemplateSelector"
Normal="{StaticResource NormalItemTemplate}"
Accent="{StaticResource AccentItemTemplate}"/>
</Page.Resources>
<Grid>
<ListView x:Name = "TestListView"
ItemsSource = "{x:Bind NumbersList}"
ItemTemplateSelector = "{StaticResource MyDataTemplateSelector}">
</ListView>
</Grid>
Page.xaml.cs
public sealed partial class MainPage : Page
{
public ObservableCollection<int> NumbersList = new ObservableCollection<int>();
public MainPage()
{
this.InitializeComponent();
NumbersList.Add(1);
NumbersList.Add(2);
NumbersList.Add(3);
}
}
public class MyDataTemplateSelector : DataTemplateSelector
{
public DataTemplate Normal { get; set; }
public DataTemplate Accent { get; set; }
protected override DataTemplate SelectTemplateCore(object item)
{
if ((int)item % 2 == 0)
{
return Normal;
}
else
{
return Accent;
}
}
}
Edit
According to this document,
If your ItemsControl.ItemsPanel is an ItemsStackPanel or ItemsWrapGrid, provide an override for the SelectTemplateCore(Object) method. If the ItemsPanel is a different panel, such as VirtualizingStackPanel or WrapGrid, provide an override for the SelectTemplateCore(Object, DependencyObject) method.
So you need override the SelectTemplateCore(Object, DependencyObject)
method in your DataTemplateSelector
.
Page.xaml
<Page.Resources>
<DataTemplate x:Key="NormalItemTemplate" x:DataType="x:Int32">
<TextBox Text="{x:Bind}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="{ThemeResource SystemChromeLowColor}" />
</DataTemplate>
<DataTemplate x:Key="AccentItemTemplate" x:DataType="x:Int32">
<TextBox Text="{x:Bind}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="{ThemeResource SystemAccentColor}" />
</DataTemplate>
<local:MyDataTemplateSelector x:Key="MyDataTemplateSelector"
Normal="{StaticResource NormalItemTemplate}"
Accent="{StaticResource AccentItemTemplate}"/>
</Page.Resources>
<Grid>
<ComboBox x:Name="Testcombox"
ItemsSource="{x:Bind NumbersList}"
ItemTemplateSelector = "{StaticResource MyDataTemplateSelector}">
</ComboBox>
</Grid>
Page.xaml.cs
public sealed partial class MainPage : Page
{
public ObservableCollection<int> NumbersList = new ObservableCollection<int>();
public MainPage()
{
this.InitializeComponent();
NumbersList.Add(1);
NumbersList.Add(2);
NumbersList.Add(3);
}
}
public class MyDataTemplateSelector : DataTemplateSelector
{
public DataTemplate Normal { get; set; }
public DataTemplate Accent { get; set; }
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
if ((int)item % 2 == 0)
{
return Normal;
}
else
{
return Accent;
}
}
}