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

View File

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

View File

@ -29,9 +29,9 @@
<cmdpalUI:DetailsDataTemplateSelector <cmdpalUI:DetailsDataTemplateSelector
x:Key="DetailsDataTemplateSelector" x:Key="DetailsDataTemplateSelector"
CommandTemplate="{StaticResource DetailsCommandsTemplate}"
LinkTemplate="{StaticResource DetailsLinkTemplate}" LinkTemplate="{StaticResource DetailsLinkTemplate}"
SeparatorTemplate="{StaticResource DetailsSeparatorTemplate}" SeparatorTemplate="{StaticResource DetailsSeparatorTemplate}"
CommandTemplate="{StaticResource DetailsCommandTemplate}"
TagTemplate="{StaticResource DetailsTagsTemplate}" /> TagTemplate="{StaticResource DetailsTagsTemplate}" />
<converters:BoolToVisibilityConverter <converters:BoolToVisibilityConverter
@ -51,6 +51,27 @@
ToolTipService.ToolTip="{x:Bind ToolTip, Mode=OneWay}" /> ToolTipService.ToolTip="{x:Bind ToolTip, Mode=OneWay}" />
</DataTemplate> </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"> <DataTemplate x:Key="DetailsLinkTemplate" x:DataType="viewModels:DetailsLinkViewModel">
<StackPanel Orientation="Vertical"> <StackPanel Orientation="Vertical">
<TextBlock <TextBlock
@ -72,25 +93,16 @@
Visibility="{x:Bind IsLink, Mode=OneWay}" /> Visibility="{x:Bind IsLink, Mode=OneWay}" />
</StackPanel> </StackPanel>
</DataTemplate> </DataTemplate>
<DataTemplate x:Key="DetailsCommandTemplate" x:DataType="viewModels:DetailsCommandViewModel"> <DataTemplate x:Key="DetailsCommandsTemplate" x:DataType="viewModels:DetailsCommandsViewModel">
<StackPanel Margin="0,0,0,0" Padding="0,0,0,0" Orientation="Vertical"> <StackPanel Orientation="Vertical" Spacing="4">
<Button <TextBlock
Style="{StaticResource SubtleButtonStyle}" IsTextSelectionEnabled="True"
HorizontalAlignment="Stretch" Text="{x:Bind Key, Mode=OneWay}"
HorizontalContentAlignment="Left" TextWrapping="WrapWholeWords" />
> <ItemsControl
<StackPanel Orientation="Horizontal"> ItemTemplate="{StaticResource CommandTemplate}"
<cpcontrols:IconBox ItemsSource="{x:Bind Commands, Mode=OneWay}"
Width="16" Visibility="{x:Bind HasCommands, Mode=OneWay}" />
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>
</StackPanel> </StackPanel>
</DataTemplate> </DataTemplate>
<DataTemplate x:Key="DetailsSeparatorTemplate" x:DataType="viewModels:DetailsSeparatorViewModel"> <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; 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() new DetailsElement()
{ {
Key = "Commands", Key = "Commands",
Data = new DetailsCommand() Data = new DetailsCommands()
{ {
Command = new ToastCommand("Hey! You clicked it!", MessageState.Success) Commands = [
{ new ToastCommand("Hey! You clicked it!", MessageState.Success)
Name = "Do something amazing", {
Icon = new("\uE945"), Name = "Do something amazing",
}, Icon = new("\uE945"),
}, },
}, new ToastCommand("I warned you!", MessageState.Error)
new DetailsElement() {
{ Name = "Don't click me",
Data = new DetailsCommand() Icon = new("\uEA39"),
{ },
Command = 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; 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; }; String Text { get; };
} }
[contract(Microsoft.CommandPalette.Extensions.ExtensionsContract, 1)] [contract(Microsoft.CommandPalette.Extensions.ExtensionsContract, 1)]
interface IDetailsCommand requires IDetailsData { interface IDetailsCommands requires IDetailsData {
ICommand Command { get; }; ICommand[] Commands { get; };
} }
[uuid("58070392-02bb-4e89-9beb-47ceb8c3d741")] [uuid("58070392-02bb-4e89-9beb-47ceb8c3d741")]
[contract(Microsoft.CommandPalette.Extensions.ExtensionsContract, 1)] [contract(Microsoft.CommandPalette.Extensions.ExtensionsContract, 1)]