Skip to content

Combos not supported for toolbar? #558

@rezanid

Description

@rezanid

I am trying to migrate a VSSDK VSIX to the new API. I have started with a clean in-proc template and then started migrating commands one by one, but the first command is a combo which seem to be not supported!

Image

Here is the original command I am trying to migrate:

[Command(PackageGuids.XrmToolsCmdSetIdString, PackageIds.ManageEnvironmentCmdId)]
internal class ManageEnvironmentsCommand : BaseCommand<ManageEnvironmentsCommand>
{
    private const string ManageItem = "Manage environments...";
    private const string DefaultItem = "Select environment...";

    [Import]
    public IEnvironmentEditor EnvironmentEditor { get; set; }

    [Import]
    public IEnvironmentProvider EnvironmentProvider { get; set; }

    protected override async Task InitializeCompletedAsync()
    {
        var componentModel = await Package.GetServiceAsync<SComponentModel, IComponentModel>();
        componentModel?.DefaultCompositionService.SatisfyImportsOnce(this);
    }

    protected override void BeforeQueryStatus(EventArgs e)
    {
        Command.Enabled = true;
        Command.Text = DefaultItem;
    }

    protected override async Task ExecuteAsync(OleMenuCmdEventArgs e)
    {
        if (e is not OleMenuCmdEventArgs args)
            return;

        if (args.OutValue != IntPtr.Zero)
        {
            await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
            var activeEnvironment = await EnvironmentProvider.GetActiveEnvironmentAsync(true);
            var environmentName = activeEnvironment?.Name ?? DefaultItem;
            if (args.OutValue != IntPtr.Zero) Marshal.GetNativeVariantForObject(environmentName, args.OutValue);
        }
        else if (args.InValue is string selected)
        {
            if (selected == ManageItem)
            {
                await EnvironmentEditor.EditEnvironmentsAsync();
                return;
            }

            await SetActiveEnvironmentAsync(selected);
        }
    }

    private async Task SetActiveEnvironmentAsync(string name)
    {
        if (string.IsNullOrWhiteSpace(name) || name == ManageItem)
        {
            return;
        }
        var environments = await EnvironmentProvider.GetAvailableEnvironmentsAsync();
        var environment = environments.FirstOrDefault(e => e.Name.Equals(name, StringComparison.OrdinalIgnoreCase));
        if (environment == null)
        {
            await VS.MessageBox.ShowErrorAsync("Manage Environments", $"Environment '{name}' not found.");
            return;
        }
        await EnvironmentProvider.SetActiveEnvironmentAsync(environment, true);
    }
}

[Command(PackageGuids.XrmToolsCmdSetIdString, PackageIds.ManageEnvironmenGetListCmdId)]
internal class ManageEnvironmentsGetListCommand : BaseCommand<ManageEnvironmentsGetListCommand>
{
    private const string ManageItem = "Manage environments...";

    [Import]
    public IEnvironmentProvider EnvironmentProvider { get; set; }

    protected override async Task InitializeCompletedAsync()
    {
        var componentModel = await Package.GetServiceAsync<SComponentModel, IComponentModel>();
        componentModel?.DefaultCompositionService.SatisfyImportsOnce(this);
    }

    protected override async Task ExecuteAsync(OleMenuCmdEventArgs e)
    {
        if (e is not OleMenuCmdEventArgs args)
            return;

        if (args.InValue is not null)
        {
            throw new ArgumentException("In parameter may not be specified");
        }
        else if (args.OutValue != IntPtr.Zero)
        {
            var environments = await EnvironmentProvider.GetAvailableEnvironmentsAsync();
            string[] envNames = [.. environments.Select(e => e.Name), ManageItem];
            Marshal.GetNativeVariantForObject(envNames, args.OutValue);
        }
        else
        {
            throw new ArgumentException("Out parameter must be specified");
        }
    }
}

Which is rendered like this:

Image

Basically I allow the developers select an environment (it will be highlighted) or click on the Manage Environments.. that displays a dialog to manage environments. You can see the source code of the original command here: https://github.com/rezanid/xrmtools/blob/main/src/XrmTools/Commands/ManageEnvironmentsCommand.cs

There's documentation at the top of the command about how it works, but you probably already know better than me.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions