如何将 IServiceProvider 注入 WPF UserControl

问题描述 投票:0回答:1

我正在编写一个 VSIX 项目,它显示解决方案中文件的树视图(如解决方案资源管理器)。

我现在需要显示项目项的相关图标(.cs 文件等),并具有以下代码。

using System.Windows;
using System.Windows.Controls;
using Microsoft.VisualStudio.Shell;
using System;
using System.Windows.Media;
using Microsoft.VisualStudio.Imaging.Interop;
using Microsoft.VisualStudio.Shell.Interop;

namespace Morris.FeatureExplorer.Features.FeatureExplorer;

public partial class VSIconControl : UserControl
{
    private readonly IServiceProvider ServiceProvider;

    public static readonly DependencyProperty FileExtensionProperty =
         DependencyProperty.Register("FileExtension", typeof(string), typeof(VSIconControl), new PropertyMetadata(null, OnFileExtensionChanged));

    public VSIconControl(IServiceProvider serviceProvider)
    {
        ServiceProvider = serviceProvider;
        InitializeComponent();
        UpdateIcon();
    }

    public string FileExtension
    {
        get { return (string)GetValue(FileExtensionProperty); }
        set { SetValue(FileExtensionProperty, value); }
    }

    private static void OnFileExtensionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var control = d as VSIconControl;
        control?.UpdateIcon();
    }

    private void UpdateIcon()
    {
        string fileExtension = FileExtension;
        if (string.IsNullOrEmpty(fileExtension))
        {
            // If no file extension is provided, use the folder icon
            fileExtension = "folder";
        }

        ImageSource imageSource = GetImageForFileExtension(ServiceProvider, fileExtension);
        IconImage.Source = imageSource;
    }

    private ImageSource GetImageForFileExtension(IServiceProvider serviceProvider, string fileExtension)
    {
        ImageMoniker moniker = GetImageMonikerForFileExtension(serviceProvider, fileExtension);
        ImageSource image = GetImageForMoniker(serviceProvider, moniker);
        return image;
    }

    private ImageMoniker GetImageMonikerForFileExtension(IServiceProvider serviceProvider, string fileExtension)
    {
        ThreadHelper.ThrowIfNotOnUIThread();

        IVsImageService2 imageService = serviceProvider.GetService(typeof(SVsImageService)) as IVsImageService2;
        if (imageService == null)
        {
            throw new InvalidOperationException("Failed to get IVsImageService2.");
        }

        // Get the ImageMoniker for the given file extension
        ImageMoniker moniker = imageService.GetImageMonikerForFile(fileExtension);
        return moniker;
    }

    private ImageSource GetImageForMoniker(IServiceProvider serviceProvider, ImageMoniker moniker)
    {
        ThreadHelper.ThrowIfNotOnUIThread();

        IVsImageService2 imageService = serviceProvider.GetService(typeof(SVsImageService)) as IVsImageService2;
        if (imageService is null)
            throw new InvalidOperationException("Failed to get IVsImageService2.");

        // Get the actual image for the moniker
        object image = imageService.GetImage(moniker, new ImageAttributes());
        return image as ImageSource;
    }
}

我正在尝试像这样使用这个组件:

<StackPanel Orientation="Horizontal">
  <featureui:VSIconControl FileExtension=".cs"/>
  <TextBlock Text="{Binding Name}" Margin="5"/>
</StackPanel>

但这不起作用,因为

VSIconControl
没有无参数构造函数。我怎样才能实现我的目标?

wpf dependency-injection vsix
1个回答
0
投票

Microsoft.VisualStudio.Shell.ServiceProvider.GlobalProvider

© www.soinside.com 2019 - 2024. All rights reserved.