Определение источника данных декларативно в XAML

1

У меня есть элементы управления списком с небольшими статическими источниками данных. Например:

<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). Любые мысли приветствуются!

  • 1
    Эта связь здесь может помочь вам.
Теги:
xaml
wpf
windows-phone-8

2 ответа

1
Лучший ответ

Вы можете сделать это, создав новый 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>
  • 0
    Вам не нужен набор для публичного класса CountryCollection?
  • 0
    @ Blam Нет, CountryCollection является производной от ObservableCollection, поэтому нет необходимости создавать установщик / получатель. Благодаря наследованию он все равно будет просто иметь все обычные функциональные возможности ObservableCollection. Смотри мое редактирование
Показать ещё 2 комментария
0

Вот как вы можете сделать это чистым 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 в качестве ссылки.

  • 0
    Поймите, однако, что этот метод нарушает MVVM, потому что ваша «Модель» ( Country ) предоставляется только в ваших данных представления. В качестве альтернативы вы можете написать файл XML и проанализировать его в объектах во время инициализации вашей ViewModel.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню