3

我正在尝试在我的VSPackage项目中使用Graph#库,但不幸的是,有一些障碍需要克服。这是我所做的:

我将以下所有 DLL 复制到项目根目录中的文件夹 /Libraries 中:

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

所有的构建操作都是“内容”,选项复制到输出设置为“不复制”。

我将这些引用添加到我的项目中。(添加参考... -> 浏览 -> 从 /Library 文件夹中选择它们)

之后,我创建了以下文件。您可以看到 ViewModel 设置为 UserControl 的 DataContext,并且它定义了 UI 绑定的“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;
    }
}

视图模型

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 应用程序并完成了上述所有操作。在此解决方案中,一切正常!这太奇怪了!

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

4

4 回答 4

1

你能在你的项目中使用 nuget 吗?install-package graphsharp如果是这样,您应该尝试运行命令,而不是手动复制 dll-s 和引用。

我认为这是某种DLL strong name问题。

于 2012-10-17T22:02:13.553 回答
0

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

它说:

我有这样一个问题,并且在讨论中的某个地方进行了讨论。您需要做的是打开项目属性>路径并删除所有路径(只需将它们留空)

于 2012-10-19T12:55:45.670 回答
0

我现在设法让一切正常。还是要谢谢你的帮助!

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

可以在此处找到有关此内容的更多信息:托管 VSPackage 文件位置密钥

于 2012-10-19T14:06:37.427 回答
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
}
于 2020-09-16T04:34:01.337 回答