diff --git a/components/MetadataControl/OpenSolution.bat b/components/MetadataControl/OpenSolution.bat new file mode 100644 index 00000000..814a56d4 --- /dev/null +++ b/components/MetadataControl/OpenSolution.bat @@ -0,0 +1,3 @@ +@ECHO OFF + +powershell ..\..\tooling\ProjectHeads\GenerateSingleSampleHeads.ps1 -componentPath %CD% %* \ No newline at end of file diff --git a/components/MetadataControl/samples/DelegateCommand.cs b/components/MetadataControl/samples/DelegateCommand.cs new file mode 100644 index 00000000..161cbc94 --- /dev/null +++ b/components/MetadataControl/samples/DelegateCommand.cs @@ -0,0 +1,171 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using CommunityToolkit.WinUI.Controls; +using System.Windows.Input; + +namespace MetadataControlExperiment.Samples; + +public class DelegateCommand : ICommand +{ + private readonly Action commandExecuteAction; + + private readonly Func commandCanExecute; + + /// + /// Initializes a new instance of the class. + /// + /// + /// The action to execute when called. + /// + /// + /// The function to call to determine if the command can execute the action. + /// + /// + /// Thrown if the execute action is null. + /// + public DelegateCommand(Action execute, Func? canExecute = null) + { + if (execute == null) + { + throw new ArgumentNullException(nameof(execute)); + } + + commandExecuteAction = execute; + commandCanExecute = canExecute ?? (() => true); + } + + /// + /// Occurs when changes occur that affect whether or not the command should execute. + /// + public event EventHandler? CanExecuteChanged; + + /// + /// Defines the method that determines whether the command can execute in its current state. + /// + /// + /// The parameter used by the command. + /// + /// + /// Returns a value indicating whether this command can be executed. + /// + public bool CanExecute(object? parameter = null) + { + try + { + return commandCanExecute(); + } + catch + { + return false; + } + } + + /// + /// Defines the method to be called when the command is invoked. + /// + /// + /// The parameter used by the command. + /// + public void Execute(object? parameter) + { + if (!CanExecute(parameter)) + { + return; + } + + try + { + commandExecuteAction(); + } + catch + { + Debugger.Break(); + } + } + + public void RaiseCanExecuteChanged() + { + CanExecuteChanged?.Invoke(this, EventArgs.Empty); + } +} + + +public class DelegateCommand : ICommand +{ + private readonly Action commandExecuteAction; + + private readonly Func commandCanExecute; + + public DelegateCommand(Action executeAction, Func? canExecute = null) + { + if (executeAction == null) + { + throw new ArgumentNullException(nameof(executeAction)); + } + + commandExecuteAction = executeAction; + commandCanExecute = canExecute ?? (e => true); + } + + /// + /// Occurs when changes occur that affect whether or not the command should execute. + /// + public event EventHandler? CanExecuteChanged; + + /// + /// Defines the method that determines whether the command can execute in its current state. + /// + /// + /// The parameter used by the command. + /// + /// + /// Returns a value indicating whether this command can be executed. + /// + public bool CanExecute(object? parameter) + { + try + { + return commandCanExecute(ConvertParameterValue(parameter!)); + } + catch + { + return false; + } + } + + /// + /// Defines the method to be called when the command is invoked. + /// + /// + /// The parameter used by the command. + /// + public void Execute(object? parameter) + { + if (!CanExecute(parameter)) + { + return; + } + + try + { + commandExecuteAction(ConvertParameterValue(parameter!)); + } + catch + { + Debugger.Break(); + } + } + + public void RaiseCanExecuteChanged() + { + CanExecuteChanged?.Invoke(this, EventArgs.Empty); + } + + private static T ConvertParameterValue(object parameter) + { + parameter = parameter is T ? parameter : Convert.ChangeType(parameter, typeof(T)); + return (T)parameter; + } +} \ No newline at end of file diff --git a/components/MetadataControl/samples/Dependencies.props b/components/MetadataControl/samples/Dependencies.props new file mode 100644 index 00000000..e622e1df --- /dev/null +++ b/components/MetadataControl/samples/Dependencies.props @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/components/MetadataControl/samples/MetadataControl.Samples.csproj b/components/MetadataControl/samples/MetadataControl.Samples.csproj new file mode 100644 index 00000000..7be36aac --- /dev/null +++ b/components/MetadataControl/samples/MetadataControl.Samples.csproj @@ -0,0 +1,8 @@ + + + MetadataControl + + + + + diff --git a/components/MetadataControl/samples/MetadataControl.md b/components/MetadataControl/samples/MetadataControl.md new file mode 100644 index 00000000..8fff46b6 --- /dev/null +++ b/components/MetadataControl/samples/MetadataControl.md @@ -0,0 +1,59 @@ +--- +title: MetadataControl +author: vgromfeld +description: The MetadataControl control displays a list of labels and hyper-links separated by a bullet. +keywords: MetadataControl, Control, metadata +dev_langs: + - csharp +category: Controls +subcategory: Layout +discussion-id: 0 +issue-id: 0 +--- + +# MetadataControl + +The [MetadataControl](/dotnet/api/microsoft.toolkit.uwp.ui.controls.metadatacontrol) control displays a list of labels and hyper-links separated by a bullet. +It also generates an accessible string representing its content. + +The bullet separator can be customized using the `Separator` property. +`AccessibleSeparator` is used as a replacement for `Separator` to generate the accessible string. + +The control needs a list of [MetadataItem](https://github.com/windows-toolkit/WindowsCommunityToolkit/blob/main/Microsoft.Toolkit.Uwp.UI.Controls.Core/MetadataControl/MetadataItem.cs). +Each item will be displayed either as a text or as an hyper-link (if the `Command`property is set). + +The default control template is using on a `TextBlock`. The style of this `TextBlock` can be customized using the `TextBlockStyle` property. + +> [!SAMPLE MetadataControlSample] + +## Example + +Add the control in the page: + +```xaml + +``` + +Add items to control: + +```cs +metadataControl.Items = new[] +{ + new MetadataItem { Label = "Hello" }, + new MetadataItem { Label = "World", Command = myCommand }, +}; +``` + +## MetadataItem + +A `MetadataItem` contains the information about one entry which will be displayed in the `MetadataControl` + +| Property | Type | Description | +| -- | -- | -- | +| Label | String | Gets or sets the label of the item | +| AccessibleLabel | String | Gets or sets the automation name that will be set on the item. If not set, `Label` will be used. | +| Command | ICommand | Gets or sets the command associated to the item. If null, the item will be displayed as a text field. If set, the item will be displayed as an hyperlink. | +| CommandParameter | Object | Gets or sets the parameter that will be provided to the `Command`| diff --git a/components/MetadataControl/samples/MetadataControlSample.xaml b/components/MetadataControl/samples/MetadataControlSample.xaml new file mode 100644 index 00000000..132b9963 --- /dev/null +++ b/components/MetadataControl/samples/MetadataControlSample.xaml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + +