У меня есть элементы управления списком с небольшими статическими источниками данных. Например:
<ItemsControl ItemsSource="{Binding Countries}" .../>
и моя модель просмотра заполняет список:
this.Countries.Add(new Country { Code = "BE", Name = "Belgium" });
this.Countries.Add(new Country { Code = "CA", Name = "Canada" });
// etc.
Есть ли альтернативный способ определения содержимого списка в XAML? Что-то вроде:
<ItemsControl>
<ItemsControl.ItemsSource>
<somenamespace:list>
<mynamespace:Country Code="BE" Name="Belgium" />
etc.
</somenamespace:list>
</ItemsControl.ItemsSource>
</ItemsControl>
Я бы поместил списки в отдельные файлы ресурсов и надеялся бы сделать ItemsSource="{StaticResource myListOfCountries}"
после определения их как ресурса.
Я хочу сделать это, чтобы облегчить шаблонный код в моих виртуальных машинах. Интересно, будет ли это негативно влиять на производительность, поскольку эти объекты могут быть созданы до визуализации представления, в то время как в противном случае я мог бы загрузить их позже (при навигации, в режиме просмотра,... против contructor). Любые мысли приветствуются!
Вы можете сделать это, создав новый CollectionType, а затем заполнив его в XAML.
Пример,
CollectionType, который будет использоваться в XAML:
using System.Collections.ObjectModel;
namespace WpfApplication4
{
public class CountryCollection : ObservableCollection<Country>
{
}
}
ПОКО:
using System;
using System.Collections;
namespace WpfApplication4
{
public class Country
{
public String Name { get; set; }
public String Code { get; set; }
}
}
XAML:
<Window x:Class="WpfApplication4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication4"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:CountryCollection x:Key="CountryList">
<local:Country Name="Canada" Code="CA"/>
<local:Country Name="United States" Code="US"/>
<local:Country Name="Belgium" Code="BE"/>
</local:CountryCollection>
</Window.Resources>
<Grid>
<ItemsControl ItemsSource="{StaticResource CountryList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Label Content="{Binding Name}"/>
<Label Content="{Binding Code}"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Window>
Обратите внимание, что предоставленный XAML подобен:
var CountryList = new ObservableCollection<Country>
{
new Country {Name = "Canada", Code = "CA"},
new Country {Name = "United States", Code = "US"},
new Country {Name = "Belgium", Code = "BE"}
};
Изменить (обновить с помощью ArrayList)
с пространством имен коллекций, определенным в XAML, вы можете использовать
xmlns:collections="clr-namespace:System.Collections;assembly=mscorlib"
<Window.Resources>
<collections:ArrayList x:Key="CountryList">
<local:Country Name="Canada" Code="CA"/>
<local:Country Name="United States" Code="US"/>
<local:Country Name="Belgium" Code="BE"/>
</collections:ArrayList>
</Window.Resources>
Вот как вы можете сделать это чистым XAML:
<Window x:Class="WpfApplication.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="MainWindow"
Height="350"
Width="525">
<Window.Resources>
<XmlDataProvider x:Key="MockList"
XPath="/MockObjects/*">
<x:XData>
<MockObjects xmlns="">
<MockObject Code="BE"
Name="Belgium" />
<MockObject Code="CA"
Name="Canada" />
<MockObject Code="US"
Name="USA! USA!" />
</MockObjects>
</x:XData>
</XmlDataProvider>
</Window.Resources>
<Grid DataContext="{Binding Source={StaticResource MockList}}">
<ItemsControl ItemsSource="{Binding Mode=Default, XPath=/MockObjects/MockObject}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding XPath=@Code}" FontWeight="Bold" Margin="0 0 5 0"/>
<TextBlock Text="{Binding XPath=@Name}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Window>
Я использовал этот ответ SO в качестве ссылки.
Country
) предоставляется только в ваших данных представления. В качестве альтернативы вы можете написать файл XML и проанализировать его в объектах во время инициализации вашей ViewModel.