Jak mam to wdrożyć?UWP DataTemplates dla wielu typów przedmiotów w ListView
Powiedzmy to mój model:
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" });
}
}
Dla ilości kodu w tej kwestii prosimy o założenie, że INotifyPropertyChanged
jest realizowany w miarę potrzeby, i że ViewModel jest prawidłowo zainicjowany na stronie.
Jak mogę używać własnych odpowiedników DataTemplates? W WPF chciałbym zdefiniować wiele DataTemplates bez x:Key
, ale ze zdefiniowanym DataType i pozwolić ListView wybrać, które z nich korzystać w oparciu o typ elementu. UWP tego nie lubi; kompilator po prostu stwierdza Dictionary Item "DataTemplate" must have a Key attribute
. Jak więc osiągnąć mój cel?
Obecna próba
Moja obecna próba jest, aby zwyczaj DataTemplateSelector
, co wydaje się dość prosta.
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; }
}
zdefiniować go w XAML tak:
<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>
Niestety kiedy uruchomić ten wyjątek występuje podczas wykonywania, stwierdzając Failed to create a 'Ui.Components.TemplateMatch' from the text 'model:Dog'.
Więc wydaje wiążące do właściwości Type
nie jest takie proste.
Każda pomoc jest doceniana!
Proszę zauważyć, że chciałbym użyć właściwości typu Type
, w przeciwieństwie do string
, w której chciałbym podać nazwę typu CLR i użyć odbicia, aby wywołać typ, głównie dlatego, że nie chcę mieszanych CLR i XML przestrzenie nazw pojawiają się w XAML. Jeśli możesz znaleźć sposób na wywołanie tego typu przy użyciu przestrzeni nazw XML, z chęcią przyjmiemy to jako odpowiedź.
czy wypróbowałeś TargetType = "{x: Typ modelu: Pies}", ponieważ właściwość jest typu "Typ", a nie ciąg znaków. –
Zrobiłem. UWP nie obsługuje już znaczników x: Type. To byłoby rozwiązanie dla WPF. :) –
Dlaczego nie utworzyć instrukcji warunkowej wewnątrz metody wybierania szablonu zamiast używać TemplateMatch? – Lance