Библиотека классов .NET Standard, на которую ссылается WPF — ошибка подписи в XAML во время разработки

Я сделал библиотеку классов netstandard. Я ориентируюсь на нетстандарт 1.6. Мой csproj выглядит так:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup Label="Globals">
    <SccProjectName>SAK</SccProjectName>
    <SccProvider>SAK</SccProvider>
    <SccAuxPath>SAK</SccAuxPath>
    <SccLocalPath>SAK</SccLocalPath>
  </PropertyGroup>

  <PropertyGroup>
    <TargetFramework>netstandard1.6</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="System.Runtime" Version="4.3.0" />
    <PackageReference Include="System.Runtime.Serialization.Primitives" Version="4.3.0" />
    <PackageReference Include="System.Runtime.Serialization.Xml" Version="4.3.0" />
  </ItemGroup>
</Project>

И у меня есть WPF-проект, в котором я ссылаюсь на эту dll. Я могу использовать классы netstandard dll в С#. Я могу использовать их и в xaml. Я получаю даже интеллект для них. Но дизайнер xaml говорит, что мой xaml недействителен. Я могу скомпилировать решение, я могу запустить приложение. Во время работы все ок. Но дизайнер не может с ним работать.

введите здесь описание изображения

Класс Person выглядит так:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Text;

namespace DS.Publications.Common
{
    [DataContract(Namespace = Constants.NamespaceConstants.DataContractNamespace)]
    public class Person : INotifyPropertyChanged
    {
        private string _Title = string.Empty;

        [DataMember]
        public string Title { get { return _Title; } set { Set(ref _Title, value); } }



        private string _ForeName;

        [DataMember]
        public string ForeName { get { return _ForeName; } set { Set(ref _ForeName, value); } }

        private string _LastName;
        [DataMember]
        public string LastName { get { return _LastName; } set { Set(ref _LastName, value); } }



        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propertyName)
        {
            this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        private bool Set<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
        {

            if (field == null || !field.Equals(value))
            {
                field = value;
                this.OnPropertyChanged(propertyName);
                return true;
            }
            return false;
        }
    }
}

Вы знаете обходной путь или у вас есть идея, как я могу это исправить?


person lvoros    schedule 06.10.2017    source источник
comment
Как определяется ваш класс?   -  person CShark    schedule 06.10.2017
comment
Я добавил источник класса Person   -  person lvoros    schedule 06.10.2017


Ответы (2)


Я также столкнулся с подобной проблемой; У меня был класс в стандартном проекте .NET, и я пытался отобразить его в ListBox с помощью Observable Collection. Получается, что XAML не любит DataContracts. Как только я удалил атрибут [DataContract] из своего класса .NET Standard, все заработало. Я уже подал отчет об ошибке Microsoft об этом поведении. Если мое предположение верно, ошибка должна исчезнуть, как только вы удалите атрибут [DataContract].

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

Возможно, он работает в скомпилированном режиме, потому что он определен только как ресурс. Пока он не отображается активно, он, вероятно, может работать. Может быть, дизайнер пытается отображать ресурсы?

Это может быть связано с другой ошибкой (здесь и здесь), где зависимости из .NET Standard не импортируются/не транслируются в другие проекты. В этом отчете об ошибке описывается, что при доступе к функциям из указанной DLL происходит сбой. По сути, у вас есть стандартная библиотека .NET, использующая стороннюю библиотеку X, и проект .NET Framework Z, использующий вашу стандартную библиотеку .NET Y. Как только вы вызываете метод в Y, который, в свою очередь, вызывает X, вы облажались. Вам нужно будет вручную импортировать все ссылки из Y в ваш проект Z.

О том, как это может быть связано. Контракты данных — это функция только .NET Standard, цель которой — заменить Serializable. Но у них, кажется, есть немного больше функциональных возможностей, которые каким-то образом запускаются внешним интерфейсом XAML. А поскольку контракты данных недоступны для .NET Framework, все рушится.

Если вам удастся найти решение, сообщите нам об этом, так как эта ошибка нуждается в «правильном» обходном пути...

person CShark    schedule 06.10.2017
comment
Спасибо за ваш ответ. Я удалил атрибуты DataContract и DataMember из своего класса, но это не помогло. - person lvoros; 06.10.2017
comment
Вы перекомпилировали свою библиотеку после этого? - person CShark; 06.10.2017

На самом деле я не нашел решения этой проблемы... Я установил целевую структуру моей библиотеки netstandard обратно на netstandard1.3. При таргетинге 1.3 все работает нормально. Я надеюсь, что исправление появится со следующим обновлением VS.

PS. Когда я установил цель на netstandard1.3, у меня возникла проблема, что были найдены старые двоичные файлы netstandard1.6, пока я действительно не очистил решение, как здесь: Как действительно очистить решение.

person lvoros    schedule 10.10.2017