使用Graph#库时出现XamlParseException异常

3
我正在尝试在我的VSPackage项目中使用Graph#库,但不幸的是还有一些障碍需要克服。这是我所做的:
我将以下所有DLL文件复制到项目根目录下的/Libraries文件夹中:
  • GraphSharp.dll
  • GraphSharp.Controls.dll
  • QuickGraph.dll
  • WPFExtensions.dll
所有文件的构建操作均为“内容”,并将“复制到输出目录”选项设置为“不复制”。
我将这些引用添加到了我的项目中。(添加引用... -> 浏览 -> 从 /Library 文件夹中选择它们)
之后,我创建了以下文件。您可以看到 ViewModel 被设置为 UserControl 的数据上下文,并定义了一个“MethodGraph”,供 UI 进行绑定。
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;
    }
}

视图模型

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;
    }
}

幸运的是,我可以编译整个项目,但在运行时,在所需的标签(<Graphsharp:GraphLayout x:Name="graphLayout">)上出现了以下XAML错误:

无法加载文件或程序集"GraphSharp.Controls, PublicKeyToken=null"或其其中一个依赖项。系统找不到指定的文件。

但我已经引用了这些程序集,它们列在了引用列表中。 问题出在哪里呢?写一个Visual Studio Package(插件)时,程序集是否需要以另一种方式进行引用?

编辑:我刚刚尝试在另一个项目中让它正常工作,所以我只是建立了一个普通的WPF应用程序并完成了以上所有步骤。在这个解决方案中一切正常工作!太奇怪了!

希望你能帮助我 :-) 最好的问候!

4个回答

1
你的项目能否使用NuGet?如果可以,不要手动复制DLL和引用,而应该尝试运行install-package graphsharp命令。
我认为这是一种DLL强名称问题。

谢谢你的帮助!我已经尝试过了,但是还是出现了相同的错误。我也尝试过不签署我的项目(这样引用的程序集也可以保持未签名状态),但错误仍然存在。非常奇怪的是,在20个案例中有一个可以工作!GraphLayout和ZoomControl都可以被加载并正常工作!我很快就要疯了,因为我已经尝试了几乎所有我能想到的方法。如果你有一些进一步的提示,那将非常好!到目前为止,非常感谢你! - Biocoder
我尝试了一下是否是签名(强名称)的问题。但不是这个原因。你可以使用Graph#源代码并自己签署程序集,或者取消签名你自己的项目(链接)。 我已经解决了这个问题。当然,现在我正在使用从NuGet加载的最新版本。 - Biocoder

0

你试过这个吗?http://shfb.codeplex.com/workitem/32819

它说:

我曾经遇到过这个问题,而且在讨论区里也有相关的讨论。你需要做的是打开项目属性 > 路径,然后删除所有路径(只需将其留空即可)


0

我现在已经成功解决了所有问题。无论如何,感谢您的帮助!

运行时 VSPackages 的问题基本上是它们从计算机上另一个位置(称为私有程序集文件夹)加载第三方程序集。(C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PrivateAssemblies) 因此,您只需要将引用的程序集复制到此文件夹中(需要管理员权限)。为了能够在开发时使用这些程序集,只需像平常一样将这些引用添加到您的项目中,编译器将以通常的方式使用它们。唯一的区别是在运行时,因为 Visual Studio 从私有程序集文件夹加载这些引用。

关于此更多信息可以在这里找到:Managed VSPackage File Location Keys


0

其他解决方案:

  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
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接