XamlParseException при использовании библиотек Graph#

Я пытаюсь использовать библиотеки Graph# в своем проекте VSPackage, но, к сожалению, есть некоторые препятствия для победы. Вот что я сделал:

Я скопировал все следующие библиотеки DLL в папку / библиотеки в корне проекта:

  • GraphSharp.dll
  • GraphSharp.Controls.dll
  • QuickGraph.dll
  • WPFExtensions.dll

Действие "Построить все" - "Содержимое", а для параметра "Копировать в вывод" установлено значение "Не копировать".

Я добавил эти ссылки в мой проект. (Добавить ссылку... -> Обзор -> выбрать их из папки / Библиотека)

После этого я создал следующие файлы. Вы можете видеть, что ViewModel установлен как DataContext UserControl и что он определяет "MethodGraph", к которому привязывается пользовательский интерфейс.

Файл XAML

<UserControl x:Class="Biocoder.InteractiveExploration.View.ExplorationControl"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:graphsharp="clr-namespace:GraphSharp.Controls;assembly=GraphSharp.Controls"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>

    <ListView Grid.Row="0" ItemsSource="{Binding SelectedMethods}">
        <ListView.View>
            <GridView>
                <GridViewColumn Header="Method" DisplayMemberBinding="{Binding Name}"/>
                <GridViewColumn Header="ReturnType" DisplayMemberBinding="{Binding ReflectionInfo.ReturnType}"/>
                <GridViewColumn Header="Incoming Calls"/>
                <GridViewColumn Header="Outgoing Calls"/>
            </GridView>
        </ListView.View>
    </ListView>

    <graphsharp:GraphLayout Graph="{Binding MethodGraph}"/>

</Grid>

</UserControl>

Код-за

public partial class ExplorationControl : UserControl
{
    public ExplorationControl()
    {
        InitializeComponent();

        // set the datacontext
        DataContext = InteractiveExplorationPackage.ExplorationToolViewModel;
    }
}

ViewModel

public class ExplorationToolViewModel : ViewModelBase
{
    private IBidirectionalGraph<object, IEdge<object>> _methodGraph;

    public IBidirectionalGraph<object, IEdge<object>> MethodGraph
    {
        get { return _methodGraph; }
        set
        {
            if (value != _methodGraph)
            {
                _methodGraph = value;
                NotifyPropertyChanged("MethodGraph");
            }
        }
    }

    public ExplorationToolViewModel()
    {
        InitializeViewModel();
    }

    private void InitializeViewModel()
    {
        SelectedMethods = new ObservableCollection<Method>();
        CreateGraph();
    }

    private void CreateGraph()
    {
        var g = new BidirectionalGraph<object, IEdge<object>>();

        // add vertices
        string[] vertices = new string[5];
        for (int i = 0; i < 5; i++)
        {
            vertices[i] = i.ToString();
            g.AddVertex(vertices[i]);
        }

        // add edges
        g.AddEdge(new Edge<object>(vertices[0], vertices[1]));
        g.AddEdge(new Edge<object>(vertices[1], vertices[2]));
        g.AddEdge(new Edge<object>(vertices[2], vertices[3]));
        g.AddEdge(new Edge<object>(vertices[3], vertices[1]));
        g.AddEdge(new Edge<object>(vertices[1], vertices[4]));

        MethodGraph = g;
    }
}

К счастью, я могу скомпилировать весь проект, но во время выполнения в теге возникает следующая ошибка в XAML (прямо над нужным тегом):

Не удалось загрузить файл или сборку 'GraphSharp.Controls, PublicKeyToken=null' или одну из ее зависимостей. Система не может найти файл.

Но я ссылался на сборки, они перечислены в списке литературы. В чем проблема? Может ли быть так, что на сборки нужно ссылаться иначе, чем обычно, при написании пакета Visual Studio (плагина)?

РЕДАКТИРОВАТЬ: Я просто попытался заставить его работать в другом проекте, поэтому я просто установил обычное приложение WPF и сделал все вышеописанное. В этом решении все работает правильно! Это так странно!

Надеюсь, вы можете помочь мне:-) С уважением!

3 ответа

Решение

Мне удалось заставить все работать сейчас. В любом случае спасибо за вашу помощь!

Проблема с VSPackages во время выполнения заключается в том, что они загружают сторонние сборки из другого места на компьютере, называемого папкой Private Assembly. (C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PrivateAssemblies) Поэтому все, что вам нужно сделать, это скопировать ссылочные сборки в эту папку (требуются права администратора). Чтобы иметь возможность использовать сборки при разработке, просто добавьте эти ссылки в ваш проект, как обычно, и компилятор будет использовать их обычным способом. Единственное отличие заключается во времени выполнения, поскольку Visual Studio загружает эти ссылки из папки Private Assemblies.

Дополнительную информацию об этом можно найти здесь: Ключи расположения файла управляемого VSPackage

Вы можете использовать Nuget в своем проекте? Если это так, вместо копирования dll-ов и ссылок вручную, вы должны попробовать запустить install-package graphsharp команда.

Я думаю, что это какая-то DLL strong name проблема.

Вы пробовали это? http://shfb.codeplex.com/workitem/32819

Это говорит:

У меня была такая проблема, и она обсуждалась где-то в дискуссиях. Что вам нужно сделать, это открыть свойства проекта> Пути и там удалить все пути (просто оставьте их пустыми)

Другое решение:

  1. Добавьте свою библиотеку как актив сборки в файл.vsixmanifest:
  2. Добавьте этот код в код инициализации вашего пакета.
protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
{
    AppDomain.CurrentDomain.AssemblyResolve += LoadFromSameFolder;

    static Assembly? LoadFromSameFolder(object sender, ResolveEventArgs args)
    {
        var executingAssemblyPath = Assembly.GetExecutingAssembly().Location;
        var folderPath = Path.GetDirectoryName(executingAssemblyPath) ?? string.Empty;
        var assemblyPath = Path.Combine(folderPath, $"{new AssemblyName(args.Name).Name}.dll");

        return File.Exists(assemblyPath)
            ? Assembly.LoadFrom(assemblyPath)
            : null;
    }

    // your code
}
Другие вопросы по тегам