XAML 根据UWP中的类型选择数据模板

o7jaxewo  于 2022-12-07  发布在  其他
关注(0)|答案(1)|浏览(123)

给定这些类型

public class TestTypeBase
{
    public string Name { get; set; }
}
public class TestTypeToggle : TestTypeBase
{
}
public class TestType : TestTypeBase
{
    public bool Enabled { get; set; } = false;
}

该数据上下文

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>

这种观点

<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>

我希望根据项目类型选择ItemTemplate,但我得到的只是字符串形式的类型名称。
This solution看起来很有前途,但我不知道如何给予类型提示。

  • (我遇到的问题基本上与this question相同,但在UWP上下文中)*

这是可能的,还是我必须使用ItemTemplateSelector

k0pti3hp

k0pti3hp1#

是的,UWP不同于WPF。在UWP中必须使用ItemTemplateSelector
这是官方文件供你参考。

页面.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>

页面. 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;
        }
    }
}

编辑

根据这份文件,
如果您的ItemsControl.ItemsPanel是ItemsStackPanel或ItemsWrapGrid,请提供SelectTemplateCore(Object)方法的覆写。如果ItemsPanel是不同的面板,例如VirtualizingStackPanel或WrapGrid,请提供SelectTemplateCore(Object,DependencyObject)方法的覆写。
因此,您需要覆盖DataTemplateSelector中的SelectTemplateCore(Object, DependencyObject)方法。

页面.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>

页面. 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;
        }
    }
}

相关问题