Skip to content

Commit

Permalink
Merge branch 'release/v23.1.1' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
billhenn committed Jun 12, 2023
2 parents d989d12 + b355ea2 commit 8a1b21f
Show file tree
Hide file tree
Showing 52 changed files with 567 additions and 140 deletions.
2 changes: 1 addition & 1 deletion Documentation/topics/barcode/symbologies/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Actipro Bar Code includes a number of built-in common symbology implementations.

QR Code is a 2D symbology, originally used in automotive manufacturing, that is now used worldwide for a wide variety of purposes.

It is readable by most mobile devices with cameras and can be used to display text to a user, add a vCard contact to the user's device, open a URL, or compose a text message or e-mail.
It is readable by most mobile devices with cameras and can be used to display text to a user, compose a message, and much more.

</td>
</tr>
Expand Down
2 changes: 1 addition & 1 deletion Documentation/topics/barcode/symbologies/qr-code.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ order: 2

QR Code is a 2D symbology, originally used in automotive manufacturing, that is now used worldwide for a wide variety of purposes.

It is readable by most mobile devices with cameras and can be used to display text to a user, add a vCard contact to the user's device, open a URL, or compose a text message or e-mail.
It is readable by most mobile devices with cameras and can be used to display text to a user, compose a message, and much more.

![Screenshot](../images/symbology-qr-code.png)

Expand Down
56 changes: 46 additions & 10 deletions Documentation/topics/bars/controls/auto-generation.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,20 @@ Other contextual values (like certain `ICommand` types) can also be used when au
This time-saving feature helps reduce the need to specify many `Label` and `KeyTipText` values, except in scenarios where a customized value is necessary!

> [!TIP]
> The optional MVVM Library defines multiple view models that utilize the same [LabelGenerator](xref:@ActiproUIRoot.Controls.Bars.LabelGenerator) and [KeyTipTextGenerator](xref:@ActiproUIRoot.Controls.Bars.KeyTipTextGenerator) classes to auto-generate property values that are not explicitly passed to an object's constructor, so the same time-saving feature is available for MVVM configurations, too. See the [MVVM Support](../mvvm-support.md) topic for additional details on the MVVM Library.
> The optional MVVM Library defines multiple view models that utilize implementations of the same [ILabelGenerator](xref:@ActiproUIRoot.Controls.Bars.ILabelGenerator) and [IKeyTipTextGenerator](xref:@ActiproUIRoot.Controls.Bars.IKeyTipTextGenerator) interfaces to auto-generate property values that are not explicitly passed to an object's constructor, so this time-saving feature is available for MVVM configurations, too! See the [MVVM Support](../mvvm-support.md) topic for additional details on the MVVM Library.
> [!IMPORTANT]
> `Label` and `KeyTipText` are UI-based properties that may need to be localized, but the `Key` property value should not be localized. If localization of `Label` or `KeyTipText` is necessary for an application, those property values should be explicitly defined instead of relying on auto-generation from the non-localized `Key` property value.
> `Label` and `KeyTipText` are UI-based properties that may need to be localized, but the `Key` property value should not be localized. See the "Localization" section below for additional details.
## Label Generation

The static [LabelGenerator](xref:@ActiproUIRoot.Controls.Bars.LabelGenerator) class defines several convenience methods that can be used to automatically generate a label from various context.
Label generation is defined by the [ILabelGenerator](xref:@ActiproUIRoot.Controls.Bars.ILabelGenerator) interface with several convenience methods that can be used to automatically generate a label from various contexts. This interface is implemented by the [LabelGenerator](xref:@ActiproUIRoot.Controls.Bars.LabelGenerator) class, and an instance of this class is accessible, by default, from the static [BarControlService](xref:@ActiproUIRoot.Controls.Bars.BarControlService).[LabelGenerator](xref:@ActiproUIRoot.Controls.Bars.BarControlService.LabelGenerator) property.

The [BarControlService](xref:@ActiproUIRoot.Controls.Bars.BarControlService).[LabelGenerator](xref:@ActiproUIRoot.Controls.Bars.BarControlService.LabelGenerator) property can also be set to a custom implementation of [ILabelGenerator](xref:@ActiproUIRoot.Controls.Bars.ILabelGenerator) to extend or replace the default capabilities.

### Label from Key

The [LabelGenerator](xref:@ActiproUIRoot.Controls.Bars.LabelGenerator).[FromKey](xref:@ActiproUIRoot.Controls.Bars.LabelGenerator.FromKey*) method will analyze a given `Key` to determine the best label. Supported key values must *only* contain upper- or lower-ASCII letters `A-Z`, digits `0-9`, underscore (`_`), or hypen (`-`). Any other characters in the key will result in a `null` value being returned.
The default [LabelGenerator](xref:@ActiproUIRoot.Controls.Bars.LabelGenerator).[FromKey](xref:@ActiproUIRoot.Controls.Bars.LabelGenerator.FromKey*) method implementation will analyze a given `Key` to determine the best label. Supported key values must *only* contain upper- or lower-ASCII letters `A-Z`, digits `0-9`, underscore (`_`), or hypen (`-`). Any other characters in the key will result in a `null` value being returned.

When generating a label, the `Key` must be split into individual words using either word break characters or changes in character casing.

Expand All @@ -39,14 +41,14 @@ Any `Key` without word break characters will use either "PascalCase" or "camelCa

For example, the `Key` values `"OpenFile"` or `"openFile"` will recognize the words "Open" and "File".

With the exception of the first word in "camelCase", all recognized words will use the casing of the original word without converting to "Title Case", so the `Key` value `"ExportToXML"` will generate the label `"Export To XML"` with the original acronym casing unchanged.
Exception for the first word in "camelCase", all recognized words will use the casing of the original word without converting to "Title Case", so the `Key` value `"ExportToXML"` will generate the label `"Export To XML"` with the original acronym casing unchanged.

> [!IMPORTANT]
> A limitation of "camelCase" is that the casing of the leading word is ambiguous between words and acrynoyms (e.g., `"toUpper"` vs. `"ioException"`), so the first word will always be converted to "Title Case". For this reason, "PascalCase" is recommended instead.
### Label from Command

The [LabelGenerator](xref:@ActiproUIRoot.Controls.Bars.LabelGenerator).[FromCommand](xref:@ActiproUIRoot.Controls.Bars.LabelGenerator.FromCommand*) method will analyze an `ICommand` to determine the best label.
The default [LabelGenerator](xref:@ActiproUIRoot.Controls.Bars.LabelGenerator).[FromCommand](xref:@ActiproUIRoot.Controls.Bars.LabelGenerator.FromCommand*) method implementation will analyze an `ICommand` to determine the best label.
- The `ApplicationCommands.NotACommand` command is ignored and will always return a value of `null`.
- Any other `RoutedUICommand` will use the `RoutedUICommand.Text` property as the label.
- Any `RoutedCommand` will use the `RoutedCommand.Name` property as the label.
Expand All @@ -56,11 +58,13 @@ A value of `null` will be returned if a label could not be determined from the c

## Key Tip Generation

The static [KeyTipTextGenerator](xref:@ActiproUIRoot.Controls.Bars.KeyTipTextGenerator) class defines several convenience methods that can be used to automatically generate key tip text from various contexts.
Key tip generation is defined by the [IKeyTipTextGenerator](xref:@ActiproUIRoot.Controls.Bars.IKeyTipTextGenerator) interface with several convenience methods that can be used to automatically generate key tip text from various contexts. This interface is implemented by the [KeyTipTextGenerator](xref:@ActiproUIRoot.Controls.Bars.KeyTipTextGenerator) class, and an instance of this class is accessible, by default, from the static [BarControlService](xref:@ActiproUIRoot.Controls.Bars.BarControlService).[KeyTipTextGenerator](xref:@ActiproUIRoot.Controls.Bars.BarControlService.KeyTipTextGenerator) property.

The [BarControlService](xref:@ActiproUIRoot.Controls.Bars.BarControlService).[KeyTipTextGenerator](xref:@ActiproUIRoot.Controls.Bars.BarControlService.KeyTipTextGenerator) property can also be set to a custom implementation of [IKeyTipTextGenerator](xref:@ActiproUIRoot.Controls.Bars.IKeyTipTextGenerator) to extend or replace the default capabilities.

### Key Tip from Label

The [KeyTipTextGenerator](xref:@ActiproUIRoot.Controls.Bars.KeyTipTextGenerator).[FromLabel](xref:@ActiproUIRoot.Controls.Bars.KeyTipTextGenerator.FromLabel*) method will analyze a string label to determine the best key tip text. The label is analyzed against multiple rules (in the order listed below) and the first matching rule, if any, will determine the key tip text. A value of `null` will be returned if a matching rule was not found.
The default [KeyTipTextGenerator](xref:@ActiproUIRoot.Controls.Bars.KeyTipTextGenerator).[FromLabel](xref:@ActiproUIRoot.Controls.Bars.KeyTipTextGenerator.FromLabel*) method implementation will analyze a string label to determine the best key tip text. The label is analyzed against multiple rules (in the order listed below) and the first matching rule, if any, will determine the key tip text. A value of `null` will be returned if a matching rule is not found.

| Rule | Description |
| ---- | ---- |
Expand All @@ -75,16 +79,48 @@ In the list of rules above, regular expressions are used to locate "words" where

### Key Tip from KeyGesture

The [KeyTipTextGenerator](xref:@ActiproUIRoot.Controls.Bars.KeyTipTextGenerator).[FromKeyGesture](xref:@ActiproUIRoot.Controls.Bars.KeyTipTextGenerator.FromKeyGesture*) method will analyze a `KeyGesture` to determine the best key tip text.
The default [KeyTipTextGenerator](xref:@ActiproUIRoot.Controls.Bars.KeyTipTextGenerator).[FromKeyGesture](xref:@ActiproUIRoot.Controls.Bars.KeyTipTextGenerator.FromKeyGesture*) method implementation will analyze a `KeyGesture` to determine the best key tip text.

If the `KeyGesture.Key` property defines a `Key` whose string representation is a single letter, that letter will be used as the key tip text. For example, the `KeyGesture` for <kbd>Ctrl</kbd>+<kbd>V</kbd> (commonly used for the paste command), would return `"V"` as the key tip text.

A value of `null` will be returned if a value for key tip text could not be determined from the `KeyGesture`.

### Key Tip from Command

The [KeyTipTextGenerator](xref:@ActiproUIRoot.Controls.Bars.KeyTipTextGenerator).[FromCommand](xref:@ActiproUIRoot.Controls.Bars.KeyTipTextGenerator.FromCommand*) method will analyze an `ICommand` to determine the best key tip text.
The default [KeyTipTextGenerator](xref:@ActiproUIRoot.Controls.Bars.KeyTipTextGenerator).[FromCommand](xref:@ActiproUIRoot.Controls.Bars.KeyTipTextGenerator.FromCommand*) method implementation will analyze an `ICommand` to determine the best key tip text.

If the `ICommand` is a `RoutedCommand`, the `RoutedCommand.InputGestures` collection will be queried for gestures of type `KeyGesture`. The first `KeyGesture` that returns a non-`null` value when passed to [KeyTipTextGenerator](xref:@ActiproUIRoot.Controls.Bars.KeyTipTextGenerator).[FromKeyGesture](xref:@ActiproUIRoot.Controls.Bars.KeyTipTextGenerator.FromKeyGesture*) will be used as the key tip text.

A value of `null` will be returned if a value for key tip text could not be determined from the `ICommand`.

## Localization

The most common scenario for the automatic generation of labels and key tip texts is to auto-generate a label from a given key and then use the resulting label to auto-generate the key tip text. Since the key should not be localized, the default implementation of auto-generated values cannot be used when localized labels or key tip texts are required. In this scenario, a custom implementation of [ILabelGenerator](xref:@ActiproUIRoot.Controls.Bars.ILabelGenerator) and/or [IKeyTipTextGenerator](xref:@ActiproUIRoot.Controls.Bars.IKeyTipTextGenerator) can be used.

### Localizing Label Generation

Most localization will only need to customize the label that is auto-generated from a key since the key tip generator will use the localized label when auto-generating the key tip text.

The following steps can be used to implement localized label generation:

1. Create a new class that derives from [LabelGenerator](xref:@ActiproUIRoot.Controls.Bars.LabelGenerator).
1. Override the [LabelGenerator](xref:@ActiproUIRoot.Controls.Bars.LabelGenerator).[FromKey](xref:@ActiproUIRoot.Controls.Bars.LabelGenerator.FromKey*) method to return a localized label for the given key.
1. Optionally override the [LabelGenerator](xref:@ActiproUIRoot.Controls.Bars.LabelGenerator).[FromCommand](xref:@ActiproUIRoot.Controls.Bars.LabelGenerator.FromCommand*) method to return a localized label for the given command. This is only necessary if the `RoutedUICommand.Text` or `RoutedCommand.Name` properties are not already localized.
1. During application startup before any UI is initialized, set the [BarControlService](xref:@ActiproUIRoot.Controls.Bars.BarControlService).[LabelGenerator](xref:@ActiproUIRoot.Controls.Bars.BarControlService.LabelGenerator) property to an instance of the custom class.

> [!NOTE]
> As an alternative to deriving from the [LabelGenerator](xref:@ActiproUIRoot.Controls.Bars.LabelGenerator) class, a custom class can also fully implement the [ILabelGenerator](xref:@ActiproUIRoot.Controls.Bars.ILabelGenerator) interface instead.
### Localizing Key Tip Generation

While typically not required, localization may also be necessary when auto-generating key tip text from a label.

The following steps can be used to implement localized key tip generation:

1. Create a new class that derives from [KeyTipTextGenerator](xref:@ActiproUIRoot.Controls.Bars.KeyTipTextGenerator).
1. Override the [KeyTipTextGenerator](xref:@ActiproUIRoot.Controls.Bars.KeyTipTextGenerator).[FromLabel](xref:@ActiproUIRoot.Controls.Bars.KeyTipTextGenerator.FromLabel*) method to return a localized key tip text for the given label.
1. Optionally override the [KeyTipTextGenerator](xref:@ActiproUIRoot.Controls.Bars.KeyTipTextGenerator).[FromCommand](xref:@ActiproUIRoot.Controls.Bars.KeyTipTextGenerator.FromCommand*) method to return a localized key tip text for the given command. This is only necessary if key tip text cannot be auto-generated from a `KeyGesture` defined within `RoutedCommand.InputGestures`.
1. During application startup before any UI is initialized, set the [BarControlService](xref:@ActiproUIRoot.Controls.Bars.BarControlService).[KeyTipTextGenerator](xref:@ActiproUIRoot.Controls.Bars.BarControlService.KeyTipTextGenerator) property to an instance of the custom class.

> [!NOTE]
> As an alternative to deriving from the [KeyTipTextGenerator](xref:@ActiproUIRoot.Controls.Bars.KeyTipTextGenerator) class, a custom class can also fully implement the [IKeyTipTextGenerator](xref:@ActiproUIRoot.Controls.Bars.IKeyTipTextGenerator) interface instead.
3 changes: 3 additions & 0 deletions Documentation/topics/bars/controls/using-commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ The WPF framework has a couple built-in types that implement `ICommand`.

Screen tips and menu items are able to locate any `KeyBinding` that is on the `RoutedCommand` and can display its keyboard shortcut if no other input gesture text is specified.

> [!IMPORTANT]
> A `RoutedCommand` is dependent upon the visual tree for handling commands. When working with [Ribbon](../ribbon-features/index.md), the [RibbonBackstage](xref:@ActiproUIRoot.Controls.Bars.RibbonBackstage) and [RibbonQuickAccessToolBar](xref:@ActiproUIRoot.Controls.Bars.RibbonQuickAccessToolBar) controls are not always visual children of the [Ribbon](xref:@ActiproUIRoot.Controls.Bars.Ribbon) control. This means the ideal location to define a `CommandBinding` for a `RoutedCommand` is on the `Window` that contains the [Ribbon](xref:@ActiproUIRoot.Controls.Bars.Ribbon) control.
## RoutedUICommand

`RoutedUICommand` inherits `RoutedCommand` and has the same general design, but with the additional benefit that it contains a `Text` property too.
Expand Down
Loading

0 comments on commit 8a1b21f

Please sign in to comment.