Designdata с xaml и классом - PullRequest
       2

Designdata с xaml и классом

1 голос
/ 09 декабря 2011

У меня есть класс ComponentItem, который я упростил (псевдокод) ниже

public class ComponentItem : NotificationObject
{
    private ObservableCollection<FileItem> _files;
    public ObservableCollection<FileItem> Files

    private ObservableCollection<SparepartItem> spareparts;
    public ObservableCollection<SparepartItem> SpareParts
    public string ObjectId
}

Если я создаю данные дизайна для этого класса, я могу сделать это с помощью

<m:ComponentItem xmlns:m="clr-namespace:AITReportEditor.Infrastructure.Models;assembly=AITReportEditor.Infrastructure" ObjectId="AAAA-BBBB-CCCC-DDDDD">
    <m:ComponentItem.PartData>
        <m:PartDataItem Name="Component name" Status="1" Note="This is a note description"  />   
    </m:ComponentItem.PartData>
    <m:ComponentItem.Files>
        <m:FileItem FileName="Image1.jpg" Note="This is a note1" ObjectId="AAAA-BBBB-CCCC-DDDDD" ></m:FileItem>
        <m:FileItem FileName="Image1.jpg" Note="This is a note2" ObjectId="AAAA-BBBB-CCCC-DDDDE" ></m:FileItem>
    </m:ComponentItem.Files>
    <m:ComponentItem.SpareParts>
        <m:SparepartItem ObjectId="AAAA-BBBB-CCCC-DDDDD" Note="This is a note1" SpId="1" Amount="22" />
        <m:SparepartItem ObjectId="AAAA-BBBB-CCCC-DDDDE" Note="This is a note2" SpId="1" Amount="23" />
    </m:ComponentItem.SpareParts>
</m:ComponentItem>

Я могу использовать это как данные проектирования для usercontro. Пользовательский элемент управления содержит настраиваемые дочерние элементы управления пользователя, и данные дизайна не отображаются в дочерних элементах управления при проектировании родительского элемента, поэтому я хочу добавить данные проекта в дочерние элементы управления отдельно. Моя проблема в том, что я не могу определить xaml для такой коллекции, как

private ObservableCollection _files;

кажется, что нет способа объявить псевдо-код xaml

<List<FileItem>  ............
 <m:FileItem ...... />

Я решил это, объявив ненужный класс FilesItem

 public class FilesItem : ObservableCollection<FileItem>
    {
        public FilesItem()
        {

        }
    }
}

и файл xaml.

<m:FilesItem xmlns:m="clr-namespace:AITReportEditor.Infrastructure.Models;assembly=AITReportEditor.Infrastructure">
    <m:FileItem FileName="Image1.jpg" Note="This is a note1" ObjectId="AAAA-BBBB-CCCC-DDDDD" ></m:FileItem>
    <m:FileItem FileName="Image2.jpg" Note="This is a note2" ObjectId="AAAA-BBBB-CCCC-DDDDE" ></m:FileItem>
    <m:FileItem FileName="Image2.jpg" Note="This is a note2" ObjectId="AAAA-BBBB-CCCC-DDDDF" ></m:FileItem>
</m:FilesItem>

Кто-нибудь знает, так ли это, или я могу как-то избавиться от ненужных классов.

1 Ответ

2 голосов
/ 09 декабря 2011

Вы не можете создавать универсальные экземпляры в XAML (по крайней мере, в скомпилированном XAML), один из обходных путей - это создание подклассов, как вы показали.Другим методом было бы делегировать создание расширению разметки, что-то вроде этого:

[ContentProperty("Items")]
public class GenericCollectionFactoryExtension : MarkupExtension
{
    public Type Type { get; set; }

    private readonly List<Type> _TypeArguments = new List<Type>();
    public List<Type> TypeArguments { get { return _TypeArguments; } }

    private readonly List<Object> _Items = new List<Object>();
    public List<Object> Items { get { return _Items; } }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        var genericType = Type.MakeGenericType(_TypeArguments.ToArray());
        var list = Activator.CreateInstance(genericType) as IList;
        if (list == null) throw new Exception("Instance type does not implement IList");
        foreach (var item in Items)
        {
            list.Add(item);
        }
        return list;
    }
}

Это создает универсальную коллекцию с использованием отражения, добавляет все элементы, переданные ей (здесь предполагается, что IListбудет создан для упрощения) и возвращает коллекцию.

Использование:

xmlns:om="clr-namespace:System.Collections.ObjectModel;assembly=System"
<me:GenericCollectionFactory x:Key="files"
                Type="{x:Type om:ObservableCollection`1}">
    <me:GenericCollectionFactory.TypeArguments>
        <x:Type Type="m:FileItem" />
    </me:GenericCollectionFactory.TypeArguments>
    <m:FileItem FileName="Image1.jpg" Note="This is a note1" ObjectId="AAAA-BBBB-CCCC-DDDDD" />
    <m:FileItem FileName="Image1.jpg" Note="This is a note2" ObjectId="AAAA-BBBB-CCCC-DDDDE" />
</me:GenericCollectionFactory>
<!-- ... -->
<m:ComponentItem Files="{StaticResource files}"/>

`1 необходимо указать, что этот тип является универсальным.Вы можете сократить XAML, создав версию, которая принимает только один аргумент типа (поскольку многие классы, такие как ObservableCollection имеют только один), сохраняет три строки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...