Detail commands now call commands
Some checks failed
Spell checking / Check Spelling (push) Has been cancelled
Spell checking / Report (Push) (push) Has been cancelled
Spell checking / Report (PR) (push) Has been cancelled
Spell checking / Update PR (push) Has been cancelled

This commit is contained in:
Michael Jolley 2025-06-04 17:39:13 -05:00
parent 97c74f3297
commit 0421a16398
No known key found for this signature in database
GPG Key ID: F608E47FBB163707
8 changed files with 75 additions and 57 deletions

View File

@ -7,18 +7,16 @@ using Microsoft.CommandPalette.Extensions;
namespace Microsoft.CmdPal.UI.ViewModels;
public partial class DetailsCommandViewModel(
public partial class DetailsCommandsViewModel(
IDetailsElement _detailsElement,
WeakReference<IPageContext> context) : DetailsElementViewModel(_detailsElement, context)
{
private readonly ExtensionObject<IDetailsCommand> _dataModel =
new(_detailsElement.Data as IDetailsCommand);
public List<CommandViewModel> Commands { get; private set; } = [];
public string Text { get; private set; } = string.Empty;
public bool HasCommands => Commands.Count > 0;
public IconInfoViewModel Icon { get; private set; } = new(null);
public ICommand? Command { get; private set; }
private readonly ExtensionObject<IDetailsCommands> _dataModel =
new(_detailsElement.Data as IDetailsCommands);
public override void InitializeProperties()
{
@ -29,12 +27,16 @@ public partial class DetailsCommandViewModel(
return;
}
Text = model.Command.Name ?? string.Empty;
Icon = new(model.Command.Icon);
Command = model.Command;
UpdateProperty(nameof(Text));
UpdateProperty(nameof(Icon));
UpdateProperty(nameof(Command));
Commands = model
.Commands?
.Select(c =>
{
var vm = new CommandViewModel(c, PageContext);
vm.InitializeProperties();
return vm;
})
.ToList() ?? [];
UpdateProperty(nameof(HasCommands));
UpdateProperty(nameof(Commands));
}
}

View File

@ -49,7 +49,7 @@ public partial class DetailsViewModel(IDetails _details, WeakReference<IPageCont
{
IDetailsSeparator => new DetailsSeparatorViewModel(element, this.PageContext),
IDetailsLink => new DetailsLinkViewModel(element, this.PageContext),
IDetailsCommand => new DetailsCommandViewModel(element, this.PageContext),
IDetailsCommands => new DetailsCommandsViewModel(element, this.PageContext),
IDetailsTags => new DetailsTagsViewModel(element, this.PageContext),
_ => null,
};

View File

@ -29,7 +29,7 @@ public partial class DetailsDataTemplateSelector : DataTemplateSelector
{
DetailsSeparatorViewModel => SeparatorTemplate,
DetailsLinkViewModel => LinkTemplate,
DetailsCommandViewModel => CommandTemplate,
DetailsCommandsViewModel => CommandTemplate,
DetailsTagsViewModel => TagTemplate,
_ => null,
};

View File

@ -29,9 +29,9 @@
<cmdpalUI:DetailsDataTemplateSelector
x:Key="DetailsDataTemplateSelector"
CommandTemplate="{StaticResource DetailsCommandsTemplate}"
LinkTemplate="{StaticResource DetailsLinkTemplate}"
SeparatorTemplate="{StaticResource DetailsSeparatorTemplate}"
CommandTemplate="{StaticResource DetailsCommandTemplate}"
TagTemplate="{StaticResource DetailsTagsTemplate}" />
<converters:BoolToVisibilityConverter
@ -51,6 +51,27 @@
ToolTipService.ToolTip="{x:Bind ToolTip, Mode=OneWay}" />
</DataTemplate>
<DataTemplate x:Key="CommandTemplate" x:DataType="viewModels:CommandViewModel">
<StackPanel Orientation="Vertical">
<Button
Name="Command"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Left"
Click="Command_Click"
Style="{StaticResource SubtleButtonStyle}">
<StackPanel VerticalAlignment="Center" Orientation="Horizontal">
<cpcontrols:IconBox
Width="16"
Height="16"
Margin="0,3,8,0"
SourceKey="{x:Bind Icon, Mode=OneWay}"
SourceRequested="{x:Bind help:IconCacheProvider.SourceRequested}" />
<TextBlock Text="{x:Bind Name}" />
</StackPanel>
</Button>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="DetailsLinkTemplate" x:DataType="viewModels:DetailsLinkViewModel">
<StackPanel Orientation="Vertical">
<TextBlock
@ -72,25 +93,16 @@
Visibility="{x:Bind IsLink, Mode=OneWay}" />
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="DetailsCommandTemplate" x:DataType="viewModels:DetailsCommandViewModel">
<StackPanel Margin="0,0,0,0" Padding="0,0,0,0" Orientation="Vertical">
<Button
Style="{StaticResource SubtleButtonStyle}"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Left"
>
<StackPanel Orientation="Horizontal">
<cpcontrols:IconBox
Width="16"
Height="16"
Margin="4,0,4,0"
VerticalAlignment="Center"
SourceKey="{x:Bind Icon, Mode=OneWay}"
SourceRequested="{x:Bind help:IconCacheProvider.SourceRequested}" />
<TextBlock
Text="{x:Bind Text}" />
</StackPanel>
</Button>
<DataTemplate x:Key="DetailsCommandsTemplate" x:DataType="viewModels:DetailsCommandsViewModel">
<StackPanel Orientation="Vertical" Spacing="4">
<TextBlock
IsTextSelectionEnabled="True"
Text="{x:Bind Key, Mode=OneWay}"
TextWrapping="WrapWholeWords" />
<ItemsControl
ItemTemplate="{StaticResource CommandTemplate}"
ItemsSource="{x:Bind Commands, Mode=OneWay}"
Visibility="{x:Bind HasCommands, Mode=OneWay}" />
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="DetailsSeparatorTemplate" x:DataType="viewModels:DetailsSeparatorViewModel">

View File

@ -629,4 +629,12 @@ public sealed partial class ShellPage : Microsoft.UI.Xaml.Controls.Page,
return iconInfoVM?.HasIcon(requestedTheme == Microsoft.UI.Xaml.ElementTheme.Light) ?? false;
}
}
private void Command_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
if (sender is Button button && button.DataContext is CommandViewModel commandViewModel)
{
WeakReferenceMessenger.Default.Send<PerformCommandMessage>(new(commandViewModel.Model));
}
}
}

View File

@ -133,24 +133,20 @@ internal sealed partial class SampleListPageWithDetails : ListPage
new DetailsElement()
{
Key = "Commands",
Data = new DetailsCommand()
Data = new DetailsCommands()
{
Command = new ToastCommand("Hey! You clicked it!", MessageState.Success)
{
Name = "Do something amazing",
Icon = new("\uE945"),
},
},
},
new DetailsElement()
{
Data = new DetailsCommand()
{
Command = new ToastCommand("I warned you!", MessageState.Error)
{
Name = "Don't click me",
Icon = new("\uEA39"),
},
Commands = [
new ToastCommand("Hey! You clicked it!", MessageState.Success)
{
Name = "Do something amazing",
Icon = new("\uE945"),
},
new ToastCommand("I warned you!", MessageState.Error)
{
Name = "Don't click me",
Icon = new("\uEA39"),
},
],
},
},
],

View File

@ -4,7 +4,7 @@
namespace Microsoft.CommandPalette.Extensions.Toolkit;
public partial class DetailsCommand : IDetailsCommand
public partial class DetailsCommands : IDetailsCommands
{
public ICommand? Command { get; set; }
public ICommand[]? Commands { get; set; }
}

View File

@ -182,8 +182,8 @@ namespace Microsoft.CommandPalette.Extensions
String Text { get; };
}
[contract(Microsoft.CommandPalette.Extensions.ExtensionsContract, 1)]
interface IDetailsCommand requires IDetailsData {
ICommand Command { get; };
interface IDetailsCommands requires IDetailsData {
ICommand[] Commands { get; };
}
[uuid("58070392-02bb-4e89-9beb-47ceb8c3d741")]
[contract(Microsoft.CommandPalette.Extensions.ExtensionsContract, 1)]