У меня есть приложение для Android, где я сохраняю макет отчета в формате XML. Каждое поле имеет размер System.Drawing.Size и расположение System.Drawing.Point.

XML для точки

<Location>
    <X>32</X>
    <Y>40</Y>
</Location>

XML для размера

<Size>
    <Width>600</Width>
    <Height>56</Height>
</Size>

Объект содержит свойства для того же, что и

    private Size _Size = new Size(50, 20);
    public Size Size
    {
        get
        {
            return _Size;
        }
        set
        {
            bool DoEvent = true;
            if (value.Height == _Size.Height && value.Width == _Size.Width)
                DoEvent = false;
            _Size = value;
            if (DoEvent)
                OnPropertyChanged("Size");
        }
    }

И

    private System.Drawing.Point _Location;
    public System.Drawing.Point Location
    {
        get
        {
            return _Location;
        }
        set
        {
            _Location = value;
            OnPropertyChanged("Location");
        }
    }

Сериализатор создаю следующим образом

    public static void NewSerializer()
    {
        Type[] extraTypes = new Type[7];
        extraTypes[0] = typeof(MPSReportPage);
        extraTypes[1] = typeof(MPSReportField);
        extraTypes[2] = typeof(MPSTextField);
        extraTypes[3] = typeof(MPSImageField);
        extraTypes[4] = typeof(Margins);
        extraTypes[5] = typeof(Size);
        extraTypes[6] = typeof(System.Drawing.Point);

        try
        {
            ReportSerializer = new XmlSerializer(typeof(MPSReportDocument), extraTypes);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }

        //ReportSerializer = new XmlSerializer(typeof(MPSReportDocument));
    }

Точка и размер изначально не были такими как extraTypes, но я добавил их, чтобы попытаться решить проблему.

Это все отлично десериализуется, если я установил Linking to None. Если я установлю Linking to SDK Only, оба типа полей десериализуются в 0, 0. Все остальные типы полей десериализуются нормально. Заранее спасибо за любую помощь с этим.

https://github.com/JimWilcox3/XMLSerializerTest

Ссылка на решение Visual Studio, которое показывает проблему.

0
Jim Wilcox 6 Апр 2017 в 17:01

2 ответа

Лучший ответ

Эта проблема была отправлена в Microsoft, и они работают над этим. Однако, просмотрев мой код, я понял, что никогда не передаю размер или точку никаким собственным функциям. Я просто использую ширину / высоту или X / Y, чтобы выяснить, где нарисовать объект. Поэтому я просто создал свои собственные объекты Point и Size следующим образом:

[Serializable]
public class Point
{
    public Point()
    {
    }

    public Point(int X, int Y)
    {
        this.X = X;
        this.Y = Y;
    }
    public int X { get; set; }
    public int Y { get; set; }
}

[Serializable]
public class Size
{
    public Size()
    {
    }

    public Size(int Width, int Height)
    {
        this.Width = Width;
        this.Height = Height;
    }
    public int Width { get; set; }
    public int Height { get; set; }
}

И затем в моем десериализаторе я сделал дополнительные типы как:

public static void NewSerializer()
{
    Type[] extraTypes = new Type[7];
    extraTypes[0] = typeof(MPSReportPage);
    extraTypes[1] = typeof(MPSReportField);
    extraTypes[2] = typeof(MPSTextField);
    extraTypes[3] = typeof(MPSImageField);
    extraTypes[4] = typeof(Margins);
    extraTypes[5] = typeof(Size);
    extraTypes[6] = typeof(Point);

    try
    {
        ReportSerializer = new XmlSerializer(typeof(MPSReportDocument), extraTypes);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.ToString());
    }

    //ReportSerializer = new XmlSerializer(typeof(MPSReportDocument));
}

Мне пришлось полностью их квалифицировать, когда я использовал их в другом месте приложения, но это была небольшая цена за 20-30 МБ меньшего размера приложения.

0
Jim Wilcox 14 Апр 2017 в 14:58

В своем .csproj добавьте Mono.Android сборку в AndroidLinkSkip в свойстве PropertyGroup для своего {{X4 }} конфигурация (или Debug при желании).

<AndroidLinkSkip>Mono.Android</AndroidLinkSkip>

Или добавьте его через IDE:

enter image description here

Вам нужно будет просмотреть шаг Sweep monolinker, чтобы определить точные элементы, которые удаляются для создания файла дескриптора xml, который предотвращает удаление только тех необходимых типов, но отключает связывание. в целом Mono.Android сборка определенно будет работать и позволит вашей десериализации XML работать правильно.

1
SushiHangover 6 Апр 2017 в 19:39