gpt4 book ai didi

xaml - ListView 中多种项目类型的 UWP DataTemplates

转载 作者:行者123 更新时间:2023-12-04 08:48:21 26 4
gpt4 key购买 nike

我将如何实现呢?

假设这是我的模型:

public interface IAnimal
{
string Name { get; }
}
public class Fish : IAnimal
{
public string Name { get; set; }
public int ScalesCount { get; set; }
}
public class Dog : IAnimal
{
public string Name { get; set; }
public string CollarManufacturerName { get; set; }
}

public class ViewModel
{
public ObservableCollection<IAnimal> Animals { get; set; }

public ViewModel()
{
this.Animals = new ObservableCollection<IAnimal>();
this.Animals.Add(new Fish { Name = "Carl", ScalesCount = 9000 });
this.Animals.Add(new Dog { Name = "Fifi", CollarManufacturerName = "Macrosoft" });
}
}

为了这个问题中的代码量,请假设 INotifyPropertyChanged在必要时实现,并且 ViewModel 在页面中正确初始化。

如何使用自己对应的 DataTemplates?在 WPF 中,我只定义多个没有 x:Key 的 DataTemplates但是使用定义的 DataType 并让 ListView 根据项目的类型选择使用哪个。 UWP 不喜欢这样。编译器只是声明 Dictionary Item "DataTemplate" must have a Key attribute .那么我该如何实现我的目标呢?

当前尝试

我目前的尝试是自定义 DataTemplateSelector ,这看起来相当简单。
public class MyDataTemplateSelector: Windows.UI.Xaml.Controls.DataTemplateSelector
{
public ObservableCollection<TemplateMatch> Matches { get; set; }

public DataTemplateSelector()
{
this.Matches = new ObservableCollection<TemplateMatch>();
}

protected override DataTemplate SelectTemplateCore(object item)
{
return this.Matches.FirstOrDefault(m => m.TargetType.Equals(item))?.Template;
}

protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
return this.Matches.FirstOrDefault(m => m.TargetType.Equals(item))?.Template;
}
}

public class TemplateMatch
{
public Type TargetType { get; set; }
public DataTemplate Template { get; set; }
}

像这样在 XAML 中定义它:
<ListView ItemsSource="{x:Bind ViewModel.Animals}">
<ListView.ItemTemplateSelector>
<cmp:MyDataTemplateSelector>
<cmp:MyDataTemplateSelector.Matches>
<cmp:TemplateMatch TargetType="model:Dog" Template="{StaticResource DogTemplate}"/>
<cmp:TemplateMatch TargetType="model:Fish" Template="{StaticResource FishTemplate}"/>
</cmp:MyDataTemplateSelector.Matches>
</cmp:MyDataTemplateSelector>
</ListView.ItemTemplateSelector>
</ListView>

不幸的是,当我运行它时,运行时出现异常,说明 Failed to create a 'Ui.Components.TemplateMatch' from the text 'model:Dog'.所以它似乎绑定(bind)到 Type属性(property)没那么容易。

任何帮助表示赞赏!

请注意,我想使用类型为 Type 的属性。 ,而不是 string我将传递 CLR 类型名称并使用反射来调用该类型,主要是因为我不希望混合的 CLR 和 XML 命名空间出现在 XAML 中。如果您能找到一种使用 XML 命名空间调用该类型的方法,我很乐意将其作为答案。

最佳答案

我找到了解决方法。如果您能够创建这些类型的实例 - 您可以使用它来检测类型:

[ContentProperty(Name = nameof(Matches))]
public class TypeTemplateSelector : DataTemplateSelector
{
public ObservableCollection<TemplateMatch> Matches { get; set; }
public TypeTemplateSelector()
{
this.Matches = new ObservableCollection<TemplateMatch>();
}

protected override DataTemplate SelectTemplateCore(object item)
{
return this.Matches.FirstOrDefault(m => m.ItemOfType.GetType().Equals(item.GetType()))?.TemplateContent;
}

protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
return this.Matches.FirstOrDefault(m => m.ItemOfType.GetType().Equals(item.GetType()))?.TemplateContent;
}
}

[ContentProperty(Name = nameof(ItemOfType))]
public class TemplateMatch
{
public object ItemOfType { get; set; }
public DataTemplate TemplateContent { get; set; }
}

XAML:
<controls:TypeTemplateSelector>
<controls:TemplateMatch TemplateContent="{StaticResource FishTemplate}">
<models:Fish/>
</controls:TemplateMatch>
<controls:TemplateMatch TemplateContent="{StaticResource DogTemplate}">
<models:Dog/>
</controls:TemplateMatch>
</controls:TypeTemplateSelector>

关于xaml - ListView 中多种项目类型的 UWP DataTemplates,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32414233/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com