diff --git a/Documentation/topics/bars/controls/button.md b/Documentation/topics/bars/controls/button.md
index 555b25ce..a5960e56 100644
--- a/Documentation/topics/bars/controls/button.md
+++ b/Documentation/topics/bars/controls/button.md
@@ -118,10 +118,12 @@ The [BarMenuItem](xref:@ActiproUIRoot.Controls.Bars.BarMenuItem).[Label](xref:@A
The controls can display images that help identify their function.
-All [BarButton](xref:@ActiproUIRoot.Controls.Bars.BarButton) instances should set a [SmallImageSource](xref:@ActiproUIRoot.Controls.Bars.BarButton.SmallImageSource) at a minimum, which is generally used for `Small` and `Medium` variants, as well as in the [Ribbon Quick Access Toolbar](../ribbon-features/quick-access-toolbar.md) and if the control overflows to a menu. If the button supports a `Large` variant size, it should also define a [LargeImageSource](xref:@ActiproUIRoot.Controls.Bars.BarButton.LargeImageSource). When the button has a `Spacious` UI density, it will try to use [MediumImageSource](xref:@ActiproUIRoot.Controls.Bars.BarButton.MediumImageSource), falling back to [SmallImageSource](xref:@ActiproUIRoot.Controls.Bars.BarButton.SmallImageSource) if a medium image is not available.
+All [BarButton](xref:@ActiproUIRoot.Controls.Bars.BarButton) instances should set a [SmallImageSource](xref:@ActiproUIRoot.Controls.Bars.BarButton.SmallImageSource) at a minimum, which is generally used for `Small` and `Medium` variants, as well as in the [Ribbon Quick Access Toolbar](../ribbon-features/quick-access-toolbar.md) and if the control overflows to a menu. If the button supports a `Large` variant size, it should also define a [LargeImageSource](xref:@ActiproUIRoot.Controls.Bars.BarButton.LargeImageSource). When the button has a `Spacious` UI density, it will try to use [MediumImageSource](xref:@ActiproUIRoot.Controls.Bars.BarButton.MediumImageSource).
-[BarMenuItem](xref:@ActiproUIRoot.Controls.Bars.BarMenuItem) instances can optionally define a [SmallImageSource](xref:@ActiproUIRoot.Controls.Bars.BarMenuItem.SmallImageSource) that appears in the menu's icon column. When [UseLargeSize](xref:@ActiproUIRoot.Controls.Bars.BarMenuItem.UseLargeSize) is set to create a large menu item, the [LargeImageSource](xref:@ActiproUIRoot.Controls.Bars.BarMenuItem.LargeImageSource) property is used instead. When the menu item is checked, a highlight box will appear around the image. If no image is specified, a standard check glyph will be used in place of the image.
+> [!TIP]
+> See the [Control Basics](control-basics.md) topic for more detail on the fallback logic for button images.
+[BarMenuItem](xref:@ActiproUIRoot.Controls.Bars.BarMenuItem) instances can optionally define a [SmallImageSource](xref:@ActiproUIRoot.Controls.Bars.BarMenuItem.SmallImageSource) that appears in the menu's icon column. When [UseLargeSize](xref:@ActiproUIRoot.Controls.Bars.BarMenuItem.UseLargeSize) is set to create a large menu item, the [LargeImageSource](xref:@ActiproUIRoot.Controls.Bars.BarMenuItem.LargeImageSource) property is used instead. When the menu item is checked, a highlight box will appear around the image. If no image is specified, a standard check glyph will be used in place of the image.
### Description (BarMenuItem only)
diff --git a/Documentation/topics/bars/controls/control-basics.md b/Documentation/topics/bars/controls/control-basics.md
index 3583a042..6306c871 100644
--- a/Documentation/topics/bars/controls/control-basics.md
+++ b/Documentation/topics/bars/controls/control-basics.md
@@ -89,20 +89,29 @@ Some controls support a single image size, while other controls with variant siz
| Medium | 24x24 | Medium images are only used in [Simplified layout mode](../ribbon-features/layout-and-density.md) for some controls. |
| Large | 32x32 | Large images are used in certain controls when in large variant sizes. |
-When a button is in a ribbon with [Simplified layout mode](../ribbon-features/layout-and-density.md) active, it will fall back to using its small image if a medium image is not available.
-
#### Fallback Label and Images
If an image is not defined and is vital to the normal appearance of the control, a fallback display mechanism can occur, primarily in buttons.
In many cases, a missing image for small and medium variant size buttons will result in the label being displayed instead.
-In other cases, such as when the control is within the ribbon's [quick access toolbar](../ribbon-features/quick-access-toolbar.md) or when the control is a collapsed ribbon group, then a default fallback image will be used.
+In other cases, such as when the control is within the ribbon's [quick access toolbar](../ribbon-features/quick-access-toolbar.md) or when the control is a collapsed ribbon group, then a default missing fallback image will be used.
![Screenshot](../images/fallback-image.png)
*The fallback image*
+The following table describes the priority order of properties (e.g., `SmallImageSource`, `LargeImageSource`) used to resolve an image for a desired image size.
+
+| Desired Image Size | Resolution Priority |
+|-----|-----|
+| Small (16x16) | Small, Large (downscaled), Medium (downscaled), Missing (if no label visible) |
+| Medium (24x24) | Medium, Small (centered), Large (downscaled), Missing (if no label visible) |
+| Large (32x32) | Large, Medium (centered), Small (centered), Missing |
+
+> [!TIP]
+> When using a vector image for a button with the intention of using a single image for all image sizes, it is best to make a single 32x32 size vector image and assign it to the button's `LargeImageSource` property. Per the table above, a `Large` image can scale down as a fallback for other image sizes. When using raster images, it is much better to use a distinct image design for the `Large` and `Small` image sizes at a minimum.
+
### Title
An optional string `Title` can be specified, which is intended to override the control's `Label` when displayed in screen tips and customization UI.
diff --git a/Documentation/topics/bars/controls/gallery.md b/Documentation/topics/bars/controls/gallery.md
index dfb10e5e..2f8a618d 100644
--- a/Documentation/topics/bars/controls/gallery.md
+++ b/Documentation/topics/bars/controls/gallery.md
@@ -324,6 +324,10 @@ The gallery's `SelectedItem` property may be set at any time to alter the select
The [IsSelectionSupported](xref:@ActiproUIRoot.Controls.Bars.Primitives.BarGalleryBase.IsSelectionSupported) property, which defaults to `true`, can be set to `false` to prevent a selection from being retained when an item is clicked. It does this by automatically clearing the `SelectedItem` after a selection is made. This feature is handy for galleries that should take an action when an item is clicked, such as a gallery that inserts a symbol into a document based on the item that was clicked.
+### Automatically Scrolling to the Selected Item (RibbonGallery only)
+
+The [RibbonGallery](xref:@ActiproUIRoot.Controls.Bars.RibbonGallery).[CanAutoScrollToSelectedItem](xref:@ActiproUIRoot.Controls.Bars.RibbonGallery.CanAutoScrollToSelectedItem) property, which defaults to `false`, can be set to `true` to automatically scroll to the in-ribbon gallery's selected item when the selection changes. This ensures that external changes to the selection keep the newly-selected item visible in the user interface.
+
### Item Templates
Gallery controls generate a [BarGalleryItem](xref:@ActiproUIRoot.Controls.Bars.BarGalleryItem) container for each gallery item in the gallery's `ItemsSource`.
diff --git a/Documentation/topics/bars/controls/popup-button.md b/Documentation/topics/bars/controls/popup-button.md
index 8a193055..c870ba5a 100644
--- a/Documentation/topics/bars/controls/popup-button.md
+++ b/Documentation/topics/bars/controls/popup-button.md
@@ -124,7 +124,10 @@ The [BarMenuItem](xref:@ActiproUIRoot.Controls.Bars.BarMenuItem).[Label](xref:@A
The controls can display images that help identify their function.
-All [BarPopupButton](xref:@ActiproUIRoot.Controls.Bars.BarPopupButton) instances should set a [SmallImageSource](xref:@ActiproUIRoot.Controls.Bars.BarPopupButton.SmallImageSource) at a minimum, which is generally used for `Small` and `Medium` variants, as well as in the [Ribbon Quick Access Toolbar](../ribbon-features/quick-access-toolbar.md) and if the control overflows to a menu. If the button supports a `Large` variant size, it should also define a [LargeImageSource](xref:@ActiproUIRoot.Controls.Bars.BarPopupButton.LargeImageSource). When the button has a `Spacious` UI density, it will try to use [MediumImageSource](xref:@ActiproUIRoot.Controls.Bars.BarPopupButton.MediumImageSource), falling back to [SmallImageSource](xref:@ActiproUIRoot.Controls.Bars.BarPopupButton.SmallImageSource) if a medium image is not available.
+All [BarPopupButton](xref:@ActiproUIRoot.Controls.Bars.BarPopupButton) instances should set a [SmallImageSource](xref:@ActiproUIRoot.Controls.Bars.BarPopupButton.SmallImageSource) at a minimum, which is generally used for `Small` and `Medium` variants, as well as in the [Ribbon Quick Access Toolbar](../ribbon-features/quick-access-toolbar.md) and if the control overflows to a menu. If the button supports a `Large` variant size, it should also define a [LargeImageSource](xref:@ActiproUIRoot.Controls.Bars.BarPopupButton.LargeImageSource). When the button has a `Spacious` UI density, it will try to use [MediumImageSource](xref:@ActiproUIRoot.Controls.Bars.BarPopupButton.MediumImageSource).
+
+> [!TIP]
+> See the [Control Basics](control-basics.md) topic for more detail on the fallback logic for button images.
[BarMenuItem](xref:@ActiproUIRoot.Controls.Bars.BarMenuItem) instances can optionally define a [SmallImageSource](xref:@ActiproUIRoot.Controls.Bars.BarMenuItem.SmallImageSource) that appears in the menu's icon column. When [UseLargeSize](xref:@ActiproUIRoot.Controls.Bars.BarMenuItem.UseLargeSize) is set to create a large menu item, the [LargeImageSource](xref:@ActiproUIRoot.Controls.Bars.BarMenuItem.LargeImageSource) property is used instead.
diff --git a/Documentation/topics/bars/controls/split-button.md b/Documentation/topics/bars/controls/split-button.md
index 848f6352..0ebc3cc4 100644
--- a/Documentation/topics/bars/controls/split-button.md
+++ b/Documentation/topics/bars/controls/split-button.md
@@ -130,7 +130,10 @@ The [BarSplitMenuItem](xref:@ActiproUIRoot.Controls.Bars.BarSplitMenuItem).[Labe
The controls can display images that help identify their function.
-All [BarSplitButton](xref:@ActiproUIRoot.Controls.Bars.BarSplitButton) instances should set a [SmallImageSource](xref:@ActiproUIRoot.Controls.Bars.BarPopupButton.SmallImageSource) at a minimum, which is generally used for `Small` and `Medium` variants, as well as in the [Ribbon Quick Access Toolbar](../ribbon-features/quick-access-toolbar.md) and if the control overflows to a menu. If the button supports a `Large` variant size, it should also define a [LargeImageSource](xref:@ActiproUIRoot.Controls.Bars.BarPopupButton.LargeImageSource). When the button has a `Spacious` UI density, it will try to use [MediumImageSource](xref:@ActiproUIRoot.Controls.Bars.BarPopupButton.MediumImageSource), falling back to [SmallImageSource](xref:@ActiproUIRoot.Controls.Bars.BarPopupButton.SmallImageSource) if a medium image is not available.
+All [BarSplitButton](xref:@ActiproUIRoot.Controls.Bars.BarSplitButton) instances should set a [SmallImageSource](xref:@ActiproUIRoot.Controls.Bars.BarPopupButton.SmallImageSource) at a minimum, which is generally used for `Small` and `Medium` variants, as well as in the [Ribbon Quick Access Toolbar](../ribbon-features/quick-access-toolbar.md) and if the control overflows to a menu. If the button supports a `Large` variant size, it should also define a [LargeImageSource](xref:@ActiproUIRoot.Controls.Bars.BarPopupButton.LargeImageSource). When the button has a `Spacious` UI density, it will try to use [MediumImageSource](xref:@ActiproUIRoot.Controls.Bars.BarPopupButton.MediumImageSource).
+
+> [!TIP]
+> See the [Control Basics](control-basics.md) topic for more detail on the fallback logic for button images.
[BarSplitMenuItem](xref:@ActiproUIRoot.Controls.Bars.BarSplitMenuItem) instances can optionally define a [SmallImageSource](xref:@ActiproUIRoot.Controls.Bars.BarMenuItem.SmallImageSource) that appears in the menu's icon column. When [UseLargeSize](xref:@ActiproUIRoot.Controls.Bars.BarMenuItem.UseLargeSize) is set to create a large menu item, the [LargeImageSource](xref:@ActiproUIRoot.Controls.Bars.BarMenuItem.LargeImageSource) property is used instead. When the menu item is checked, a highlight box will appear around the image. If no image is specified, a standard check glyph will be used in place of the image.
diff --git a/Documentation/topics/bars/controls/using-custom-controls.md b/Documentation/topics/bars/controls/using-custom-controls.md
index 9fae7fab..46fdafc1 100644
--- a/Documentation/topics/bars/controls/using-custom-controls.md
+++ b/Documentation/topics/bars/controls/using-custom-controls.md
@@ -111,6 +111,7 @@ xmlns:editors="http://schemas.actiprosoftware.com/winfx/xaml/editors"
bars:BarControlService.Key="Minimum"
bars:BarControlService.Label="Minimum"
bars:BarControlService.PanelSpacingSuggestion="Both"
+ bars:BarControlService.SmallImageSource="/Images/Minimum16.png"
Width="60" MinHeight="24" MaxHeight="30"
UsageContext="ToolBar"
themes:ThemeProperties.CornerRadius="3"
@@ -120,6 +121,8 @@ xmlns:editors="http://schemas.actiprosoftware.com/winfx/xaml/editors"
```
+When a label and/or small image are applied to a custom control with the attached [LabelProperty](xref:@ActiproUIRoot.Controls.Bars.BarControlService.LabelProperty) and [SmallImageSourceProperty](xref:@ActiproUIRoot.Controls.Bars.BarControlService.SmallImageSourceProperty) properties, they will be displayed in the [BarMenuControlWrapper](xref:@ActiproUIRoot.Controls.Bars.BarMenuControlWrapper) alongside the custom control itself. The small image will align in the icon column with other menu items.
+
## Screen Tips
The [ScreenTip](xref:@ActiproUIRoot.Controls.Bars.ScreenTip) class inherits the native `ToolTip` control and therefore can be used anywhere a normal tooltip can, including on custom controls.
diff --git a/Documentation/topics/bars/mvvm-support.md b/Documentation/topics/bars/mvvm-support.md
index ed51aab4..1743ae7f 100644
--- a/Documentation/topics/bars/mvvm-support.md
+++ b/Documentation/topics/bars/mvvm-support.md
@@ -187,7 +187,8 @@ The following table shows the ribbon footer content view model types defined in
| Name | Description |
|-----|-----|
-| [RibbonFooterSimpleContentViewModel](xref:@ActiproUIRoot.Controls.Bars.Mvvm.RibbonFooterSimpleContentViewModel) | Specifies an `ImageSource` and text message to render in the ribbon [footer](ribbon-features/footer.md). |
+| [RibbonFooterInfoBarContentViewModel](xref:@ActiproUIRoot.Controls.Bars.Mvvm.RibbonFooterInfoBarContentViewModel) | Configures an [InfoBar](../shared/windows-controls/info-bar.md) to render in the ribbon [footer](ribbon-features/footer.md) |
+| [RibbonFooterSimpleContentViewModel](xref:@ActiproUIRoot.Controls.Bars.Mvvm.RibbonFooterSimpleContentViewModel) | Specifies an `ImageSource` and text message to render in the ribbon [footer](ribbon-features/footer.md). |
#### Gallery Item View Models
diff --git a/Documentation/topics/bars/ribbon-features/backstage.md b/Documentation/topics/bars/ribbon-features/backstage.md
index 5e04f567..c2335966 100644
--- a/Documentation/topics/bars/ribbon-features/backstage.md
+++ b/Documentation/topics/bars/ribbon-features/backstage.md
@@ -115,10 +115,14 @@ When there are not many tabs or buttons to display in the backstage, the backsta
## Auto-Selecting a Tab When Backstage Opens
+The first tab is auto-selected if no tab is currently selected when the backstage opens or when the [RibbonBackstage](xref:@ActiproUIRoot.Controls.Bars.RibbonBackstage).[CanSelectFirstTabOnOpen](xref:@ActiproUIRoot.Controls.Bars.RibbonBackstage.CanSelectFirstTabOnOpen) property is `true`, which is that property's default value.
+
The [RibbonBackstage](xref:@ActiproUIRoot.Controls.Bars.RibbonBackstage).[IsOpen](xref:@ActiproUIRoot.Controls.Bars.RibbonBackstage.IsOpen) property gets or sets whether the backstage is currently open. A related [RibbonBackstage](xref:@ActiproUIRoot.Controls.Bars.RibbonBackstage).[IsOpenChanged](xref:@ActiproUIRoot.Controls.Bars.RibbonBackstage.IsOpenChanged) event is raised whenever that property changes. This is an ideal place to initialize the backstage so that a certain tab is always selected when it opens.
The event handler for the [RibbonBackstage](xref:@ActiproUIRoot.Controls.Bars.RibbonBackstage).[IsOpenChanged](xref:@ActiproUIRoot.Controls.Bars.RibbonBackstage.IsOpenChanged) event can check to see if the backstage is being opened and, if so, ensure the [RibbonBackstage](xref:@ActiproUIRoot.Controls.Bars.RibbonBackstage).`SelectedItem` property is set to the desired tab.
+Set the [RibbonBackstage](xref:@ActiproUIRoot.Controls.Bars.RibbonBackstage).[CanSelectFirstTabOnOpen](xref:@ActiproUIRoot.Controls.Bars.RibbonBackstage.CanSelectFirstTabOnOpen) property to `false` if the selected tab will be set programmatically.
+
## TaskTabControl
The [TaskTabControl](xref:@ActiproUIRoot.Controls.Bars.TaskTabControl) is a styled version of a native WPF `TabControl` that renders its tabs on the left side. The selected tab's content appears on the right side. This tab control is ideal for use on a [RibbonBackstageTabItem](xref:@ActiproUIRoot.Controls.Bars.RibbonBackstageTabItem) since it provides a secondary level of tabs. It can be used externally to backstage as well.
diff --git a/Documentation/topics/bars/ribbon-features/footer.md b/Documentation/topics/bars/ribbon-features/footer.md
index dee414ef..c593eca4 100644
--- a/Documentation/topics/bars/ribbon-features/footer.md
+++ b/Documentation/topics/bars/ribbon-features/footer.md
@@ -48,14 +48,23 @@ The footer may also be defined by setting the [Ribbon](xref:@ActiproUIRoot.Contr
The optional companion [MVVM Library](../mvvm-support.md) defines a [RibbonFooterViewModel](xref:@ActiproUIRoot.Controls.Bars.Mvvm.RibbonFooterViewModel) class that is intended to be used as a view model for a [RibbonFooterControl](xref:@ActiproUIRoot.Controls.Bars.RibbonFooterControl) control, and the [BarControlTemplateSelector](xref:@ActiproUIRoot.Controls.Bars.Mvvm.BarControlTemplateSelector) class in the library generates a [RibbonFooterControl](xref:@ActiproUIRoot.Controls.Bars.RibbonFooterControl) for that view model.
+### Simple Content
+
A [RibbonFooterSimpleContentViewModel](xref:@ActiproUIRoot.Controls.Bars.Mvvm.RibbonFooterSimpleContentViewModel) instance may be assigned to the [RibbonFooterViewModel](xref:@ActiproUIRoot.Controls.Bars.Mvvm.RibbonFooterViewModel).[Content](xref:@ActiproUIRoot.Controls.Bars.Mvvm.RibbonFooterViewModel.Content) property. This simple content view model supports easy definition of an image and text message for the footer.
+### InfoBar Content
+
+A [RibbonFooterInfoBarContentViewModel](xref:@ActiproUIRoot.Controls.Bars.Mvvm.RibbonFooterInfoBarContentViewModel) instance may be assigned to the [RibbonFooterViewModel](xref:@ActiproUIRoot.Controls.Bars.Mvvm.RibbonFooterViewModel).[Content](xref:@ActiproUIRoot.Controls.Bars.Mvvm.RibbonFooterViewModel.Content) property. This view model supports configuring an [InfoBar](../../shared/windows-controls/info-bar.md) for the footer.
+
+> [!IMPORTANT]
+> The [RibbonFooterViewModel](xref:@ActiproUIRoot.Controls.Bars.Mvvm.RibbonFooterViewModel).[Padding](xref:@ActiproUIRoot.Controls.Bars.Mvvm.RibbonFooterViewModel.Padding) property should be set to `0` when using [RibbonFooterInfoBarContentViewModel](xref:@ActiproUIRoot.Controls.Bars.Mvvm.RibbonFooterInfoBarContentViewModel) as the content so the [InfoBar](../../shared/windows-controls/info-bar.md) can render edge-to-edge.
+
> [!TIP]
> See the [MVVM Support](../mvvm-support.md) topic for more information on how to use the library's view models and view templates to create and manage your application's bars controls with MVVM techniques.
## Showing / Hiding the Footer
-The ribbon will display the footer as long as the [Ribbon](xref:@ActiproUIRoot.Controls.Bars.Ribbon).[FooterContent](xref:@ActiproUIRoot.Controls.Bars.Ribbon.FooterContent) property is defined. To show the footer, set the [FooterContent](xref:@ActiproUIRoot.Controls.Bars.Ribbon.FooterContent) property to the desired content. To hide the footer, set the [FooterContent](xref:@ActiproUIRoot.Controls.Bars.Ribbon.FooterContent) property to `null`.
+The ribbon will display the footer as long as the [Ribbon](xref:@ActiproUIRoot.Controls.Bars.Ribbon).[FooterContent](xref:@ActiproUIRoot.Controls.Bars.Ribbon.FooterContent) property is defined. To show the footer, set the [FooterContent](xref:@ActiproUIRoot.Controls.Bars.Ribbon.FooterContent) property to the desired content. To hide the footer, set the [FooterContent](xref:@ActiproUIRoot.Controls.Bars.Ribbon.FooterContent) property to `null` or invoke the command defined by the [ClearFooterCommand](xref:@ActiproUIRoot.Controls.Bars.Ribbon.ClearFooterCommand) property.
> [!IMPORTANT]
> The ribbon has an altered appearance based on the presence of the footer, so changing the `Visibility` property of a footer control is not sufficient to properly hide the footer.
@@ -70,4 +79,70 @@ Instead of setting the `Background` property directly, the [RibbonFooterControl]
See the [Reusable Assets](../../themes/reusable-assets.md) topic for details on customizing the pre-defined brush assets used by a footer kind.
> [!TIP]
-> See the "Footer" Bars Ribbon QuickStart of the Sample Browser application for a full demonstration of working with the ribbon footer.
\ No newline at end of file
+> See the "Footer" Bars Ribbon QuickStart of the Sample Browser application for a full demonstration of working with the ribbon footer.
+
+## Using InfoBar in the Footer
+
+The [InfoBar](../../shared/windows-controls/info-bar.md) is specifically designed to display non-intrusive user messages and is a natural fit for use in the footer, but some properties should be changed to optimally display the control.
+
+- **BorderThickness** - Set [InfoBar](xref:@ActiproUIRoot.Controls.InfoBar).`BorderThickness` to `0` since the footer already defines a border.
+- **IsAnimationEnabled** - The ribbon already animates when a footer is opened/closed, so set [InfoBar](xref:@ActiproUIRoot.Controls.InfoBar).[IsAnimationEnabled](xref:@ActiproUIRoot.Controls.InfoBar.IsAnimationEnabled) to `false`.
+
+### Padding
+
+Since the [InfoBar](../../shared/windows-controls/info-bar.md) should fill the entire area of the footer, it is important to set the [RibbonFooterControl](xref:@ActiproUIRoot.Controls.Bars.RibbonFooterControl).`Padding` to `0`. Any changes to padding should be assigned to [InfoBar](xref:@ActiproUIRoot.Controls.InfoBar).`Padding`.
+
+### Background Color
+
+The default background color for [InfoBar](../../shared/windows-controls/info-bar.md) (at the default [InfoBarSeverity](xref:@ActiproUIRoot.Controls.InfoBarSeverity)) is different than the default footer background color. It is recommended to apply a `Style` to [InfoBar](xref:@ActiproUIRoot.Controls.InfoBar) that changes the `Background` property to `Transparent` when the default [InfoBarSeverity](xref:@ActiproUIRoot.Controls.InfoBarSeverity) is used as this will allow the footer's own `Background` to be shown.
+
+> [!IMPORTANT]
+> Setting the `Background` property directly will prevent the background color from changing to match the current [InfoBarSeverity](xref:@ActiproUIRoot.Controls.InfoBarSeverity).
+
+### Closing
+
+When [InfoBar](xref:@ActiproUIRoot.Controls.InfoBar).[CanClose](xref:@ActiproUIRoot.Controls.InfoBar.CanClose) is set to `true`, a **Close Button** is displayed. By default, clicking this button will hide the [InfoBar](xref:@ActiproUIRoot.Controls.InfoBar) (i.e., set `Visibility` to `Collapsed`), but hiding the control does not effectively hide the ribbon's footer. As noted in the "Showing / Hiding the Footer" section above, the footer must be set to `null` to properly hide the footer.
+
+The easiest solution is to bind the [InfoBar](xref:@ActiproUIRoot.Controls.InfoBar).[CloseButtonCommand](xref:@ActiproUIRoot.Controls.InfoBar.CloseButtonCommand) to the ancestor [Ribbon](xref:@ActiproUIRoot.Controls.Bars.Ribbon).[ClearFooterCommand](xref:@ActiproUIRoot.Controls.Bars.Ribbon.ClearFooterCommand) so clicking the **Close Button** will clear the footer. Otherwise, use a custom command or listen to the [InfoBar](xref:@ActiproUIRoot.Controls.InfoBar).[CloseButtonClick](xref:@ActiproUIRoot.Controls.InfoBar.CloseButtonClick) event and clear the footer as noted in the "Showing / Hiding the Footer" section above.
+
+### Example
+
+The following example fully demonstrates one way to use an [InfoBar](../../shared/windows-controls/info-bar.md) on a footer:
+
+```xaml
+xmlns:bars="http://schemas.actiprosoftware.com/winfx/xaml/bars"
+xmlns:shared="http://schemas.actiprosoftware.com/winfx/xaml/shared"
+...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
\ No newline at end of file
diff --git a/Documentation/topics/editors/editboxes/enumeditbox.md b/Documentation/topics/editors/editboxes/enumeditbox.md
index 3fc6cb08..fb12443e 100644
--- a/Documentation/topics/editors/editboxes/enumeditbox.md
+++ b/Documentation/topics/editors/editboxes/enumeditbox.md
@@ -93,7 +93,7 @@ Sometimes it is helpful to display an alternate text version of an enumeration v
This scenario is fully supported by [EnumEditBox](xref:@ActiproUIRoot.Controls.Editors.EnumEditBox). A `System.ComponentModel.DataAnnotations.DisplayAttribute` can be applied to a value to give it an alternate textual description. Then as long as the [UseDisplayAttributes](xref:@ActiproUIRoot.Controls.Editors.EnumEditBox.UseDisplayAttributes) property is set to `true`, that alternate text will be used.
-If the `DisplayAttribute.ResourceType` property is left blank, it will use the direct value specified by the `Name` property. Otherwise, it will look in the specified resource `Type` for a localized resource value within the property indicated by `Name`.
+If the `DisplayAttribute.ResourceType` property is left blank, it will use the direct value specified by the `Name` property. Otherwise, it will look in the specified resource `Type` for a localized resource value within the property indicated by `Name`. If the `Name` property is undefined, the `ShortName` property will be used instead.
In this example, the `DisplayAttribute` will look for a property named `MyFirstValue` in the string resources type `MyResources` and use that property's value:
@@ -120,6 +120,8 @@ By default, values are listed in the order they are defined. The exception is t
Sorting can be altered by implementing a custom `IComparer` class and assigning it to the [EnumSortComparer](xref:@ActiproUIRoot.Controls.Editors.EnumEditBox.EnumSortComparer) property. The [EnumValueNameSortComparer](xref:@ActiproUIRoot.Controls.Editors.Primitives.EnumValueNameSortComparer).[Instance](xref:@ActiproUIRoot.Controls.Editors.Primitives.EnumValueNameSortComparer.Instance) static property provides access to a pre-built comparer for listing enumeration values alphabetically by name.
+Alternatively, the `DisplayAttribute.Order` property can be used to define the sort order if the [UseDisplayAttributes](xref:@ActiproUIRoot.Controls.Editors.EnumEditBox.UseDisplayAttributes) property is set to `true` and a custom [EnumSortComparer](xref:@ActiproUIRoot.Controls.Editors.EnumEditBox.EnumSortComparer) is undefined. Values that define a `DisplayAttribute.Order` will always be sorted before values that do not define the attribute.
+
## Hiding Enumeration Values
By default, all values are listed in the control's popup and when cycling through values using arrow keys. If you wish to hide a specific value from the end user, use `EditorBrowsableAttribute` on the value with `EditorBrowsableState.Never`.
diff --git a/Documentation/topics/editors/pickers/enumpicker.md b/Documentation/topics/editors/pickers/enumpicker.md
index 7e14b8d8..eedec520 100644
--- a/Documentation/topics/editors/pickers/enumpicker.md
+++ b/Documentation/topics/editors/pickers/enumpicker.md
@@ -23,7 +23,7 @@ Sometimes it is helpful to display an alternate text version of an enumeration v
This scenario is fully supported by [EnumPicker](xref:@ActiproUIRoot.Controls.Editors.EnumPicker). A `System.ComponentModel.DataAnnotations.DisplayAttribute` can be applied to a value to give it an alternate textual description. Then as long as the [UseDisplayAttributes](xref:@ActiproUIRoot.Controls.Editors.EnumPicker.UseDisplayAttributes) property is set to `true`, that alternate text will be used.
-If the `DisplayAttribute.ResourceType` property is left blank, it will use the direct value specified by the `Name` property. Otherwise, it will look in the specified resource `Type` for a localized resource value within the property indicated by `Name`.
+If the `DisplayAttribute.ResourceType` property is left blank, it will use the direct value specified by the `Name` property. Otherwise, it will look in the specified resource `Type` for a localized resource value within the property indicated by `Name`. If the `Name` property is undefined, the `ShortName` property will be used instead.
In this example, the `DisplayAttribute` will look for a property named `MyFirstValue` in the string resources type `MyResources` and use that property's value:
@@ -50,6 +50,8 @@ By default, values are listed in the order they are defined. The exception is t
Sorting can be altered by implementing a custom `IComparer` class and assigning it to the [EnumSortComparer](xref:@ActiproUIRoot.Controls.Editors.EnumPicker.EnumSortComparer) property. The [EnumValueNameSortComparer](xref:@ActiproUIRoot.Controls.Editors.Primitives.EnumValueNameSortComparer).[Instance](xref:@ActiproUIRoot.Controls.Editors.Primitives.EnumValueNameSortComparer.Instance) static property provides access to a pre-built comparer for listing enumeration values alphabetically by name.
+Alternatively, the `DisplayAttribute.Order` property can be used to define the sort order if the [UseDisplayAttributes](xref:@ActiproUIRoot.Controls.Editors.EnumPicker.UseDisplayAttributes) property is set to `true` and a custom [EnumSortComparer](xref:@ActiproUIRoot.Controls.Editors.EnumPicker.EnumSortComparer) is undefined. Values that define a `DisplayAttribute.Order` will always be sorted before values that do not define the attribute.
+
## Hiding Enumeration Values
By default, all values are listed in the control. If you wish to hide a specific value from the end user, use `EditorBrowsableAttribute` on the value with `EditorBrowsableState.Never`.
diff --git a/Documentation/topics/licensing.md b/Documentation/topics/licensing.md
index ae787295..7086cecd 100644
--- a/Documentation/topics/licensing.md
+++ b/Documentation/topics/licensing.md
@@ -152,7 +152,7 @@ The contents of a *licenses.licx* file are pretty simple. It needs a single lin
This single line (update the version to match the one you use) should be added to the *licenses.licx* file in any project that uses Actipro @@PlatformName control or SyntaxEditor add-on products:
```
-ActiproSoftware.Products.ActiproLicenseToken, ActiproSoftware.Shared.Wpf, Version=24.1.1.0, Culture=neutral, PublicKeyToken=36ff2196ab5654b9
+ActiproSoftware.Products.ActiproLicenseToken, ActiproSoftware.Shared.Wpf, Version=24.1.2.0, Culture=neutral, PublicKeyToken=36ff2196ab5654b9
```
> [!IMPORTANT]
diff --git a/Documentation/topics/recent-updates.md b/Documentation/topics/recent-updates.md
index 14fe9d31..f477a44f 100644
--- a/Documentation/topics/recent-updates.md
+++ b/Documentation/topics/recent-updates.md
@@ -9,9 +9,20 @@ WPF Studio's documentation has frequent updates, so this topic is the best place
If you are looking for a list of recently added major new features to WPF Studio products, please see the Sample Browser's Recent Updates page instead.
+## Updates for v24.1.2
+
+- **Bars:** Updated [Footer](bars/ribbon-features/footer.md) documentation with details on using [InfoBar](shared/windows-controls/info-bar.md) in the ribbon footer.
+
+- **Views:** Added documentation for the new [SettingsCard](views/controls/settings-card.md), [SettingsExpander](xref:@ActiproUIRoot.Controls.Views.SettingsExpander), and [SettingsGroup](xref:@ActiproUIRoot.Controls.Views.SettingsGroup) controls.
+
+- **Shared:** Added documentation for the new [Card](shared/windows-controls/card.md) and [InfoBar](shared/windows-controls/info-bar.md) controls.
+
+- **Shared:** Added documentation for [Template Selectors](shared/windows-controls/template-selectors.md) which includes the new [ImageTemplateSelector](xref:@ActiproUIRoot.Controls.ImageTemplateSelector).
+
## Updates for v24.1.0
- **Shared:** Restructured [User Prompt](shared/windows-controls/user-prompt/index.md) documentation across multiple topics.
+- **Shared:** Added documentation for the new [Avatar](shared/windows-controls/avatar.md), [AvatarGroup](shared/windows-controls/avatar-group.md), [Badge](shared/windows-controls/badge.md), and [CircularProgressBar](shared/windows-controls/circular-progressbar.md) controls.
- **All:** Updated [Sample Code and QuickStarts](quick-starts.md) topic.
diff --git a/Documentation/topics/shared/images/card-padding.png b/Documentation/topics/shared/images/card-padding.png
new file mode 100644
index 00000000..f0131f9e
Binary files /dev/null and b/Documentation/topics/shared/images/card-padding.png differ
diff --git a/Documentation/topics/shared/images/card.png b/Documentation/topics/shared/images/card.png
new file mode 100644
index 00000000..4f1042f1
Binary files /dev/null and b/Documentation/topics/shared/images/card.png differ
diff --git a/Documentation/topics/shared/images/info-bar-action.png b/Documentation/topics/shared/images/info-bar-action.png
new file mode 100644
index 00000000..80bb2213
Binary files /dev/null and b/Documentation/topics/shared/images/info-bar-action.png differ
diff --git a/Documentation/topics/shared/images/info-bar-content.png b/Documentation/topics/shared/images/info-bar-content.png
new file mode 100644
index 00000000..83877fe0
Binary files /dev/null and b/Documentation/topics/shared/images/info-bar-content.png differ
diff --git a/Documentation/topics/shared/images/info-bar-severity.png b/Documentation/topics/shared/images/info-bar-severity.png
new file mode 100644
index 00000000..560477cc
Binary files /dev/null and b/Documentation/topics/shared/images/info-bar-severity.png differ
diff --git a/Documentation/topics/shared/images/info-bar-wrapping.png b/Documentation/topics/shared/images/info-bar-wrapping.png
new file mode 100644
index 00000000..0e77f2fe
Binary files /dev/null and b/Documentation/topics/shared/images/info-bar-wrapping.png differ
diff --git a/Documentation/topics/shared/images/info-bar.png b/Documentation/topics/shared/images/info-bar.png
new file mode 100644
index 00000000..f1473c2a
Binary files /dev/null and b/Documentation/topics/shared/images/info-bar.png differ
diff --git a/Documentation/topics/shared/index.md b/Documentation/topics/shared/index.md
index 516efe15..48f16c79 100644
--- a/Documentation/topics/shared/index.md
+++ b/Documentation/topics/shared/index.md
@@ -19,11 +19,13 @@ The Shared Library is not a product that is sold on its own, but any developer w
- An [Avatar](windows-controls/avatar.md) control to represent people or objects.
- An [AvatarGroup](windows-controls/avatar-group.md) control that renders multiple [Avatar](windows-controls/avatar.md) controls.
- A [Badge](windows-controls/badge.md) control, which can be used to provide contextual information for other elements or can be used stand-alone.
+- A [Card](windows-controls/card.md) control to displays visually grouped information for a single subject.
- A [CircularProgressBar](windows-controls/circular-progressbar.md) displays a ranged progress value using fluent animations. It is similar to a native linear `ProgressBar`, except that it renders the progress in a ring shape.
- A [CircularThumb](xref:@ActiproUIRoot.Controls.Primitives.CircularThumb) control, which is a thumb gripper with a circular shape and arrow adornment.
- A [CustomDrawElement](windows-controls/customdrawelement.md) element, which is an element that raises an event when it is being rendered, allowing for custom drawing.
- A [DropShadowChrome](windows-controls/dropshadowchrome.md) decorator, which can be used to render a drop shadow for a popup.
- A [HorizontalListBox](windows-controls/horizontallistbox.md) control, which allows for selection of items that are arranged horizontally with a uniform width.
+- An [InfoBar](windows-controls/info-bar.md) control, which can be used to display essential information to a user without disrupting the user flow.
- A [PixelSnapper](windows-controls/pixelsnapper.md) decorator, which helps prevent image and border blurring in WPF.
- A [PopupButton](windows-controls/popupbutton.md) control, which provides an implementation of a popup and split button that can display context menu popups or a popup containing any other WPF content.
- A [RadialSlider](windows-controls/radialslider.md) controls, which is a circular slider that can be used to input any scalar value.
diff --git a/Documentation/topics/shared/windows-controls/advancedtextblock.md b/Documentation/topics/shared/windows-controls/advancedtextblock.md
index 6faa2611..ed313e2a 100644
--- a/Documentation/topics/shared/windows-controls/advancedtextblock.md
+++ b/Documentation/topics/shared/windows-controls/advancedtextblock.md
@@ -1,7 +1,7 @@
---
title: "AdvancedTextBlock"
page-title: "AdvancedTextBlock - Shared Library Controls"
-order: 3
+order: 5
---
# AdvancedTextBlock
diff --git a/Documentation/topics/shared/windows-controls/animatedexpander.md b/Documentation/topics/shared/windows-controls/animatedexpander.md
index 4447c433..fab75caa 100644
--- a/Documentation/topics/shared/windows-controls/animatedexpander.md
+++ b/Documentation/topics/shared/windows-controls/animatedexpander.md
@@ -1,7 +1,7 @@
---
title: "AnimatedExpander"
page-title: "AnimatedExpander - Shared Library Controls"
-order: 4
+order: 10
---
# AnimatedExpander
diff --git a/Documentation/topics/shared/windows-controls/animatedprogressbar.md b/Documentation/topics/shared/windows-controls/animatedprogressbar.md
index f48f44b8..cbf10b3f 100644
--- a/Documentation/topics/shared/windows-controls/animatedprogressbar.md
+++ b/Documentation/topics/shared/windows-controls/animatedprogressbar.md
@@ -1,7 +1,7 @@
---
title: "AnimatedProgressBar"
page-title: "AnimatedProgressBar - Shared Library Controls"
-order: 7
+order: 15
---
# AnimatedProgressBar
diff --git a/Documentation/topics/shared/windows-controls/avatar-group.md b/Documentation/topics/shared/windows-controls/avatar-group.md
index 61c3b686..bd6b2df7 100644
--- a/Documentation/topics/shared/windows-controls/avatar-group.md
+++ b/Documentation/topics/shared/windows-controls/avatar-group.md
@@ -1,7 +1,7 @@
---
title: "AvatarGroup"
page-title: "Avatar Group - Shared Library Controls"
-order: 9
+order: 21
---
# AvatarGroup
diff --git a/Documentation/topics/shared/windows-controls/avatar.md b/Documentation/topics/shared/windows-controls/avatar.md
index 1738d29f..3598324a 100644
--- a/Documentation/topics/shared/windows-controls/avatar.md
+++ b/Documentation/topics/shared/windows-controls/avatar.md
@@ -1,7 +1,7 @@
---
title: "Avatar"
page-title: "Avatar - Shared Library Controls"
-order: 8
+order: 20
---
# Avatar
diff --git a/Documentation/topics/shared/windows-controls/badge.md b/Documentation/topics/shared/windows-controls/badge.md
index 835ee4c2..1b31fb4c 100644
--- a/Documentation/topics/shared/windows-controls/badge.md
+++ b/Documentation/topics/shared/windows-controls/badge.md
@@ -1,7 +1,7 @@
---
title: "Badge"
page-title: "Badge - Shared Library Controls"
-order: 10
+order: 25
---
# Badge
diff --git a/Documentation/topics/shared/windows-controls/card.md b/Documentation/topics/shared/windows-controls/card.md
new file mode 100644
index 00000000..5eeff37d
--- /dev/null
+++ b/Documentation/topics/shared/windows-controls/card.md
@@ -0,0 +1,387 @@
+---
+title: "Card"
+page-title: "Card - Fundamentals Controls"
+order: 30
+---
+# Card
+
+The [Card](xref:@ActiproUIRoot.Controls.Card) control is typically used to present visually grouped information for a single subject.
+
+![Screenshot](../images/card.png)
+
+*Card control with optional cover, footer, thumbnail, and default header*
+
+## Content Areas
+
+The [Card](xref:@ActiproUIRoot.Controls.Card) control is defined by multiple content areas:
+- `Content` (Body) - The default content area of the card.
+- [Cover](xref:@ActiproUIRoot.Controls.Card.Cover) - Typically used for a high-quality image which can be docked to any side of the card.
+- [Header](xref:@ActiproUIRoot.Controls.Card.Header) - Displayed above the content, and typically contains a title and/or description.
+- [Thumbnail](xref:@ActiproUIRoot.Controls.Card.Thumbnail) - Typically a small image or icon displayed on the left side of the header.
+- [Footer](xref:@ActiproUIRoot.Controls.Card.Footer) - Displayed at the bottom of the card.
+
+Each content area can optionally be set to any value supported by `ContentPresenter` and the layout will adjust to only show the areas where content is defined.
+
+> [!TIP]
+> In some scenarios, content may not be automatically detected. For instance, if a `DataTemplate` is used to define content without setting the corresponding content property, the card will not know that content is available. Use the [IsCoverVisible](xref:@ActiproUIRoot.Controls.Card.IsCoverVisible), [IsHeaderVisible](xref:@ActiproUIRoot.Controls.Card.IsHeaderVisible), [IsThumbnailVisible](xref:@ActiproUIRoot.Controls.Card.IsThumbnailVisible), and [IsFooterVisible](xref:@ActiproUIRoot.Controls.Card.IsFooterVisible) properties to manually control the visibility of each content area.
+
+### Content (Body)
+
+[Card](xref:@ActiproUIRoot.Controls.Card) is a `ContentControl`, and the default content of the control will be displayed in the body area of the card. The content can be set to any value supported by `ContentPresenter`.
+
+The following example demonstrates defining the content of a [Card](xref:@ActiproUIRoot.Controls.Card):
+
+@if (avalonia) {
+```xaml
+xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui"
+...
+
+
+
+```
+}
+@if (wpf) {
+```xaml
+xmlns:shared="http://schemas.actiprosoftware.com/winfx/xaml/shared"
+...
+
+
+
+```
+}
+
+### Cover
+
+The [Cover](xref:@ActiproUIRoot.Controls.Card.Cover) can be docked to any side of the card using the [CoverDock](xref:@ActiproUIRoot.Controls.Card.CoverDock) property. While a high-quality image is typically used for the [Cover](xref:@ActiproUIRoot.Controls.Card.Cover), it can be set to any value supported by `ContentPresenter`.
+
+@if (wpf) {
+> [!TIP]
+> The [CoverTemplateSelector](xref:@ActiproUIRoot.Controls.Card.CoverTemplateSelector) is pre-configured with a default [ImageTemplateSelector](xref:@ActiproUIRoot.Controls.ImageTemplateSelector), so it supports `ImageSource` and `Geometry` data values. See the [Template Selectors](template-selectors.md) topic for more details.
+}
+
+The following example demonstrates creating a [Card](xref:@ActiproUIRoot.Controls.Card) with a cover image docked to the left:
+
+@if (avalonia) {
+```xaml
+xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui"
+...
+
+
+
+
+
+
+
+
+
+```
+}
+@if (wpf) {
+```xaml
+xmlns:shared="http://schemas.actiprosoftware.com/winfx/xaml/shared"
+...
+
+
+
+
+
+
+
+
+
+```
+}
+
+### Header
+
+The [Title](xref:@ActiproUIRoot.Controls.Card.Title) and [Description](xref:@ActiproUIRoot.Controls.Card.Description) properties can be used to define a header with a default template where the [Title](xref:@ActiproUIRoot.Controls.Card.Title) is displayed with typography consistent with a heading, and the [Description](xref:@ActiproUIRoot.Controls.Card.Description), if defined, is displayed immediately below it.
+
+@if (avalonia) {
+Use the [TitleTheme](xref:@ActiproUIRoot.Controls.Card.TitleTheme) and [DescriptionTheme](xref:@ActiproUIRoot.Controls.Card.DescriptionTheme) properties to customize the appearance of each element.
+}
+@if (wpf) {
+Use the [TitleStyle](xref:@ActiproUIRoot.Controls.Card.TitleStyle) and [DescriptionStyle](xref:@ActiproUIRoot.Controls.Card.DescriptionStyle) properties to customize the appearance of each element.
+}
+
+The following example demonstrates creating a [Card](xref:@ActiproUIRoot.Controls.Card) with both [Title](xref:@ActiproUIRoot.Controls.Card.Title) and [Description](xref:@ActiproUIRoot.Controls.Card.Description) defined:
+
+@if (avalonia) {
+```xaml
+xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui"
+...
+
+
+
+```
+}
+@if (wpf) {
+```xaml
+xmlns:shared="http://schemas.actiprosoftware.com/winfx/xaml/shared"
+...
+
+
+
+```
+}
+
+Alternatively, the [Header](xref:@ActiproUIRoot.Controls.Card.Header) can be set to any value supported by `ContentPresenter`. In this case, the explicit content will be used instead of the default template based on the [Title](xref:@ActiproUIRoot.Controls.Card.Title) and [Description](xref:@ActiproUIRoot.Controls.Card.Description) properties.
+
+The following example demonstrates creating a [Card](xref:@ActiproUIRoot.Controls.Card) with an explicit [Header](xref:@ActiproUIRoot.Controls.Card.Header) defined:
+
+@if (avalonia) {
+```xaml
+xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui"
+...
+
+
+
+ Title Here
+
+
+
+
+
+```
+}
+@if (wpf) {
+```xaml
+xmlns:shared="http://schemas.actiprosoftware.com/winfx/xaml/shared"
+...
+
+
+
+ Title Here
+
+
+
+
+
+```
+}
+
+### Thumbnail
+
+The [Thumbnail](xref:@ActiproUIRoot.Controls.Card.Thumbnail) is displayed in the header area, but is separate from the [Header](xref:@ActiproUIRoot.Controls.Card.Header) content. [Thumbnail](xref:@ActiproUIRoot.Controls.Card.Thumbnail) can be set to any value supported by `ContentPresenter` but is typically used to display a small image.
+
+@if (wpf) {
+> [!TIP]
+> The [ThumbnailTemplateSelector](xref:@ActiproUIRoot.Controls.Card.ThumbnailTemplateSelector) is pre-configured with a default [ImageTemplateSelector](xref:@ActiproUIRoot.Controls.ImageTemplateSelector), so it supports `ImageSource` and `Geometry` data values. See the [Template Selectors](template-selectors.md) topic for more details.
+}
+
+By default, the [Thumbnail](xref:@ActiproUIRoot.Controls.Card.Thumbnail) is vertically centered with a right margin to separate it from the [Header](xref:@ActiproUIRoot.Controls.Card.Header). Use the @if (avalonia) {[ThumbnailTheme](xref:@ActiproUIRoot.Controls.Card.ThumbnailTheme)}@if (wpf) {[ThumbnailStyle](xref:@ActiproUIRoot.Controls.Card.ThumbnailStyle)} property to customize the appearance.
+
+The following example demonstrates creating a [Card](xref:@ActiproUIRoot.Controls.Card) with top-aligned image and a custom margin:
+
+@if (avalonia) {
+```xaml
+xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui"
+...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+}
+@if (wpf) {
+```xaml
+xmlns:shared="http://schemas.actiprosoftware.com/winfx/xaml/shared"
+...
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+}
+
+### Footer
+
+The [Footer](xref:@ActiproUIRoot.Controls.Card.Footer) can be set to any value supported by `ContentPresenter`.
+
+The following example demonstrates creating a [Card](xref:@ActiproUIRoot.Controls.Card) with italicized text in the footer:
+
+@if (avalonia) {
+```xaml
+xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui"
+...
+
+
+
+
+
+
+
+
+
+```
+}
+@if (wpf) {
+```xaml
+xmlns:shared="http://schemas.actiprosoftware.com/winfx/xaml/shared"
+...
+
+
+
+
+
+
+
+
+
+```
+}
+
+## Appearance
+
+The appearance of the control can be fully customized.
+
+### Brushes
+
+The following brush properties are available:
+
+| Property | Description |
+| ----- | ----- |
+| `Foreground` | The default foreground for all areas. |
+| `Background` | The default background for all areas. |
+| `BorderBrush` | The brush for the outer border. |
+| [HeaderForeground](xref:@ActiproUIRoot.Controls.Card.HeaderForeground) | The foreground for the header area, overriding the default foreground. |
+| [HeaderBackground](xref:@ActiproUIRoot.Controls.Card.HeaderBackground) | The background for the header area, overriding the default background. |
+| [HeaderBorderBrush](xref:@ActiproUIRoot.Controls.Card.HeaderBorderBrush) | The brush for the bottom border of the header.
+| [FooterForeground](xref:@ActiproUIRoot.Controls.Card.FooterForeground) | The foreground for the footer area, overriding the default foreground. |
+| [FooterBackground](xref:@ActiproUIRoot.Controls.Card.FooterBackground) | The background for the footer area, overriding the default background. |
+| [FooterBorderBrush](xref:@ActiproUIRoot.Controls.Card.FooterBorderBrush) | The brush for the top border of the footer. |
+
+### Header and Footer Borders
+
+Use the [HeaderBorderThickness](xref:@ActiproUIRoot.Controls.Card.HeaderBorderThickness) and [FooterBorderThickness](xref:@ActiproUIRoot.Controls.Card.FooterBorderThickness) properties to insert a border below the header or above the footer. In the event header and footer both define a border when no content is defined between them, only the header border will be displayed.
+
+> [!IMPORTANT]
+> When setting the border thickness, only `Thickness.Bottom` is used by the header and `Thickness.Top` is used by the footer.
+
+### Padding
+
+![Screenshot](../images/card-padding.png)
+
+*Card controls with the same padding shown with and without separation between then content and the header/footer*
+
+By default, the `Padding` is consistently applied around the header, content, and footer areas instead of having separate values for each area. When there is visual separation between the content and the header/footer (either by a border or an explicit background color), the padding will be consistently applied to both sides of the separation.
+
+> [!NOTE]
+> The [Cover](xref:@ActiproUIRoot.Controls.Card.Cover) area does not have any default padding applied so the content can be displayed edge-to-edge.
+
+## Using Card as a Button
+
+[Card](xref:@ActiproUIRoot.Controls.Card) derives from `Button`, so it supports the same `Command` model and `Click` event as `Button`. Unlike a `Button`, though, not all instances of [Card](xref:@ActiproUIRoot.Controls.Card) will be interactive and the control has been configured to appear non-interactive by default.
+
+Set the [IsClickEnabled](xref:@ActiproUIRoot.Controls.Card.IsClickEnabled) property to `true` to enable clicking the card. The `Click` event will not be raised if this property is `false`.
+
+> [!TIP]
+> If the `Command` property is assigned a non-`null` value, the [IsClickEnabled](xref:@ActiproUIRoot.Controls.Card.IsClickEnabled) property is automatically coerced to `true`, so no additional configuration is necessary.
+
+> [!NOTE]
+> Setting the [IsClickEnabled](xref:@ActiproUIRoot.Controls.Card.IsClickEnabled) property to `true` will also trigger hover effects to emphasize the control is actionable.
+
+@if (wpf) {
+## Badge Adornment
+
+[Card](xref:@ActiproUIRoot.Controls.Card) includes built-in support for adding a [Badge](badge.md) adornment. Refer to the [Badge](badge.md) documentation for details on working with a badge.
+
+The following properties are available for configuring the badge, which correspond to attached properties on [BadgeService](xref:@ActiproUIRoot.Controls.BadgeService):
+
+| Property | Description |
+| ----- | ----- |
+| [Badge](xref:@ActiproUIRoot.Controls.Card.Badge) | Set to an instance of a [Badge](badge.md). |
+| [BadgeHorizontalAlignment](xref:@ActiproUIRoot.Controls.Card.BadgeHorizontalAlignment) | Set to one of the [AdornmentHorizontalAlignment](xref:@ActiproUIRoot.Controls.AdornmentHorizontalAlignment) values to alter the horizontal alignment. (Default = [CenterOnTargetRightEdge](xref:@ActiproUIRoot.Controls.AdornmentHorizontalAlignment.CenterOnTargetRightEdge) ) |
+| [BadgeHorizontalOffset](xref:@ActiproUIRoot.Controls.Card.BadgeHorizontalOffset) | An explicit offset to be applied after alignment. Positive values shift to the right while negative values shift to the left. |
+| [BadgeVerticalAlignment](xref:@ActiproUIRoot.Controls.Card.BadgeVerticalAlignment) | Set to one of the [AdornmentVerticalAlignment](xref:@ActiproUIRoot.Controls.AdornmentVerticalAlignment) values to alter the vertical alignment. (Default = [CenterOnTargetTopEdge](xref:@ActiproUIRoot.Controls.AdornmentVerticalAlignment.CenterOnTargetTopEdge) ) |
+| [BadgeVerticalOffset](xref:@ActiproUIRoot.Controls.Card.BadgeVerticalOffset) | An explicit offset to be applied after alignment. Positive values shift down while negative values shift up. |
+
+}
+
+
+@if (avalonia) {
+## Themes
+
+![Screenshot](../images/card-themes.png)
+
+*Card control in the outline, solid, soft, and elevated themes*
+
+The following control themes are supported:
+- [CardBase](xref:@ActiproUIRoot.Themes.ControlThemeKind.CardBase) - Base control theme used by several others.
+- [CardElevated](xref:@ActiproUIRoot.Themes.ControlThemeKind.CardElevated) (`theme-elevated`) - Has an elevated appearance with a shadow.
+- [CardOutline](xref:@ActiproUIRoot.Themes.ControlThemeKind.CardOutline) (`theme-outline`) - Has an outline appearance.
+- [CardSoft](xref:@ActiproUIRoot.Themes.ControlThemeKind.CardSoft) (`theme-soft`) - Has a soft fill appearance.
+- [CardSolid](xref:@ActiproUIRoot.Themes.ControlThemeKind.CardSolid) (`theme-solid`) - Has a solid appearance.
+
+
+The following example demonstrates how to define a card using the elevated theme:
+
+```xaml
+xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui"
+...
+
+```
+
+### Elevated Button Animation
+
+When used as a `Button` and the elevated theme is applied (`theme-elevated` style class name), an animation is applied when the pointer is over the [Card](xref:@ActiproUIRoot.Controls.Card) that slides the control up while raising the elevation of the shadow.
+
+Animations are automatically enabled. To turn off animations, set the [IsAnimationEnabled](xref:@ActiproUIRoot.Controls.Card.IsAnimationEnabled) property to `false`.
+}
+@if (wpf) {
+## Elevated Appearance
+
+By default, the [IsShadowEnabled](xref:@ActiproUIRoot.Controls.Card.IsShadowEnabled) property is set to `true` and gives the [Card](xref:@ActiproUIRoot.Controls.Card) an elevated appearance.
+
+When also used as a `Button`, an animation is applied when the mouse is over the [Card](xref:@ActiproUIRoot.Controls.Card) that slides the control up while raising the elevation of the shadow.
+
+Animations are automatically disabled, as appropriate, based on system settings. To manually turn off animations, set the [IsAnimationEnabled](xref:@ActiproUIRoot.Controls.Card.IsAnimationEnabled) property to `false`.
+}
+
+@if (avalonia) {
+
+## Theme Resources
+
+The following theme resources are available for customizing the appearance of the control:
+
+| Theme Resource | Description |
+| ----- | ----- |
+| [CardBorderThickness](xref:@ActiproUIRoot.Themes.ThemeResourceKind.CardBorderThickness) | The default `BorderThickness`. |
+| [CardCornerRadius](xref:@ActiproUIRoot.Themes.ThemeResourceKind.CardCornerRadius) | The default `CornerRadius`. |
+| [CardPadding](xref:@ActiproUIRoot.Themes.ThemeResourceKind.CardPadding) | The default `Padding`. |
+
+}
+@if (wpf) {
+## Theme Assets
+
+See the [Theme Reusable Assets](../../themes/reusable-assets.md) topic for more details on using and customizing theme assets. The following reusable assets are used by [SettingsCard](xref:@ActiproUIRoot.Controls.Views.SettingsCard):
+
+| Asset Resource Key | Description |
+|-----|-----|
+| [CardBorderNormalThicknessKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.CardBorderNormalThicknessKey) | The default `BorderThickness`. |
+| [CardBorderNormalCornerRadiusKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.CardBorderNormalCornerRadiusKey) | The default [CornerRadius](xref:@ActiproUIRoot.Controls.Card.CornerRadius). |
+| [CardBorderNormalThicknessKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.CardPaddingNormalThicknessKey) | The default `Padding`. |
+}
\ No newline at end of file
diff --git a/Documentation/topics/shared/windows-controls/circular-progressbar.md b/Documentation/topics/shared/windows-controls/circular-progressbar.md
index 61b6f646..cdf75aba 100644
--- a/Documentation/topics/shared/windows-controls/circular-progressbar.md
+++ b/Documentation/topics/shared/windows-controls/circular-progressbar.md
@@ -1,7 +1,7 @@
---
title: "CircularProgressBar"
page-title: "CircularProgressBar- Shared Library Controls"
-order: 11
+order: 35
---
# CircularProgressBar
diff --git a/Documentation/topics/shared/windows-controls/customdrawelement.md b/Documentation/topics/shared/windows-controls/customdrawelement.md
index 8cbf299c..d7d72b7f 100644
--- a/Documentation/topics/shared/windows-controls/customdrawelement.md
+++ b/Documentation/topics/shared/windows-controls/customdrawelement.md
@@ -1,7 +1,7 @@
---
title: "CustomDrawElement"
page-title: "CustomDrawElement - Shared Library Controls"
-order: 12
+order: 40
---
# CustomDrawElement
diff --git a/Documentation/topics/shared/windows-controls/dropshadowchrome.md b/Documentation/topics/shared/windows-controls/dropshadowchrome.md
index 63b16909..a38f814a 100644
--- a/Documentation/topics/shared/windows-controls/dropshadowchrome.md
+++ b/Documentation/topics/shared/windows-controls/dropshadowchrome.md
@@ -1,7 +1,7 @@
---
title: "DropShadowChrome"
page-title: "DropShadowChrome - Shared Library Controls"
-order: 13
+order: 45
---
# DropShadowChrome
diff --git a/Documentation/topics/shared/windows-controls/dynamicimage.md b/Documentation/topics/shared/windows-controls/dynamicimage.md
index c18c85e7..720c2ded 100644
--- a/Documentation/topics/shared/windows-controls/dynamicimage.md
+++ b/Documentation/topics/shared/windows-controls/dynamicimage.md
@@ -1,7 +1,7 @@
---
title: "DynamicImage"
page-title: "DynamicImage - Shared Library Controls"
-order: 14
+order: 50
---
# DynamicImage
diff --git a/Documentation/topics/shared/windows-controls/editablecontentcontrol.md b/Documentation/topics/shared/windows-controls/editablecontentcontrol.md
index 97f823c3..173fea1c 100644
--- a/Documentation/topics/shared/windows-controls/editablecontentcontrol.md
+++ b/Documentation/topics/shared/windows-controls/editablecontentcontrol.md
@@ -1,7 +1,7 @@
---
title: "EditableContentControl"
page-title: "EditableContentControl - Shared Library Controls"
-order: 16
+order: 55
---
# EditableContentControl
diff --git a/Documentation/topics/shared/windows-controls/horizontallistbox.md b/Documentation/topics/shared/windows-controls/horizontallistbox.md
index 6f2dc755..733b76b5 100644
--- a/Documentation/topics/shared/windows-controls/horizontallistbox.md
+++ b/Documentation/topics/shared/windows-controls/horizontallistbox.md
@@ -1,7 +1,7 @@
---
title: "HorizontalListBox"
page-title: "HorizontalListBox - Shared Library Controls"
-order: 19
+order: 60
---
# HorizontalListBox
diff --git a/Documentation/topics/shared/windows-controls/imagetextinfo.md b/Documentation/topics/shared/windows-controls/imagetextinfo.md
index b82e49f8..ace8ffef 100644
--- a/Documentation/topics/shared/windows-controls/imagetextinfo.md
+++ b/Documentation/topics/shared/windows-controls/imagetextinfo.md
@@ -1,7 +1,7 @@
---
title: "ImageTextInfo"
page-title: "ImageTextInfo - Shared Library Controls"
-order: 21
+order: 65
---
# ImageTextInfo
diff --git a/Documentation/topics/shared/windows-controls/index.md b/Documentation/topics/shared/windows-controls/index.md
index dbf4394e..6caac15b 100644
--- a/Documentation/topics/shared/windows-controls/index.md
+++ b/Documentation/topics/shared/windows-controls/index.md
@@ -31,6 +31,10 @@ The [AvatarGroup](avatar-group.md) control renders multiple [Avatar](avatar.md)
The [Badge](badge.md) control is used to provide contextual information for other elements or can be used stand-alone.
+## The Card Control
+
+The [Card](card.md) control is typically used to present visually grouped information for a single subject.
+
## The CircularProgressBar Control
[CircularProgressBar](circular-progressbar.md) displays a ranged progress value using fluent animations. It is similar to a native linear `ProgressBar`, except that it renders the progress in a ring shape.
@@ -65,6 +69,10 @@ The [HorizontalListBox](horizontallistbox.md) control is a restyled native `List
The [ImageTextInfo](imagetextinfo.md) class is a simple helper class that can be used to store image and text data for databinding.
+## The InfoBar Control
+
+The [InfoBar](info-bar.md) control can be used to display essential information to a user without disrupting the user flow.
+
## The PixelSnapper Decorator
The [PixelSnapper](pixelsnapper.md) decorator snaps the measurement of its child content to integer values, thereby helping to prevent blurry images and borders that may appear after it.
diff --git a/Documentation/topics/shared/windows-controls/info-bar.md b/Documentation/topics/shared/windows-controls/info-bar.md
new file mode 100644
index 00000000..277d8d45
--- /dev/null
+++ b/Documentation/topics/shared/windows-controls/info-bar.md
@@ -0,0 +1,262 @@
+---
+title: "InfoBar"
+page-title: "InfoBar - Shared Library Controls"
+order: 67
+---
+# InfoBar
+
+An [InfoBar](xref:@ActiproUIRoot.Controls.InfoBar) can be used to display essential information to a user without disrupting the user flow.
+
+![Screenshot](../images/info-bar.png)
+
+*InfoBar with default severity showing a title and message*
+
+## Title and Message
+
+The [Title](xref:@ActiproUIRoot.Controls.InfoBar.Title) property is typically set to short text that categorizes the message being displayed while the [Message](xref:@ActiproUIRoot.Controls.InfoBar.Message) property is set to text that provides additional detail.
+
+The following demonstrates how to create an info bar with a title and message:
+
+@if (avalonia) {
+```xaml
+xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui"
+...
+
+```
+}
+@if (wpf) {
+```xaml
+xmlns:shared="http://schemas.actiprosoftware.com/winfx/xaml/shared"
+...
+
+```
+}
+
+## Severity
+
+![Screenshot](../images/info-bar-severity.png)
+
+*InfoBar with Information, Success, Warning, and Error severities*
+
+By default, an [InfoBar](xref:@ActiproUIRoot.Controls.InfoBar) is displayed with [Information](xref:@ActiproUIRoot.Controls.InfoBarSeverity.Information) severity, but the [Severity](xref:@ActiproUIRoot.Controls.InfoBar.Severity) property can be set to any one of the [InfoBarSeverity](xref:@ActiproUIRoot.Controls.InfoBarSeverity) values. Each severity automatically applies a default[Icon](xref:@ActiproUIRoot.Controls.InfoBar.Icon) and `Background` brush to visually distinguish one severity from another.
+
+## Action
+
+![Screenshot](../images/info-bar-action.png)
+
+*InfoBar with action button*
+
+The [Action](xref:@ActiproUIRoot.Controls.InfoBar.Action) can be set to any value supported by `ContentPresenter`, but is typically used to show a button or hyperlink the user can act upon to respond to the message.
+
+The following demonstrates how to create an info bar with a button for an action:
+
+@if (avalonia) {
+```xaml
+xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui"
+...
+
+
+
+
+
+```
+}
+@if (wpf) {
+```xaml
+xmlns:shared="http://schemas.actiprosoftware.com/winfx/xaml/shared"
+...
+
+
+
+
+
+```
+}
+
+## Icon
+
+By default, info bar will display an icon that corresponds to the value of the [Severity](xref:@ActiproUIRoot.Controls.InfoBar.Severity) property. To hide the icon, set the [IsIconVisible](xref:@ActiproUIRoot.Controls.InfoBar.IsIconVisible) property to `false`.
+
+@if (avalonia) {
+The following sample demonstrates using an `Image` for the icon, but any content supported by `ContentPresenter` can be used (like `PathIcon` or [DynamicImage](../../shared/controls/dynamic-image.md) controls):
+
+```xaml
+xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui"
+...
+
+
+
+
+
+```
+}
+@if (wpf) {
+To customize the icon, assign any value supported by `ContentPresenter` to the [Icon](xref:@ActiproUIRoot.Controls.InfoBar.Icon) property.
+
+> [!TIP]
+> The [IconTemplateSelector](xref:@ActiproUIRoot.Controls.InfoBar.IconTemplateSelector) is pre-configured with a default [ImageTemplateSelector](xref:@ActiproUIRoot.Controls.ImageTemplateSelector), so it supports `ImageSource` and `Geometry` data values. See the [Template Selectors](template-selectors.md) topic for more details.
+
+The following sample demonstrates using an `ImageSource` for the icon based on a relative `Uri` path:
+
+```xaml
+xmlns:shared="http://schemas.actiprosoftware.com/winfx/xaml/shared"
+...
+
+```
+}
+
+> [!NOTE]
+> [InfoBar](xref:@ActiproUIRoot.Controls.InfoBar) is designed for use with 16x16 icons. See the @if (avalonia) { "Theme Resources" }@if (wpf) { "Theme Assets" } section below for more information on customizing the icon size.
+
+## Custom Content
+
+![Screenshot](../images/info-bar-content.png)
+
+*InfoBar with a progressbar as content*
+
+While not typically necessary, any content supported by `ContentPresenter` can be defined as the `Content` of the info bar. When defined, the `Content` is always displayed below the other UI elements.
+
+The following sample demonstrates including a progressbar as content:
+
+@if (avalonia) {
+```xaml
+xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui"
+...
+
+
+
+```
+}
+@if (wpf) {
+```xaml
+xmlns:shared="http://schemas.actiprosoftware.com/winfx/xaml/shared"
+...
+
+
+
+```
+}
+
+## Opening and Closing
+
+The [IsOpen](xref:@ActiproUIRoot.Controls.InfoBar.IsOpen) property is used to open and close the info bar programmatically.
+
+By default, a **Close Button** is also displayed that the user can click to close the info bar. Set the [CanClose](xref:@ActiproUIRoot.Controls.InfoBar.CanClose) property to `false` to hide the **Close Button**.
+
+> [!WARNING]
+> Do not use the @if (avalonia) { `IsVisible` }@if (wpf) { `Visibility` } property to open and close the info bar.
+
+By default, clicking the **Close Button** will set the [IsOpen](xref:@ActiproUIRoot.Controls.InfoBar.IsOpen) property to `false` when it is clicked. Alternatively, a [CloseButtonClick](xref:@ActiproUIRoot.Controls.InfoBar.CloseButtonClick) event handler or custom [CloseButtonCommand](xref:@ActiproUIRoot.Controls.InfoBar.CloseButtonCommand) can replace the default behavior.
+
+> [!IMPORTANT]
+> If the [CloseButtonClick](xref:@ActiproUIRoot.Controls.InfoBar.CloseButtonClick) event handler sets `RoutedEventArgs.Handled` to `true` or the [CloseButtonCommand](xref:@ActiproUIRoot.Controls.InfoBar.CloseButtonCommand) property is assigned, the info bar *will not* close by default when it is clicked. The respective event handler or command is responsible for setting the [IsOpen](xref:@ActiproUIRoot.Controls.InfoBar.IsOpen) property to `false` to close the info bar.
+
+### Cancel Close
+
+When the [IsOpen](xref:@ActiproUIRoot.Controls.InfoBar.IsOpen) property is set to `false`, the [Closing](xref:@ActiproUIRoot.Controls.InfoBar.Closing) event is raised with [InfoBarClosingEventArgs](xref:@ActiproUIRoot.Controls.InfoBarClosingEventArgs) passed to the event handler. Set the `Cancel` property to `true` to cancel the close request.
+
+If necessary, inspect the [Reason](xref:@ActiproUIRoot.Controls.InfoBarClosingEventArgs.Reason) property to determine if the reason for the close was due to the [CloseButton](xref:@ActiproUIRoot.Controls.InfoBarCloseReason) being clicked or if it was a [Programmatic](xref:@ActiproUIRoot.Controls.InfoBarCloseReason.Programmatic) close.
+
+## Wrapping
+
+![Screenshot](../images/info-bar-wrapping.png)
+
+*InfoBar displayed in the unwrapped and wrapped states*
+
+If enough space is available, all UI elements (except `Content`) are displayed on a single line. Otherwise, the [Title](xref:@ActiproUIRoot.Controls.InfoBar.Title), [Message](xref:@ActiproUIRoot.Controls.InfoBar.Message), [Action](xref:@ActiproUIRoot.Controls.InfoBar.Action), and `Content` are stacked vertically in the middle. When wrapped, the read-only [IsWrapped](xref:@ActiproUIRoot.Controls.InfoBar.IsWrappedProperty) property will be set to `true`.
+
+## Animation
+
+Fluent animation in the control is enabled by default but can be disabled by setting the [IsAnimationEnabled](xref:@ActiproUIRoot.Controls.InfoBar.IsAnimationEnabled) property to `false`.
+
+@if (avalonia) {
+
+## Pseudo-classes
+
+The following pseudo-classes are available and can be used when styling the control:
+
+| Class | Description |
+| ----- | ----- |
+| `:error` | Added when the [Severity](xref:@ActiproUIRoot.Controls.InfoBar.Severity) is set to [Error](xref:@ActiproUIRoot.Controls.InfoBarSeverity.Error). |
+| `:information` | Added when the [Severity](xref:@ActiproUIRoot.Controls.InfoBar.Severity) is set to [Information](xref:@ActiproUIRoot.Controls.InfoBarSeverity.Information). |
+| `:success` | Added when the [Severity](xref:@ActiproUIRoot.Controls.InfoBar.Severity) is set to [Success](xref:@ActiproUIRoot.Controls.InfoBarSeverity.Success). |
+| `:warning` | Added when the [Severity](xref:@ActiproUIRoot.Controls.InfoBar.Severity) is set to [Warning](xref:@ActiproUIRoot.Controls.InfoBarSeverity.Warning). |
+| `:wrapped` | Added when there is not enough room to display the primary controls (excluding `Content`) on a single row. |
+
+}
+
+@if (avalonia) {
+## Theme Resources
+
+The following theme resources are available for customizing the appearance of the control:
+
+| Theme Resource | Description |
+| ----- | ----- |
+| [ButtonForegroundBrush](xref:@ActiproUIRoot.Themes.ThemeResourceKind.ButtonForegroundBrush) | The default `Foreground` of the **Close Button**. |
+| [ButtonForegroundBrushDisabled](xref:@ActiproUIRoot.Themes.ThemeResourceKind.ButtonForegroundBrushDisabled) | The default `Foreground` of the **Close Button** when it is disabled. |
+| [Container1BorderBrush](xref:@ActiproUIRoot.Themes.ThemeResourceKind.Container1BorderBrush) | The default `BorderBrush`. |
+| [InfoBarBackgroundBrushError](xref:@ActiproUIRoot.Themes.ThemeResourceKind.InfoBarBackgroundBrushError) | The default `Background` when the [Severity](xref:@ActiproUIRoot.Controls.InfoBar.Severity) is [Error](xref:@ActiproUIRoot.Controls.InfoBarSeverity.Error). |
+| [InfoBarBackgroundBrushInformation](xref:@ActiproUIRoot.Themes.ThemeResourceKind.InfoBarBackgroundBrushInformation) | The default `Background` when the [Severity](xref:@ActiproUIRoot.Controls.InfoBar.Severity) is [Information](xref:@ActiproUIRoot.Controls.InfoBarSeverity.Information). |
+| [InfoBarBackgroundBrushSuccess](xref:@ActiproUIRoot.Themes.ThemeResourceKind.InfoBarBackgroundBrushSuccess) | The default `Background` when the [Severity](xref:@ActiproUIRoot.Controls.InfoBar.Severity) is [Success](xref:@ActiproUIRoot.Controls.InfoBarSeverity.Success). |
+| [InfoBarBackgroundBrushWarning](xref:@ActiproUIRoot.Themes.ThemeResourceKind.InfoBarBackgroundBrushWarning) | The default `Background` when the [Severity](xref:@ActiproUIRoot.Controls.InfoBar.Severity) is [Warning](xref:@ActiproUIRoot.Controls.InfoBarSeverity.Warning). |
+| [InfoBarBorderThickness](xref:@ActiproUIRoot.Themes.ThemeResourceKind.InfoBarBorderThickness) | The default `BorderThickness`. |
+| [InfoBarCloseButtonLength](xref:@ActiproUIRoot.Themes.ThemeResourceKind.InfoBarCloseButtonLength) | The default `Width` and `Height` of the **Close Button**. |
+| [InfoBarCornerRadius](xref:@ActiproUIRoot.Themes.ThemeResourceKind.InfoBarCornerRadius) | The default `CornerRadius`. |
+| [InfoBarIconLength](xref:@ActiproUIRoot.Themes.ThemeResourceKind.InfoBarIconLength) | The default `Width` and `Height` of the [Icon](xref:@ActiproUIRoot.Controls.InfoBar.Icon). |
+| [InfoBarPadding](xref:@ActiproUIRoot.Themes.ThemeResourceKind.InfoBarPadding) | The default `Padding`. |
+
+See the [Theme Assets](../../themes/theme-assets.md) topic for more details on working with theme resources.
+}
+@if (wpf) {
+## Theme Assets
+
+See the [Theme Reusable Assets](../../themes/reusable-assets.md) topic for more details on using and customizing theme assets. The following reusable assets are used by [InfoBar](xref:@ActiproUIRoot.Controls.InfoBar):
+
+| Asset Resource Key | Description |
+|-----|-----|
+| [ButtonBorderNormalCornerRadiusKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.ButtonBorderNormalCornerRadiusKey) | The default `CornerRadius` of the **Close Button**. |
+| [ContainerBorderLowerBrushKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.ContainerBorderLowerBrushKey) | The default `BorderBrush`. |
+| [ContainerForegroundLowestNormalBrushKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.ContainerForegroundLowestNormalBrushKey) | The default `Foreground` of the info bar and **Close Button**. |
+| [ContainerForegroundLowestDisabledBrushKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.ContainerForegroundLowestDisabledBrushKey) | The default `Foreground` of the **Close Button** when it is disabled. |
+| [InfoBarBackgroundErrorBrushKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.InfoBarBackgroundErrorBrushKey) | The default `Background` when the [Severity](xref:@ActiproUIRoot.Controls.InfoBar.Severity) is [Error](xref:@ActiproUIRoot.Controls.InfoBarSeverity.Error). |
+| [InfoBarBackgroundInformationBrushKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.InfoBarBackgroundInformationBrushKey) | The default `Background` when the [Severity](xref:@ActiproUIRoot.Controls.InfoBar.Severity) is [Information](xref:@ActiproUIRoot.Controls.InfoBarSeverity.Information). |
+| [InfoBarBackgroundSuccessBrushKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.InfoBarBackgroundSuccessBrushKey) | The default `Background` when the [Severity](xref:@ActiproUIRoot.Controls.InfoBar.Severity) is [Success](xref:@ActiproUIRoot.Controls.InfoBarSeverity.Success). |
+| [InfoBarBackgroundWarningBrushKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.InfoBarBackgroundWarningBrushKey) | The default `Background` when the [Severity](xref:@ActiproUIRoot.Controls.InfoBar.Severity) is [Warning](xref:@ActiproUIRoot.Controls.InfoBarSeverity.Warning). |
+| [InfoBarBorderNormalCornerRadiusKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.InfoBarBorderNormalCornerRadiusKey) | The default [CornerRadius](xref:@ActiproUIRoot.Controls.InfoBar.CornerRadius). |
+| [InfoBarBorderNormalThicknessKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.InfoBarBorderNormalThicknessKey) | The default `BorderThickness`. |
+| [InfoBarCloseButtonLengthDoubleKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.InfoBarCloseButtonLengthDoubleKey) | The default `Width` and `Height` of the **Close Button**. |
+| [InfoBarIconLengthDoubleKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.InfoBarIconLengthDoubleKey) | The default `Width` and `Height` of the **Icon**. |
+| [InfoBarPaddingNormalThicknessKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.InfoBarPaddingNormalThicknessKey) | The default `Padding`. |
+}
+
+## Customize String Resources
+
+The following string resources are available to localize or customize built-in strings:
+
+@if (avalonia) {
+| Resource key | Description |
+|-----|-----|
+| [UIButtonCloseDisplayName](xref:ActiproSoftware.Properties.Shared.SRName.UIButtonCloseDisplayName) | The tooltip of the **Close Button**. The default value is `"Close"`. |
+
+The following sample demonstrates how to set custom values for string resources:
+
+```csharp
+ActiproSoftware.Properties.Shared.SR.SetCustomString(ActiproSoftware.Properties.Shared.SRName.UIButtonCloseDisplayName, "Hide");
+```
+
+See the [Customizing String Resources](../../customizing-string-resources.md) topic for additional details.
+}
+@if (wpf) {
+| Resource key | Description |
+|-----|-----|
+| `UICloseButtonToolTip` | The tooltip of the **Close Button**. The default value is `"Close"`. |
+
+The following sample demonstrates how to set custom values for string resources:
+
+```csharp
+ActiproSoftware.Products.Shared.SR.SetCustomString(ActiproSoftware.Products.Shared.SRName.UICloseButtonToolTip.ToString(), "Hide");
+```
+
+See the [Customizing String Resources](../../customizing-string-resources.md) topic for additional details.
+}
\ No newline at end of file
diff --git a/Documentation/topics/shared/windows-controls/pixelsnapper.md b/Documentation/topics/shared/windows-controls/pixelsnapper.md
index 4206c21a..01bd1fb1 100644
--- a/Documentation/topics/shared/windows-controls/pixelsnapper.md
+++ b/Documentation/topics/shared/windows-controls/pixelsnapper.md
@@ -1,7 +1,7 @@
---
title: "PixelSnapper"
page-title: "PixelSnapper - Shared Library Controls"
-order: 23
+order: 70
---
# PixelSnapper
diff --git a/Documentation/topics/shared/windows-controls/popupbutton.md b/Documentation/topics/shared/windows-controls/popupbutton.md
index 55df62ba..3d065335 100644
--- a/Documentation/topics/shared/windows-controls/popupbutton.md
+++ b/Documentation/topics/shared/windows-controls/popupbutton.md
@@ -1,7 +1,7 @@
---
title: "PopupButton"
page-title: "PopupButton - Shared Library Controls"
-order: 25
+order: 75
---
# PopupButton
diff --git a/Documentation/topics/shared/windows-controls/progress-spinners.md b/Documentation/topics/shared/windows-controls/progress-spinners.md
index 7f9ea578..d57570eb 100644
--- a/Documentation/topics/shared/windows-controls/progress-spinners.md
+++ b/Documentation/topics/shared/windows-controls/progress-spinners.md
@@ -1,7 +1,7 @@
---
title: "Progress Spinners"
page-title: "Progress Spinners - Shared Library Controls"
-order: 40
+order: 125
---
# Progress Spinners
diff --git a/Documentation/topics/shared/windows-controls/radialslider.md b/Documentation/topics/shared/windows-controls/radialslider.md
index bbddf912..58e3b727 100644
--- a/Documentation/topics/shared/windows-controls/radialslider.md
+++ b/Documentation/topics/shared/windows-controls/radialslider.md
@@ -1,7 +1,7 @@
---
title: "RadialSlider"
page-title: "RadialSlider - Shared Library Controls"
-order: 27
+order: 80
---
# RadialSlider
diff --git a/Documentation/topics/shared/windows-controls/radiobuttonlist.md b/Documentation/topics/shared/windows-controls/radiobuttonlist.md
index 548efb99..983c0ad0 100644
--- a/Documentation/topics/shared/windows-controls/radiobuttonlist.md
+++ b/Documentation/topics/shared/windows-controls/radiobuttonlist.md
@@ -1,7 +1,7 @@
---
title: "RadioButtonList"
page-title: "RadioButtonList - Shared Library Controls"
-order: 28
+order: 85
---
# RadioButtonList
diff --git a/Documentation/topics/shared/windows-controls/reflectioncontentcontrol.md b/Documentation/topics/shared/windows-controls/reflectioncontentcontrol.md
index 4e7fe033..350fe05b 100644
--- a/Documentation/topics/shared/windows-controls/reflectioncontentcontrol.md
+++ b/Documentation/topics/shared/windows-controls/reflectioncontentcontrol.md
@@ -1,7 +1,7 @@
---
title: "ReflectionContentControl"
page-title: "ReflectionContentControl - Shared Library Controls"
-order: 31
+order: 90
---
# ReflectionContentControl
diff --git a/Documentation/topics/shared/windows-controls/resizablecontentcontrol.md b/Documentation/topics/shared/windows-controls/resizablecontentcontrol.md
index eb625b0f..4234102b 100644
--- a/Documentation/topics/shared/windows-controls/resizablecontentcontrol.md
+++ b/Documentation/topics/shared/windows-controls/resizablecontentcontrol.md
@@ -1,7 +1,7 @@
---
title: "ResizableContentControl"
page-title: "ResizableContentControl - Shared Library Controls"
-order: 32
+order: 95
---
# ResizableContentControl
diff --git a/Documentation/topics/shared/windows-controls/ringslice.md b/Documentation/topics/shared/windows-controls/ringslice.md
index d9544e6a..ed5db29d 100644
--- a/Documentation/topics/shared/windows-controls/ringslice.md
+++ b/Documentation/topics/shared/windows-controls/ringslice.md
@@ -1,7 +1,7 @@
---
title: "RingSlice"
page-title: "RingSlice - Shared Library Controls"
-order: 33
+order: 100
---
# RingSlice
diff --git a/Documentation/topics/shared/windows-controls/shadowchrome.md b/Documentation/topics/shared/windows-controls/shadowchrome.md
index 7cd40afe..c3c6a7d8 100644
--- a/Documentation/topics/shared/windows-controls/shadowchrome.md
+++ b/Documentation/topics/shared/windows-controls/shadowchrome.md
@@ -1,7 +1,7 @@
---
title: "ShadowChrome"
page-title: "ShadowChrome - Shared Library Controls"
-order: 34
+order: 105
---
# ShadowChrome
diff --git a/Documentation/topics/shared/windows-controls/template-selectors.md b/Documentation/topics/shared/windows-controls/template-selectors.md
new file mode 100644
index 00000000..37e131fb
--- /dev/null
+++ b/Documentation/topics/shared/windows-controls/template-selectors.md
@@ -0,0 +1,92 @@
+---
+title: "Template Selectors"
+page-title: "Template Selectors - Shared Library Controls"
+order: 130
+---
+# Template Selectors
+
+Template selectors (i.e., `DataTemplateSelector`) are primarily used with a `ContentPresenter` to automatically select the best `DataTemplate` for the current `Content`.
+
+## ImageTemplateSelector Overview
+
+The [ImageTemplateSelector](xref:@ActiproUIRoot.Controls.ImageTemplateSelector) can be used to define an image from multiple sources. The following `DataTemplate` properties are supported:
+
+| Property | Description |
+| ----- | ----- |
+| [DefaultTemplate](xref:@ActiproUIRoot.Controls.ImageTemplateSelector.DefaultTemplate) | Defines the template to be used for `null` data values. This property is typically undefined but can be populated to insert a placeholder for undefined image data instead of leaving it empty.
+| [GeometryTemplate](xref:@ActiproUIRoot.Controls.ImageTemplateSelector.GeometryTemplate) | Defines the template to be used with `Geometry` data values. This is typically a `Path` filled with the `TextElement.Foreground` brush. |
+| [ImageSourceTemplate](xref:@ActiproUIRoot.Controls.ImageTemplateSelector.ImageSourceTemplate) | Defines the template to be used with `ImageSource` data values. This is typically a [DynamicImage](dynamicimage.md) control. |
+
+Some controls will have their image properties based on the `object` data type instead of `ImageSource`. For those controls, the corresponding control template will use a `ContentPresenter` with the image property as `Content` and assign a default instance of [ImageTemplateSelector](xref:@ActiproUIRoot.Controls.ImageTemplateSelector) for the `ContentTemplateSelector`.
+
+
+The following example demonstrates creating an instance of [ImageTemplateSelector](xref:@ActiproUIRoot.Controls.ImageTemplateSelector) using templates that are consistent with typical usage scenarios:
+
+```xaml
+xmlns:shared="http://schemas.actiprosoftware.com/winfx/xaml/shared"
+...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+The following data values are recognized by the [ImageTemplateSelector](xref:@ActiproUIRoot.Controls.ImageTemplateSelector):
+
+| Content | Description |
+| ----- | ----- |
+| `Geometry` | `Geometry` values (i.e. path data) will use [GeometryTemplate](xref:@ActiproUIRoot.Controls.ImageTemplateSelector.GeometryTemplate) |
+| `ImageSource` | `ImageSource` values will use [ImageSourceTemplate](xref:@ActiproUIRoot.Controls.ImageTemplateSelector.ImageSourceTemplate) |
+| `null` | `null` values will use [DefaultTemplate](xref:@ActiproUIRoot.Controls.ImageTemplateSelector.DefaultTemplate). |
+| `string` | `string` values will be analyzed to determine the type of data represented by the `string` and use the most appropriate template. See the "String Value Processing" section below for more details.
+| `Uri` | `Uri` values will use [ImageSourceTemplate](xref:@ActiproUIRoot.Controls.ImageTemplateSelector.ImageSourceTemplate). |
+
+> [!NOTE]
+> Non-`null` data values will return a `null` reference as the `DataTemplate` that allows the `ContentPresenter` to use default logic for presenting the data .
+
+### String Value Processing
+
+A `string` value is analyzed to determine the type of data represented so the best template can be used.
+
+Any `string` that starts with `"/"` or `"pack::"` is assumed to be a `Uri` for an `ImageSource` and will use [ImageSourceTemplate](xref:@ActiproUIRoot.Controls.ImageTemplateSelector.ImageSourceTemplate). Set the [AllowStringUri](xref:@ActiproUIRoot.Controls.ImageTemplateSelector.AllowStringUri) instance property to `false` to prevent processing a `string` value as a `Uri`. The [DefaultAllowStringUri](xref:@ActiproUIRoot.Controls.ImageTemplateSelector.DefaultAllowStringUri) static property can be set to `false` to disable `Uri` processing for all new class instances.
+
+Any `string` that can be parsed by `Geometry.Parse` without throwing an exception will use [GeometryTemplate](xref:@ActiproUIRoot.Controls.ImageTemplateSelector.GeometryTemplate). Set the [AllowStringGeometry](xref:@ActiproUIRoot.Controls.ImageTemplateSelector.AllowStringGeometry) instance property to `false` to prevent processing a `string` value as a `Geometry`. The [DefaultAllowStringGeometry](xref:@ActiproUIRoot.Controls.ImageTemplateSelector.DefaultAllowStringGeometry) static property can be set to `false` to disable `Geometry` processing for all new class instances.
+
+> [!IMPORTANT]
+> When [AllowStringGeometry](xref:@ActiproUIRoot.Controls.ImageTemplateSelector.AllowStringGeometry) is `true`, a `FormatException` can be thrown when attempting to parse the `string`. This exception is handled but may appear in the **Output** window of debuggers like Visual Studio. If `Geometry` strings are not used by an application, set the [DefaultAllowStringGeometry](xref:@ActiproUIRoot.Controls.ImageTemplateSelector.DefaultAllowStringGeometry) static property to `false` to prevent exceptions from failed parse attempts.
+
+The following demonstrates several common ways to define a custom icon for the [InfoBar](info-bar.md) control which utilizes [ImageTemplateSelector](xref:@ActiproUIRoot.Controls.ImageTemplateSelector):
+
+```xaml
+xmlns:shared="http://schemas.actiprosoftware.com/winfx/xaml/shared"
+...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
\ No newline at end of file
diff --git a/Documentation/topics/shared/windows-controls/toggle-switch.md b/Documentation/topics/shared/windows-controls/toggle-switch.md
index dfa7eaba..c63b8af7 100644
--- a/Documentation/topics/shared/windows-controls/toggle-switch.md
+++ b/Documentation/topics/shared/windows-controls/toggle-switch.md
@@ -1,7 +1,7 @@
---
title: "ToggleSwitch"
page-title: "ToggleSwitch - Shared Library Controls"
-order: 35
+order: 110
---
# ToggleSwitch
diff --git a/Documentation/topics/shared/windows-controls/user-prompt/.toc-generator.yml b/Documentation/topics/shared/windows-controls/user-prompt/.toc-generator.yml
index f53ea3eb..2fa74b2c 100644
--- a/Documentation/topics/shared/windows-controls/user-prompt/.toc-generator.yml
+++ b/Documentation/topics/shared/windows-controls/user-prompt/.toc-generator.yml
@@ -1,2 +1,2 @@
title: "User Prompt"
-order: 36
+order: 115
diff --git a/Documentation/topics/shared/windows-controls/user-prompt/appearance.md b/Documentation/topics/shared/windows-controls/user-prompt/appearance.md
index 1ef8da10..7fd025bc 100644
--- a/Documentation/topics/shared/windows-controls/user-prompt/appearance.md
+++ b/Documentation/topics/shared/windows-controls/user-prompt/appearance.md
@@ -18,14 +18,14 @@ When either the [HeaderBackground](xref:@ActiproUIRoot.Controls.UserPromptContro
## Images
@if (avalonia) {
-Any `IImage` can be set to the [StatusImage](xref:@ActiproUIRoot.Controls.UserPromptControl.StatusImage) or [FooterImage](xref:@ActiproUIRoot.Controls.UserPromptControl.FooterImage) properties for a custom look. When using the [builder pattern](builder-pattern.md), set the `IImage` using [WithStatusImage](xref:@ActiproUIRoot.Controls.UserPromptBuilder.WithStatusImage*) or [WithFooterImage](xref:@ActiproUIRoot.Controls.UserPromptBuilder.WithFooterImage*).
+Any `IImage` can be set to the [StatusImageSource](xref:@ActiproUIRoot.Controls.UserPromptControl.StatusImageSource) or [FooterImageSource](xref:@ActiproUIRoot.Controls.UserPromptControl.FooterImageSource) properties for a custom look. When using the [builder pattern](builder-pattern.md), set the `IImage` using [WithStatusImage](xref:@ActiproUIRoot.Controls.UserPromptBuilder.WithStatusImage*) or [WithFooterImage](xref:@ActiproUIRoot.Controls.UserPromptBuilder.WithFooterImage*).
-The images used by [MessageBoxImage](xref:@ActiproUIRoot.Controls.MessageBoxImage) can also be customized by assigning a custom [ImageProvider](xref:@ActiproUIRoot.Media.ImageProvider) to the [ImageProvider](xref:@ActiproUIRoot.Media.ImageProvider).[Default](xref:@ActiproUIRoot.Media.ImageProvider.Default) property. Each value for [MessageBoxImage](xref:@ActiproUIRoot.Controls.MessageBoxImage) corresponds to a key of the same name defined by [SharedImageKeys](xref:@ActiproUIRoot.Media.SharedImageKeys). For example, the image [MessageBoxImage](xref:@ActiproUIRoot.Controls.MessageBoxImage).[Warning](xref:@ActiproUIRoot.Controls.MessageBoxImage.Warning) corresponds to the key [SharedImageKeys](xref:@ActiproUIRoot.Media.SharedImageKeys).[Warning](xref:@ActiproUIRoot.Media.SharedImageKeys.Warning). A custom class which derives from [ImageProvider](xref:@ActiproUIRoot.Media.ImageProvider) can override the [ImageProvider](xref:@ActiproUIRoot.Media.ImageProvider).[GetImageSource](xref:@ActiproUIRoot.Media.ImageProvider.GetImageSource*) method to return a custom `IImage` for one or more of those keys.
+The images used by [MessageBoxImage](xref:@ActiproUIRoot.Controls.MessageBoxImage) can also be customized by assigning a custom [ImageProvider](xref:@ActiproUIRoot.Media.ImageProvider) to the [ImageProvider](xref:@ActiproUIRoot.Media.ImageProvider).[Default](xref:@ActiproUIRoot.Media.ImageProvider.Default) property. Each value for [MessageBoxImage](xref:@ActiproUIRoot.Controls.MessageBoxImage) corresponds to a key of the same name defined by [SharedImageSourceKeys](xref:@ActiproUIRoot.Media.SharedImageSourceKeys). For example, the image [MessageBoxImage](xref:@ActiproUIRoot.Controls.MessageBoxImage).[Warning](xref:@ActiproUIRoot.Controls.MessageBoxImage.Warning) corresponds to the key [SharedImageSourceKeys](xref:@ActiproUIRoot.Media.SharedImageSourceKeys).[Warning](xref:@ActiproUIRoot.Media.SharedImageSourceKeys.Warning). A custom class which derives from [ImageProvider](xref:@ActiproUIRoot.Media.ImageProvider) can override the [ImageProvider](xref:@ActiproUIRoot.Media.ImageProvider).[GetImageSource](xref:@ActiproUIRoot.Media.ImageProvider.GetImageSource*) method to return a custom `IImage` for one or more of those keys.
}
@if (wpf) {
Any `ImageSource` can be set to the [StatusImageSource](xref:@ActiproUIRoot.Controls.UserPromptControl.StatusImageSource) or [FooterImageSource](xref:@ActiproUIRoot.Controls.UserPromptControl.FooterImageSource) properties for a custom look. When using the [builder pattern](builder-pattern.md), set the `ImageSource` using [WithStatusImage](xref:@ActiproUIRoot.Controls.UserPromptBuilder.WithStatusImage*) or [WithFooterImage](xref:@ActiproUIRoot.Controls.UserPromptBuilder.WithFooterImage*).
-The images used by [UserPromptStandardImage](xref:@ActiproUIRoot.Controls.UserPromptStandardImage) can also be customized by assigning a custom [ImageProvider](xref:@ActiproUIRoot.Media.ImageProvider) to the [ImageProvider](xref:@ActiproUIRoot.Media.ImageProvider).[Default](xref:@ActiproUIRoot.Media.ImageProvider.Default) property. Each value for [UserPromptStandardImage](xref:@ActiproUIRoot.Controls.UserPromptStandardImage) corresponds to a key of the same name defined by [SharedImageKeys](xref:@ActiproUIRoot.Media.SharedImageSourceKeys). For example, the image [UserPromptStandardImage](xref:@ActiproUIRoot.Controls.UserPromptStandardImage).[Warning](xref:@ActiproUIRoot.Controls.UserPromptStandardImage.Warning) corresponds to the key [SharedImageSourceKeys](xref:@ActiproUIRoot.Media.SharedImageSourceKeys).[Warning](xref:@ActiproUIRoot.Media.SharedImageSourceKeys.Warning). A custom class which derives from [ImageProvider](xref:@ActiproUIRoot.Media.ImageProvider) can override the [ImageProvider](xref:@ActiproUIRoot.Media.ImageProvider).[GetImageSource](xref:@ActiproUIRoot.Media.ImageProvider.GetImageSource*) method to return a custom `ImageSource` for one or more of those keys.
+The images used by [UserPromptStandardImage](xref:@ActiproUIRoot.Controls.UserPromptStandardImage) can also be customized by assigning a custom [ImageProvider](xref:@ActiproUIRoot.Media.ImageProvider) to the [ImageProvider](xref:@ActiproUIRoot.Media.ImageProvider).[Default](xref:@ActiproUIRoot.Media.ImageProvider.Default) property. Each value for [UserPromptStandardImage](xref:@ActiproUIRoot.Controls.UserPromptStandardImage) corresponds to a key of the same name defined by [SharedImageSourceKeys](xref:@ActiproUIRoot.Media.SharedImageSourceKeys). For example, the image [UserPromptStandardImage](xref:@ActiproUIRoot.Controls.UserPromptStandardImage).[Warning](xref:@ActiproUIRoot.Controls.UserPromptStandardImage.Warning) corresponds to the key [SharedImageSourceKeys](xref:@ActiproUIRoot.Media.SharedImageSourceKeys).[Warning](xref:@ActiproUIRoot.Media.SharedImageSourceKeys.Warning). A custom class which derives from [ImageProvider](xref:@ActiproUIRoot.Media.ImageProvider) can override the [ImageProvider](xref:@ActiproUIRoot.Media.ImageProvider).[GetImageSource](xref:@ActiproUIRoot.Media.ImageProvider.GetImageSource*) method to return a custom `ImageSource` for one or more of those keys.
}
## Customize UserPromptWindow
diff --git a/Documentation/topics/shared/windows-controls/user-prompt/builder-pattern.md b/Documentation/topics/shared/windows-controls/user-prompt/builder-pattern.md
index 31c28cf0..9432065e 100644
--- a/Documentation/topics/shared/windows-controls/user-prompt/builder-pattern.md
+++ b/Documentation/topics/shared/windows-controls/user-prompt/builder-pattern.md
@@ -40,6 +40,7 @@ There are two methods available to register callbacks that are always invoked to
The [UserPromptBuilder](xref:@ActiproUIRoot.Controls.UserPromptBuilder).[RegisterGlobalConfigureCallback](xref:@ActiproUIRoot.Controls.UserPromptBuilder.RegisterGlobalConfigureCallback*) method is used to register a callback that is invoked immediately after creating a new instance of [UserPromptBuilder](xref:@ActiproUIRoot.Controls.UserPromptBuilder). Use this method to define an application-wide configuration that will be applied to all user prompts without having to configure each builder instance individually.
+@if (avalonia) {
The following example demonstrates how a global callback can be registered to use the `theme-solid accent` style classes on the default button (if any) for every prompt:
```csharp
@@ -47,6 +48,17 @@ UserPromptBuilder.RegisterGlobalConfigureCallback(_ => _
.WithDefaultButtonClasses("theme-solid accent")
);
```
+}
+@if (wpf) {
+The following example demonstrates how a global callback can be registered to customize the header for every prompt:
+
+```csharp
+UserPromptBuilder.RegisterGlobalConfigureCallback(_ => _
+ .WithHeaderFontSize(16)
+ .WithHeaderForeground(new SolidColorBrush(Colors.Blue))
+);
+```
+}
@if (avalonia) {
##### MessageBox Only
@@ -167,6 +179,10 @@ The [UserPromptBuilder](xref:@ActiproUIRoot.Controls.UserPromptBuilder).[Instanc
> [!TIP]
> To interact with the [UserPromptBuilder](xref:@ActiproUIRoot.Controls.UserPromptBuilder).[Instance](xref:@ActiproUIRoot.Controls.UserPromptBuilder.Instance) from one of the global configuration callbacks, use the global configuration to add a callback for one of the other callbacks (like [AfterInitialize](xref:@ActiproUIRoot.Controls.UserPromptBuilder.AfterInitialize*)) that will be invoked after the instance is defined.
+### Tag Property
+
+The [UserPromptBuilder](xref:@ActiproUIRoot.Controls.UserPromptBuilder).[Tag](xref:@ActiproUIRoot.Controls.UserPromptBuilder.Tag) property can be used to store an arbitrary object value on the builder, and this can be used to store data that is accessibile from multiple callback methods. Use the [UserPromptBuilder](xref:@ActiproUIRoot.Controls.UserPromptBuilder).[WithTag](xref:@ActiproUIRoot.Controls.UserPromptBuilder.WithTag*) method to assign values to this property.
+
### AfterInitialize Callback
This callback is invoked immediately after an instance of [UserPromptControl](xref:@ActiproUIRoot.Controls.UserPromptControl) is created and can be used to initialize the control or further customize the builder before the builder configuration settings are applied.
diff --git a/Documentation/topics/shared/windows-controls/user-prompt/extension-methods.md b/Documentation/topics/shared/windows-controls/user-prompt/extension-methods.md
index e6fe4dc5..678a1ec7 100644
--- a/Documentation/topics/shared/windows-controls/user-prompt/extension-methods.md
+++ b/Documentation/topics/shared/windows-controls/user-prompt/extension-methods.md
@@ -59,4 +59,8 @@ catch (Exception ex) {
}
> [!TIP]
-> See the [Localization](localization.md) topic for details on how to customize the string resources used for exception prompt.
\ No newline at end of file
+> See the [Localization](localization.md) topic for details on how to customize the string resources used for exception prompt.
+
+## Tag Property
+
+The [UserPromptBuilder](xref:@ActiproUIRoot.Controls.UserPromptBuilder).[Tag](xref:@ActiproUIRoot.Controls.UserPromptBuilder.Tag) property can be used to store an arbitrary object value on the builder, and this can be useful for extension methods that need to store custom values while building the prompt. Use the [UserPromptBuilder](xref:@ActiproUIRoot.Controls.UserPromptBuilder).[WithTag](xref:@ActiproUIRoot.Controls.UserPromptBuilder.WithTag*) method to assign values to this property.
\ No newline at end of file
diff --git a/Documentation/topics/shared/windows-controls/user-prompt/localization.md b/Documentation/topics/shared/windows-controls/user-prompt/localization.md
index e0fbfe34..abde9db9 100644
--- a/Documentation/topics/shared/windows-controls/user-prompt/localization.md
+++ b/Documentation/topics/shared/windows-controls/user-prompt/localization.md
@@ -34,7 +34,7 @@ The following string resources are defined in the Shared Library assembly and ar
| [UICopyButtonFailureText](xref:ActiproSoftware.Properties.Shared.SRName.UICopyButtonFailureText) | The text displayed on the [exception prompt](extension-methods.md) if the [CopyButton](xref:@ActiproUIRoot.Controls.CopyButton) fails to copy the stack trace. The default value is `"Error copying text!"`. |
| [UICopyButtonSuccessText](xref:ActiproSoftware.Properties.Shared.SRName.UICopyButtonSuccessText) | The text displayed on the [exception prompt](extension-methods.md) if the [CopyButton](xref:@ActiproUIRoot.Controls.CopyButton) successfully copies the stack trace. The default value is `"Copied!"`. |
| [UIDialogTitleErrorText](xref:ActiproSoftware.Properties.Shared.SRName.UIDialogTitleErrorText) | The default title used by [UserPromptWindow](xref:@ActiproUIRoot.Controls.UserPromptWindow) when an explicit title is not defined and [UserPromptControl](xref:@ActiproUIRoot.Controls.UserPromptControl).[StandardStatusImage](xref:@ActiproUIRoot.Controls.UserPromptControl.StandardStatusImage) is set to [Error](xref:@ActiproUIRoot.Controls.MessageBoxImage.Error). The default value is `"Error"`. |
-| [UIDialogTitleIndeterminateText](xref:ActiproSoftware.Properties.Shared.SRName.UIDialogTitleIndeterminateText) | The default title used by [UserPromptWindow](xref:@ActiproUIRoot.Controls.UserPromptWindow) when an explicit title is not defined and [UserPromptControl](xref:@ActiproUIRoot.Controls.UserPromptControl).[StandardStatusImage](xref:@ActiproUIRoot.Controls.UserPromptControl.StandardStatusImage) is set to [None](xref:@ActiproUIRoot.Controls.MessageBoxImage.None) or [UserPromptControl](xref:@ActiproUIRoot.Controls.UserPromptControl).[StatusImage](xref:@ActiproUIRoot.Controls.UserPromptControl.StatusImage) is populated. The default value is `String.Empty`. |
+| [UIDialogTitleIndeterminateText](xref:ActiproSoftware.Properties.Shared.SRName.UIDialogTitleIndeterminateText) | The default title used by [UserPromptWindow](xref:@ActiproUIRoot.Controls.UserPromptWindow) when an explicit title is not defined and [UserPromptControl](xref:@ActiproUIRoot.Controls.UserPromptControl).[StandardStatusImage](xref:@ActiproUIRoot.Controls.UserPromptControl.StandardStatusImage) is set to [None](xref:@ActiproUIRoot.Controls.MessageBoxImage.None) or [UserPromptControl](xref:@ActiproUIRoot.Controls.UserPromptControl).[StatusImageSource](xref:@ActiproUIRoot.Controls.UserPromptControl.StatusImageSource) is populated. The default value is `String.Empty`. |
| [UIDialogTitleInformationText](xref:ActiproSoftware.Properties.Shared.SRName.UIDialogTitleInformationText) | The default title used by [UserPromptWindow](xref:@ActiproUIRoot.Controls.UserPromptWindow) when an explicit title is not defined and [UserPromptControl](xref:@ActiproUIRoot.Controls.UserPromptControl).[StandardStatusImage](xref:@ActiproUIRoot.Controls.UserPromptControl.StandardStatusImage) is set to [Information](xref:@ActiproUIRoot.Controls.MessageBoxImage.Information). The default value is `"Information"`. |
| [UIDialogTitleQuestionText](xref:ActiproSoftware.Properties.Shared.SRName.UIDialogTitleQuestionText) | The default title used by [UserPromptWindow](xref:@ActiproUIRoot.Controls.UserPromptWindow) when an explicit title is not defined and [UserPromptControl](xref:@ActiproUIRoot.Controls.UserPromptControl).[StandardStatusImage](xref:@ActiproUIRoot.Controls.UserPromptControl.StandardStatusImage) is set to [Question](xref:@ActiproUIRoot.Controls.MessageBoxImage.Question). The default value is `"Question"`. |
| [UIDialogTitleWarningText](xref:ActiproSoftware.Properties.Shared.SRName.UIDialogTitleWarningText) | The default title used by [UserPromptWindow](xref:@ActiproUIRoot.Controls.UserPromptWindow) when an explicit title is not defined and [UserPromptControl](xref:@ActiproUIRoot.Controls.UserPromptControl).[StandardStatusImage](xref:@ActiproUIRoot.Controls.UserPromptControl.StandardStatusImage) is set to [Warning](xref:@ActiproUIRoot.Controls.MessageBoxImage.Warning). The default value is `"Warning"`. |
diff --git a/Documentation/topics/shared/windows-controls/user-prompt/user-prompt-content.md b/Documentation/topics/shared/windows-controls/user-prompt/user-prompt-content.md
index a0cfc025..ded55703 100644
--- a/Documentation/topics/shared/windows-controls/user-prompt/user-prompt-content.md
+++ b/Documentation/topics/shared/windows-controls/user-prompt/user-prompt-content.md
@@ -135,9 +135,9 @@ The `Footer` property can be defined to display content at the bottom of the pro
Any `TextBlock` controls used within `Footer` will wrap text by default.
@if (avalonia) {
-Use the [FooterImage](xref:@ActiproUIRoot.Controls.UserPromptControl.FooterImage) property to optionally display a 16x16 image next to the `Footer` content. Any `IImage` is supported.
+Use the [FooterImageSource](xref:@ActiproUIRoot.Controls.UserPromptControl.FooterImageSource) property to optionally display a 16x16 image next to the `Footer` content. Any `IImage` is supported.
-When using the [builder pattern](builder-pattern.md), the [WithFooterContent](xref:@ActiproUIRoot.Controls.UserPromptBuilder.WithFooterContent*) method is used to configure the [UserPromptBuilder](xref:@ActiproUIRoot.Controls.UserPromptControl.Footer) property and the [WithFooterImage](xref:@ActiproUIRoot.Controls.UserPromptBuilder.WithFooterImage*) method configures the [FooterImage](xref:@ActiproUIRoot.Controls.UserPromptControl.FooterImage) property.
+When using the [builder pattern](builder-pattern.md), the [WithFooterContent](xref:@ActiproUIRoot.Controls.UserPromptBuilder.WithFooterContent*) method is used to configure the [UserPromptBuilder](xref:@ActiproUIRoot.Controls.UserPromptControl.Footer) property and the [WithFooterImage](xref:@ActiproUIRoot.Controls.UserPromptBuilder.WithFooterImage*) method configures the [FooterImageSource](xref:@ActiproUIRoot.Controls.UserPromptControl.FooterImageSource) property.
```csharp
await UserPromptBuilder.Configure()
@@ -260,12 +260,12 @@ UserPromptBuilder.Configure()
An image can be used to visually communicate the status or classification of the prompt displayed. Users can quickly differentiate an error from a warning based on the image displayed with the prompt.
@if (avalonia) {
-The [StatusImage](xref:@ActiproUIRoot.Controls.UserPromptControl.StatusImage) property can be set to any 32x32 `IImage`.
+The [StatusImageSource](xref:@ActiproUIRoot.Controls.UserPromptControl.StatusImageSource) property can be set to any 32x32 `IImage`.
-Several common images, like those for an error or warning, are defined by the [MessageBoxImage](xref:@ActiproUIRoot.Controls.MessageBoxImage) enumeration. Instead of populating the [StatusImage](xref:@ActiproUIRoot.Controls.UserPromptControl.StatusImage) property, set the [StandardStatusImage](xref:@ActiproUIRoot.Controls.UserPromptControl.StandardStatusImage) property to one of the [MessageBoxImage](xref:@ActiproUIRoot.Controls.MessageBoxImage) values.
+Several common images, like those for an error or warning, are defined by the [MessageBoxImage](xref:@ActiproUIRoot.Controls.MessageBoxImage) enumeration. Instead of populating the [StatusImageSource](xref:@ActiproUIRoot.Controls.UserPromptControl.StatusImageSource) property, set the [StandardStatusImage](xref:@ActiproUIRoot.Controls.UserPromptControl.StandardStatusImage) property to one of the [MessageBoxImage](xref:@ActiproUIRoot.Controls.MessageBoxImage) values.
> [!WARNING]
-> The [StandardStatusImage](xref:@ActiproUIRoot.Controls.UserPromptControl.StandardStatusImage) property is ignored if the [StatusImage](xref:@ActiproUIRoot.Controls.UserPromptControl.StatusImage) property is explicitly populated.
+> The [StandardStatusImage](xref:@ActiproUIRoot.Controls.UserPromptControl.StandardStatusImage) property is ignored if the [StatusImageSource](xref:@ActiproUIRoot.Controls.UserPromptControl.StatusImageSource) property is explicitly populated.
When using the [builder pattern](builder-pattern.md), the [WithStatusImage](xref:@ActiproUIRoot.Controls.UserPromptBuilder.WithStatusImage*) has one overload that accepts a custom `IImage` and another for a standard [MessageBoxImage](xref:@ActiproUIRoot.Controls.MessageBoxImage):
diff --git a/Documentation/topics/shared/windows-controls/zerosizecontentcontrol.md b/Documentation/topics/shared/windows-controls/zerosizecontentcontrol.md
index 0f4b2285..a29780d9 100644
--- a/Documentation/topics/shared/windows-controls/zerosizecontentcontrol.md
+++ b/Documentation/topics/shared/windows-controls/zerosizecontentcontrol.md
@@ -1,7 +1,7 @@
---
title: "ZeroSizeContentControl"
page-title: "ZeroSizeContentControl - Shared Library Controls"
-order: 37
+order: 120
---
# ZeroSizeContentControl
diff --git a/Documentation/topics/toc.yml b/Documentation/topics/toc.yml
index b1e80539..e055c7d3 100644
--- a/Documentation/topics/toc.yml
+++ b/Documentation/topics/toc.yml
@@ -1560,6 +1560,12 @@ items:
href: views/controls/book.md
- name: "InertiaScrollViewer"
href: views/controls/inertia-scroll-viewer.md
+ - name: "SettingsCard"
+ href: views/controls/settings-card.md
+ - name: "SettingsExpander"
+ href: views/controls/settings-expander.md
+ - name: "SettingsGroup"
+ href: views/controls/settings-group.md
- name: "TaskBoard"
href: views/controls/taskboard.md
- name: "Panels"
@@ -1690,6 +1696,8 @@ items:
href: shared/windows-controls/avatar-group.md
- name: "Badge"
href: shared/windows-controls/badge.md
+ - name: "Card"
+ href: shared/windows-controls/card.md
- name: "CircularProgressBar"
href: shared/windows-controls/circular-progressbar.md
- name: "CustomDrawElement"
@@ -1704,6 +1712,8 @@ items:
href: shared/windows-controls/horizontallistbox.md
- name: "ImageTextInfo"
href: shared/windows-controls/imagetextinfo.md
+ - name: "InfoBar"
+ href: shared/windows-controls/info-bar.md
- name: "PixelSnapper"
href: shared/windows-controls/pixelsnapper.md
- name: "PopupButton"
@@ -1749,6 +1759,8 @@ items:
href: shared/windows-controls/zerosizecontentcontrol.md
- name: "Progress Spinners"
href: shared/windows-controls/progress-spinners.md
+ - name: "Template Selectors"
+ href: shared/windows-controls/template-selectors.md
- name: "Color Selection"
href: shared/windows-controls-color-selection.md
- name: "Data"
diff --git a/Documentation/topics/views/controls/index.md b/Documentation/topics/views/controls/index.md
index aadb7941..fffe2ca6 100644
--- a/Documentation/topics/views/controls/index.md
+++ b/Documentation/topics/views/controls/index.md
@@ -17,6 +17,12 @@ The [InertiaScrollViewer](xref:@ActiproUIRoot.Controls.Views.InertiaScrollViewer
See the [InertiaScrollViewer](inertia-scroll-viewer.md) topic for more information.
+## Settings Controls
+
+The [SettingsCard](xref:@ActiproUIRoot.Controls.Views.SettingsCard), [SettingsExpander](xref:@ActiproUIRoot.Controls.Views.SettingsExpander), and [SettingsGroup](xref:@ActiproUIRoot.Controls.Views.SettingsGroup) controls are used together to organize and present configurable settings.
+
+See the [SettingsCard](settings-card.md), [Settings Expander](settings-expander.md), and [SettingsGroup](settings-group.md) topics for more information.
+
## TaskBoard
The [TaskBoard](xref:@ActiproUIRoot.Controls.Views.TaskBoard) control makes it easy to add interactive task scheduling and prioritization to your apps. A task board consists of zero to many columns, each of which can contain zero to many cards. Columns and cards can be dragged around and reordered, all using pleasing sway animations.
diff --git a/Documentation/topics/views/controls/settings-card.md b/Documentation/topics/views/controls/settings-card.md
new file mode 100644
index 00000000..3bd5976c
--- /dev/null
+++ b/Documentation/topics/views/controls/settings-card.md
@@ -0,0 +1,403 @@
+---
+title: "SettingsCard"
+page-title: "SettingsCard - Views Controls"
+order: 5
+---
+# SettingsCard
+
+The [SettingsCard](xref:@ActiproUIRoot.Controls.Views.SettingsCard), [SettingsExpander](settings-expander.md), and [SettingsGroup](settings-group.md) controls are used together to organize and present configurable settings.
+
+![Screenshot](../images/settings-examples.png)
+
+*SettingsCard and SettingsExpander displayed within a SettingsGroup*
+
+A [SettingsCard](xref:@ActiproUIRoot.Controls.Views.SettingsCard) is typically used to display a single setting and is the primary control used when building a settings interface.
+
+![Screenshot](../images/settings-card.png)
+
+*SettingsCard with header, description, header icon, and ToggleSwitch content*
+
+## Content Areas
+
+The [SettingsCard](xref:@ActiproUIRoot.Controls.Views.SettingsCard) control is defined by multiple content areas:
+
+- [Header](xref:@ActiproUIRoot.Controls.Views.SettingsCard.Header) - The primary label for the setting.
+- [Description](xref:@ActiproUIRoot.Controls.Views.SettingsCard.Description) - An additional description for the setting.
+- [HeaderIcon](xref:@ActiproUIRoot.Controls.Views.SettingsCard.HeaderIcon) - The primary icon for the setting.
+- [ActionIcon](xref:@ActiproUIRoot.Controls.Views.SettingsCard.HeaderIcon) - An icon displayed on the right side of the setting which is typically used to provide context for the action performed when a card is clicked.
+- `Content` (Editor) - The control used to edit the setting (e.g., `ToggleSwitch`, `ComboBox`).
+
+Each content area, including icons, can optionally be set to any value supported by `ContentPresenter` and the layout will adjust to only show the areas where content is defined.
+
+> [!NOTE]
+> In some scenarios, content may not be automatically detected. For instance, if a `DataTemplate` is used to define content without setting the corresponding content property, the control will not know that content is available. Use the [IsHeaderVisible](xref:@ActiproUIRoot.Controls.Views.SettingsCard.IsHeaderVisible), [IsDescriptionVisible](xref:@ActiproUIRoot.Controls.Views.SettingsCard.IsDescriptionVisible), [IsHeaderIconVisible](xref:@ActiproUIRoot.Controls.Views.SettingsCard.IsHeaderIconVisible), and [IsActionIconVisible](xref:@ActiproUIRoot.Controls.Views.SettingsCard.IsActionIconVisible) properties to manually control the visibility of each content area.
+
+> [!TIP]
+> The [SettingsExpander](settings-expander.md) control has all the same content areas as [SettingsCard](xref:@ActiproUIRoot.Controls.Views.SettingsCard) *except* [ActionIcon](xref:@ActiproUIRoot.Controls.Views.SettingsCard.ActionIcon).
+
+### Header and Description
+
+The [Header](xref:@ActiproUIRoot.Controls.Views.SettingsCard.Header) and [Description](xref:@ActiproUIRoot.Controls.Views.SettingsCard.Description) are typically `string` values describing the setting, and both are optional. The following demonstrates how to create a [SettingsCard](xref:@ActiproUIRoot.Controls.Views.SettingsCard) with a header and description:
+
+@if (avalonia) {
+```xaml
+xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui"
+...
+
+```
+}
+@if (wpf) {
+```xaml
+xmlns:views="http://schemas.actiprosoftware.com/winfx/xaml/views"
+...
+
+```
+}
+
+Since both properties can be set to any content supported by `ContentPresenter`, either property can be configured with more complex content. The following example demonstrates how a hyperlink could be used as the [Description](xref:@ActiproUIRoot.Controls.Views.SettingsCard.Description) @if (avalonia) { (using the [HyperlinkTextBlock](../../shared/controls/hyperlink-textblock.md) control) }:
+
+@if (avalonia) {
+```xaml
+xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui"
+...
+
+
+
+
+
+
+ ...
+
+
+```
+}
+@if (wpf) {
+```xaml
+xmlns:views="http://schemas.actiprosoftware.com/winfx/xaml/views"
+xmlns:themes="http://schemas.actiprosoftware.com/winfx/xaml/themes"
+...
+
+
+
+
+
+ Click here for more
+
+
+
+
+ ...
+
+
+```
+}
+
+### Icons
+
+The [SettingsCard](xref:@ActiproUIRoot.Controls.Views.SettingsCard) supports two icons:
+- [HeaderIcon](xref:@ActiproUIRoot.Controls.Views.SettingsCard.HeaderIcon) - An icon displayed on the left side of the card with a default size of `24x24`. This icon is typically related to the value(s) defined by the setting. For example, a speaker icon might be used for a setting related to output sound volume.
+- [ActionIcon](xref:@ActiproUIRoot.Controls.Views.SettingsCard.ActionIcon) - Typically used for cards with click enabled (see the "Enable Click" topic below), this icon is displayed on the right side of the card with a default size of `16x16`. It is most often related to the action that will be performed if a card is clicked. For example, if clicking a card opens a new window, an icon that represents opening an external window can help convey to the user what will happen if the card is clicked.
+
+@if (wpf) {
+> [!TIP]
+> The [HeaderIconTemplateSelector](xref:@ActiproUIRoot.Controls.Views.SettingsCard.HeaderIconTemplateSelector) and [ActionIconTemplateSelector](xref:@ActiproUIRoot.Controls.Views.SettingsCard.ActionIconTemplateSelector) are pre-configured with a default [ImageTemplateSelector](xref:@ActiproUIRoot.Controls.ImageTemplateSelector), so it supports `ImageSource` and `Geometry` data values. See the [Template Selectors](../../shared/windows-controls/template-selectors.md) topic for more details.
+}
+
+The following sample demonstrates two different techniques for defining either icon, but any content supported by `ContentPresenter` can be used to define the icons (like `Image` or @if (avalonia) { [DynamicImage](../../shared/controls/dynamic-image.md) }@if (wpf) { [DynamicImage](../../shared/windows-controls/dynamicimage.md) } controls):
+
+@if (avalonia) {
+```xaml
+xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui"
+...
+
+
+
+
+
+
+
+
+
+
+
+
+ ...
+
+
+```
+}
+@if (wpf) {
+```xaml
+xmlns:views="http://schemas.actiprosoftware.com/winfx/xaml/views"
+xmlns:themes="http://schemas.actiprosoftware.com/winfx/xaml/themes"
+...
+
+
+
+
+
+
+
+
+ ...
+
+
+```
+}
+
+### Content (Editor)
+
+The `Content` property (which is the default property for [SettingsCard](xref:@ActiproUIRoot.Controls.Views.SettingsCard)) is used to present core control for the setting. Any content supported by `ContentPresenter` can be used, but a setting is typically defined by common controls like `CheckBox`, `ComboBox`, `Slider`, and `ToggleSwitch`.
+
+The following sections discuss some of the common scenarios for defining a setting using popular control types, but the card is not limited to these control types.
+
+#### CheckBox Control
+
+A `CheckBox` is often used when the card does not define its own [Header](xref:@ActiproUIRoot.Controls.Views.SettingsCard.Header) and the label of the `CheckBox` is all that is needed.
+
+The following demonstrates defining a [SettingsCard](xref:@ActiproUIRoot.Controls.Views.SettingsCard) that uses a `CheckBox` without a header:
+
+@if (avalonia) {
+```xaml
+xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui"
+...
+
+
+
+
+
+```
+}
+@if (wpf) {
+```xaml
+xmlns:views="http://schemas.actiprosoftware.com/winfx/xaml/views"
+...
+
+
+
+
+
+```
+}
+
+#### Slider Control
+
+A `Slider` control is often used for selecting a value within a limited range. Since a `Slider` does not typically define a minimum width, it is recommended to set the width explicitly.
+
+The following demonstrates defining a [SettingsCard](xref:@ActiproUIRoot.Controls.Views.SettingsCard) that uses a `Slider`:
+
+@if (avalonia) {
+```xaml
+xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui"
+...
+
+
+
+
+
+```
+}
+@if (wpf) {
+```xaml
+xmlns:views="http://schemas.actiprosoftware.com/winfx/xaml/views"
+...
+
+
+
+
+
+```
+}
+
+#### TextBox Control
+
+A `TextBox` control used for a setting is typically displayed full width. This can be achieved by forcing the setting to wrap and using stretch alignment. See the "Wrapping" section below for more details on wrapping.
+
+The following demonstrates defining a [SettingsCard](xref:@ActiproUIRoot.Controls.Views.SettingsCard) that uses a full-width `TextBox` control:
+
+@if (avalonia) {
+```xaml
+xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui"
+...
+
+
+
+
+
+```
+}
+@if (wpf) {
+```xaml
+xmlns:shared="http://schemas.actiprosoftware.com/winfx/xaml/shared"
+xmlns:views="http://schemas.actiprosoftware.com/winfx/xaml/views"
+...
+
+
+
+
+
+```
+}
+
+#### ToggleSwitch Control
+
+A `ToggleSwitch` is a common control type for settings since the card's [Header](xref:@ActiproUIRoot.Controls.Views.SettingsCard.Header) has already defined the setting and the `ToggleSwitch` can easily be used to turn the named setting on or off without any additional label being required for context.
+
+@if (avalonia) {
+When used for a setting, a `ToggleSwitch` tends to look best with the track on the right and the on/off content on the left. When using Actipro Themes, set the [ThemeProperties](xref:@ActiproUIRoot.Themes.ThemeProperties).[ToggleSwitchHasFarAffinity](xref:@ActiproUIRoot.Themes.ThemeProperties.ToggleSwitchHasFarAffinityProperty) attached property to `true` for this layout. See the [Theme Assets](../../themes/theme-assets.md) topic for more details on working with theme resources and how to globally change the default for all `ToggleSwitch` instances.
+}
+
+The following demonstrates defining a [SettingsCard](xref:@ActiproUIRoot.Controls.Views.SettingsCard) that uses a `ToggleSwitch` control:
+
+@if (avalonia) {
+```xaml
+xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui"
+...
+
+
+
+
+
+```
+}
+@if (wpf) {
+```xaml
+xmlns:shared="http://schemas.actiprosoftware.com/winfx/xaml/shared"
+xmlns:views="http://schemas.actiprosoftware.com/winfx/xaml/views"
+...
+
+
+
+
+
+```
+}
+
+
+## Wrapping
+
+![Screenshot](../images/settings-card-wrapping.png)
+
+*SettingsCard displayed in the unwrapped and wrapped states*
+
+If enough space is available, the `Content` (Editor) of the setting is displayed to the right of the [Header](xref:@ActiproUIRoot.Controls.Views.SettingsCard.Header) and/or [Description](xref:@ActiproUIRoot.Controls.Views.SettingsCard.Description) with default right alignment. When the width of the card is less than or equal to the [WrapThreshold](xref:@ActiproUIRoot.Controls.Views.SettingsCard.WrapThreshold), the `Content` will be wrapped to the bottom of the card with default left alignment.
+
+Use the [IsWrapped](xref:@ActiproUIRoot.Controls.Views.SettingsCard.IsWrapped) property to manually control wrap behavior. When set to `null` (the default), wrapping is based on the [WrapThreshold](xref:@ActiproUIRoot.Controls.Views.SettingsCard.WrapThreshold). Set the property to `true` to force wrapping at any width, and `false` to prevent wrapping at any width.
+
+> [!NOTE]
+> Wrapping is only applicable if [Header](xref:@ActiproUIRoot.Controls.Views.SettingsCard.Header) and/or [Description](xref:@ActiproUIRoot.Controls.Views.SettingsCard.Description) are defined. Otherwise, the `Content` (Editor) will always be aligned left, by default.
+
+## Enable Click
+
+[SettingsCard](xref:@ActiproUIRoot.Controls.Views.SettingsCard) derives from `Button`, so it supports the same `Command` model and `Click` event as `Button`. Unlike a `Button`, though, not all instances of [SettingsCard](xref:@ActiproUIRoot.Controls.Views.SettingsCard) will need to support being clicked and the control has been configured to not be clickable by default.
+
+Set the [IsClickEnabled](xref:@ActiproUIRoot.Controls.Views.SettingsCard.IsClickEnabled) property to `true` to enable clicking the card. The `Click` event will not be raised if this property is `false`.
+
+> [!TIP]
+> If the `Command` property is assigned a non-`null` value, the [IsClickEnabled](xref:@ActiproUIRoot.Controls.Views.SettingsCard.IsClickEnabled) property is automatically coerced to `true`, so no additional configuration is necessary.
+
+> [!WARNING]
+> The `Click` event can bubble up from other controls hosted on a [SettingsCard](xref:@ActiproUIRoot.Controls.Views.SettingsCard), so always verify the source of the `Click` event before responding. For example, if a [SettingsCard](xref:@ActiproUIRoot.Controls.Views.SettingsCard) is configured with a `CheckBox` as the content, clicking the `CheckBox` will toggle the value *and* raise the `Click` event.
+
+The following code sample demonstrates how a [SettingsCard](xref:@ActiproUIRoot.Controls.Views.SettingsCard) can be configured to handle the `Click` event in XAML with the corresponding code-behind logic:
+
+@if (avalonia) {
+```xaml
+xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui"
+...
+
+```
+}
+@if (wpf) {
+```xaml
+xmlns:views="http://schemas.actiprosoftware.com/winfx/xaml/views"
+...
+
+```
+}
+```csharp
+// Code behind
+...
+private void OnSettingClick(object sender, RoutedEventArgs e) {
+ // Make sure the source of the Click is a SettingsCard since some Click
+ // events can bubble up from content hosted on the card (like a CheckBox)
+ if ((e.Source is SettingsCard) && (!e.Handled)) {
+ // Respond to click here
+ }
+}
+```
+
+## Indentation
+
+Not all settings will have a [HeaderIcon](xref:@ActiproUIRoot.Controls.Views.SettingsCard.HeaderIcon) or [ActionIcon](xref:@ActiproUIRoot.Controls.Views.SettingsCard.ActionIcon). When multiple settings are stacked vertically, it may be desirable to have consistent horizontal alignment of all the content areas within the individual settings. By setting [IsHeaderIconVisible](xref:@ActiproUIRoot.Controls.Views.SettingsCard.IsHeaderIconVisible) and/or [IsActionIconVisible](xref:@ActiproUIRoot.Controls.Views.SettingsCard.IsActionIconVisible) to `true`, the layout will reserve space for these elements even when a corresponding icon is not available. This results in all the settings having a consistent layout.
+
+@if (avalonia) {
+
+## Pseudo-classes
+
+The following pseudo-classes are available and can be used when styling the control:
+
+| Class | Description |
+| ----- | ----- |
+| `:wrapped` | Added when the `Content` (Editor) has wrapped due to the available width being less than or equal to the [WrapThreshold](xref:@ActiproUIRoot.Controls.SettingsCard.WrapThreshold) or when [IsWrapped](xref:@ActiproUIRoot.Controls.SettingsCard.IsWrapped) is set to `true`. |
+
+}
+
+@if (avalonia) {
+## Theme Resources
+
+The following theme resources are available for customizing the appearance of the control:
+
+| Theme Resource | Description |
+| ----- | ----- |
+| [Container1BackgroundBrush](xref:@ActiproUIRoot.Themes.ThemeResourceKind.Container1BackgroundBrush) | The default `Background`. |
+| [Container2BackgroundBrush](xref:@ActiproUIRoot.Themes.ThemeResourceKind.Container1BackgroundBrush) | The default `Background` of a clickable card when the mouse is over the control. |
+| [Container3BackgroundBrush](xref:@ActiproUIRoot.Themes.ThemeResourceKind.Container1BackgroundBrush) | The default `Background` of a clickable card when the control is pressed. |
+| [Container1BorderBrush](xref:@ActiproUIRoot.Themes.ThemeResourceKind.Container1BorderBrush) | The default `BorderBrush`. |
+| [Container2BorderBrush](xref:@ActiproUIRoot.Themes.ThemeResourceKind.Container1BorderBrush) | The default `BorderBrush` of a clickable card when the mouse is over the control. |
+| [Container3BorderBrush](xref:@ActiproUIRoot.Themes.ThemeResourceKind.Container1BorderBrush) | The default `BorderBrush` of a clickable card when the control is pressed. |
+| [SettingsCardBorderThickness](xref:@ActiproUIRoot.Themes.ThemeResourceKind.SettingsCardBorderThickness) | The default `BorderThickness`. |
+| [SettingsCardCornerRadius](xref:@ActiproUIRoot.Themes.ThemeResourceKind.SettingsCardCornerRadius) | The default `CornerRadius`. |
+| [DefaultFontSizeExtraSmall](xref:@ActiproUIRoot.Themes.ThemeResourceKind.DefaultFontSizeExtraSmall) | The default `FontSize` of the [Description](xref:@ActiproUIRoot.Controls.SettingsCard.Description) content. |
+| [DefaultForegroundBrush](xref:@ActiproUIRoot.Themes.ThemeResourceKind.DefaultForegroundBrush) | The default `Foreground`. |
+| [DefaultForegroundBrushTertiary](xref:@ActiproUIRoot.Themes.ThemeResourceKind.DefaultForegroundBrushTertiary) | The default `Foreground` of the [Description](xref:@ActiproUIRoot.Controls.SettingsCard.Description) content. |
+| [DefaultForegroundBrushDisabled](xref:@ActiproUIRoot.Themes.ThemeResourceKind.DefaultForegroundBrushDisabled) | The default `Foreground` when the control is disabled. |
+| [SettingsCardPadding](xref:@ActiproUIRoot.Themes.ThemeResourceKind.SettingsCardPadding) | The default `Padding`. |
+| [SettingsCardActionIconLength](xref:@ActiproUIRoot.Themes.ThemeResourceKind.SettingsCardActionIconLength) | The default `Width` and `Height` of the [ActionIcon](xref:@ActiproUIRoot.Controls.SettingsCard.ActionIcon). |
+| [SettingsCardHeaderIconLength](xref:@ActiproUIRoot.Themes.ThemeResourceKind.SettingsCardHeaderIconLength) | The default `Width` and `Height` of the [HeaderIcon](xref:@ActiproUIRoot.Controls.SettingsCard.HeaderIcon). |
+| [SettingsCardWrapThreshold](xref:@ActiproUIRoot.Themes.ThemeResourceKind.SettingsCardWrapThreshold) | The default [WrapThreshold](xref:@ActiproUIRoot.Controls.SettingsCard.WrapThreshold). |
+
+See the [Theme Assets](../../themes/theme-assets.md) topic for more details on working with theme resources.
+}
+@if (wpf) {
+## Theme Assets
+
+See the [Theme Reusable Assets](../../themes/reusable-assets.md) topic for more details on using and customizing theme assets. The following reusable assets are used by [SettingsCard](xref:@ActiproUIRoot.Controls.Views.SettingsCard):
+
+| Asset Resource Key | Description |
+|-----|-----|
+| [ContainerBackgroundLowestBrushKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.ContainerBackgroundLowestBrushKey) | The default `Background`. |
+| [ContainerBackgroundLowerBrushKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.ContainerBackgroundLowerBrushKey) | The default `Background` of a clickable card when the mouse is over the control. |
+| [ContainerBackgroundLowBrushKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.ContainerBackgroundLowBrushKey) | The default `Background` of a clickable card when the control is pressed. |
+| [ContainerBorderLowerBrushKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.ContainerBorderLowerBrushKey) | The default `BorderBrush`. |
+| [ContainerBorderLowBrushKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.ContainerBorderLowBrushKey) | The default `BorderBrush` of a clickable card when the mouse is over the control. |
+| [ContainerBorderMidLowBrushKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.ContainerBorderMidLowBrushKey) | The default `BorderBrush` of a clickable card when the control is pressed. |
+| [SettingsCardBorderNormalThicknessKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.SettingsCardBorderNormalThicknessKey) | The default `BorderThickness`. |
+| [SettingsCardBorderNormalCornerRadiusKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.SettingsCardBorderNormalCornerRadiusKey) | The default [CornerRadius](xref:@ActiproUIRoot.Controls.Views.SettingsCard.CornerRadius). |
+| [SmallFontSizeDoubleKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.SmallFontSizeDoubleKey) | The default `FontSize` of the [Description](xref:@ActiproUIRoot.Controls.Views.SettingsCard.Description) content. |
+| [ContainerForegroundLowestNormalBrushKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.ContainerForegroundLowestNormalBrushKey) | The default `Foreground`. |
+| [ContainerForegroundLowestSubtleBrushKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.ContainerForegroundLowestSubtleBrushKey) | The default `Foreground` of the [Description](xref:@ActiproUIRoot.Controls.Views.SettingsCard.Description) content. |
+| [ContainerForegroundLowestDisabledBrushKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.ContainerForegroundLowestDisabledBrushKey) | The default `Foreground` when the control is disabled. |
+| [SettingsCardPaddingNormalThicknessKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.SettingsCardPaddingNormalThicknessKey) | The default `Padding`. |
+| [SettingsCardActionIconLengthDoubleKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.SettingsCardActionIconLengthDoubleKey) | The default `Width` and `Height` of the [ActionIcon](xref:@ActiproUIRoot.Controls.Views.SettingsCard.ActionIcon). |
+| [SettingsCardHeaderIconLengthDoubleKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.SettingsCardHeaderIconLengthDoubleKey) | The default `Width` and `Height` of the [HeaderIcon](xref:@ActiproUIRoot.Controls.Views.SettingsCard.HeaderIcon). |
+| [SettingsCardWrapThresholdDoubleKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.SettingsCardWrapThresholdDoubleKey) | The default [WrapThreshold](xref:@ActiproUIRoot.Controls.Views.SettingsCard.WrapThreshold). |
+}
\ No newline at end of file
diff --git a/Documentation/topics/views/controls/settings-expander.md b/Documentation/topics/views/controls/settings-expander.md
new file mode 100644
index 00000000..3205a119
--- /dev/null
+++ b/Documentation/topics/views/controls/settings-expander.md
@@ -0,0 +1,390 @@
+---
+title: "SettingsExpander"
+page-title: "SettingsExpander - Views Controls"
+order: 6
+---
+# SettingsExpander
+
+The [SettingsCard](settings-card.md), [SettingsExpander](xref:@ActiproUIRoot.Controls.Views.SettingsExpander), and [SettingsGroup](settings-group.md) controls are used together to organize and present configurable settings.
+
+![Screenshot](../images/settings-examples.png)
+
+*SettingsCard and SettingsExpander displayed within a SettingsGroup*
+
+A [SettingsExpander](xref:@ActiproUIRoot.Controls.Views.SettingsExpander) has functionality similar to a [SettingsCard](settings-card.md) but can also be expanded to show additional child settings.
+
+![Screenshot](../images/settings-expander.png)
+
+*SettingsExpander with header, description, header icon, and ToggleSwitch content in the expanded state with two SettingsCard children*
+
+## Primary Content Areas
+
+The [SettingsExpander](xref:@ActiproUIRoot.Controls.Views.SettingsExpander) control is defined by multiple content areas:
+
+- [Header](xref:@ActiproUIRoot.Controls.Views.SettingsExpander.Header) - The primary label for the setting.
+- [Description](xref:@ActiproUIRoot.Controls.Views.SettingsExpander.Description) - An additional description for the setting.
+- [HeaderIcon](xref:@ActiproUIRoot.Controls.Views.SettingsExpander.HeaderIcon) - The primary icon for the setting.
+- `Content` (Editor) - The control used to edit the setting (e.g., `ToggleSwitch`, `ComboBox`).
+
+Each content area, including the icon, can optionally be set to any value supported by `ContentPresenter` and the layout will adjust to only show the areas where content is defined.
+
+> [!NOTE]
+> In some scenarios, content may not be automatically detected. For instance, if a `DataTemplate` is used to define content without setting the corresponding content property, the control will not know that content is available. Use the [IsHeaderVisible](xref:@ActiproUIRoot.Controls.Views.SettingsExpander.IsHeaderVisible), [IsDescriptionVisible](xref:@ActiproUIRoot.Controls.Views.SettingsExpander.IsDescriptionVisible), and [IsHeaderIconVisible](xref:@ActiproUIRoot.Controls.Views.SettingsExpander.IsHeaderIconVisible) properties to manually control the visibility of each content area.
+
+> [!TIP]
+> The [SettingsExpander](xref:@ActiproUIRoot.Controls.Views.SettingsExpander) control has all the same content areas as [SettingsCard](settings-card.md) *except* [ActionIcon](xref:@ActiproUIRoot.Controls.Views.SettingsCard.ActionIcon) since the expansion indicator is displayed in this area.
+
+### Header and Description
+
+The [Header](xref:@ActiproUIRoot.Controls.Views.SettingsExpander.Header) and [Description](xref:@ActiproUIRoot.Controls.Views.SettingsExpander.Description) are typically `string` values describing the setting, and both are optional. The following demonstrates how to create a [SettingsExpander](xref:@ActiproUIRoot.Controls.Views.SettingsExpander) with a header and description:
+
+@if (avalonia) {
+```xaml
+xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui"
+...
+
+```
+}
+@if (wpf) {
+```xaml
+xmlns:views="http://schemas.actiprosoftware.com/winfx/xaml/views"
+...
+
+```
+}
+
+Since both properties can be set to any content supported by `ContentPresenter`, either property can be configured with more complex content. The following example demonstrates how a hyperlink could be used as the [Description](xref:@ActiproUIRoot.Controls.Views.SettingsExpander.Description) @if (avalonia) { (using the [HyperlinkTextBlock](../../shared/controls/hyperlink-textblock.md) control) }:
+
+@if (avalonia) {
+```xaml
+xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui"
+...
+
+
+
+
+
+
+ ...
+
+
+```
+}
+@if (wpf) {
+```xaml
+xmlns:views="http://schemas.actiprosoftware.com/winfx/xaml/views"
+xmlns:themes="http://schemas.actiprosoftware.com/winfx/xaml/themes"
+...
+
+
+
+
+
+ Click here for more
+
+
+
+
+ ...
+
+
+```
+}
+
+### Header Icon
+
+The [SettingsExpander](xref:@ActiproUIRoot.Controls.Views.SettingsExpander) supports a [HeaderIcon](xref:@ActiproUIRoot.Controls.Views.SettingsExpander.HeaderIcon). This icon is displayed on the left side of the card with a default size of `24x24`. This icon is typically related to the value(s) defined by the setting. For example, a speaker icon might be used for a setting related to output sound volume.
+
+@if (wpf) {
+> [!TIP]
+> The [HeaderIconTemplateSelector](xref:@ActiproUIRoot.Controls.Views.SettingsExpander.HeaderIconTemplateSelector) is pre-configured with a default [ImageTemplateSelector](xref:@ActiproUIRoot.Controls.ImageTemplateSelector), so it supports `ImageSource` and `Geometry` data values. See the [Template Selectors](../../shared/windows-controls/template-selectors.md) topic for more details.
+}
+
+The following sample demonstrates using a @if (avalonia) { `PathIcon` }@if (wpf) { `Geometry` } for defining the icon, but any content supported by `ContentPresenter` can be used to define the icon (like `Image` or @if (avalonia) { [DynamicImage](../../shared/controls/dynamic-image.md) }@if (wpf) { [DynamicImage](../../shared/windows-controls/dynamicimage.md) } controls):
+
+@if (avalonia) {
+```xaml
+xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui"
+...
+
+
+
+
+
+
+
+ ...
+
+
+```
+}
+@if (wpf) {
+```xaml
+xmlns:views="http://schemas.actiprosoftware.com/winfx/xaml/views"
+...
+
+ ...
+
+```
+}
+
+### Content (Editor)
+
+In additional to organizing child settings, a [SettingsExpander](xref:@ActiproUIRoot.Controls.Views.SettingsExpander) may also use the `Content` property to present a control for an individual setting. Any content supported by `ContentPresenter` can be used, but a setting is typically defined by common controls like `CheckBox`, `ComboBox`, `Slider`, and `ToggleSwitch`.
+
+> [!IMPORTANT]
+> Unlike [SettingsCard](settings-card.md), the default property for [SettingsExpander](xref:@ActiproUIRoot.Controls.Views.SettingsExpander) is the `Items` collection and *not* the `Content`. Make sure the `Content` property is explicitly used when defining the control.
+
+The following demonstrates defining a [SettingsExpander](xref:@ActiproUIRoot.Controls.Views.SettingsExpander) that uses a `ToggleSwitch` control as the `Content`:
+
+@if (avalonia) {
+```xaml
+xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui"
+...
+
+
+
+
+
+
+
+
+
+```
+}
+@if (wpf) {
+```xaml
+xmlns:shared="http://schemas.actiprosoftware.com/winfx/xaml/shared"
+xmlns:views="http://schemas.actiprosoftware.com/winfx/xaml/views"
+...
+
+
+
+
+
+
+
+
+
+```
+}
+
+See the [SettingsCard](settings-card.md) topic for more examples on using different controls for settings.
+
+## Items (Child Settings)
+
+The [SettingsExpander](xref:@ActiproUIRoot.Controls.Views.SettingsExpander) is an `ItemsControl` that supports defining one or more [SettingsCard](settings-card.md) instances as child settings that are only displayed when the control is expanded.
+
+The following sample demonstrates defining a [SettingsExpander](xref:@ActiproUIRoot.Controls.Views.SettingsExpander) with multiple child settings and sets the [IsExpanded](xref:@ActiproUIRoot.Controls.Views.SettingsExpander.IsExpanded) property to `true` so the child settings are visible by default:
+
+@if (avalonia) {
+```xaml
+xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui"
+...
+
+
+
+ ...
+
+
+
+
+
+
+
+```
+}
+@if (wpf) {
+```xaml
+xmlns:shared="http://schemas.actiprosoftware.com/winfx/xaml/shared"
+xmlns:views="http://schemas.actiprosoftware.com/winfx/xaml/views"
+...
+
+
+
+ ...
+
+
+
+
+
+
+
+```
+}
+
+See the [SettingsCard](settings-card.md) topic for more details.
+
+### Indentation
+
+By default, child settings of a [SettingsExpander](xref:@ActiproUIRoot.Controls.Views.SettingsExpander) are indented by setting both [IsHeaderIconVisible](xref:@ActiproUIRoot.Controls.Views.SettingsCard.IsHeaderIconVisible) and [IsActionIconVisible](xref:@ActiproUIRoot.Controls.Views.SettingsCard.IsActionIconVisible) to `true`. This reserves space in the layout for the [HeaderIcon](xref:@ActiproUIRoot.Controls.Views.SettingsCard.HeaderIcon) and [ActionIcon](xref:@ActiproUIRoot.Controls.Views.SettingsCard.ActionIcon) even if those icons are not defined.
+
+To change this behavior, modify the @if (avalonia) { `ItemContainerTheme` }@if (wpf) { `ItemContainerStyle` } property as desired, like demonstrated in the following sample:
+
+@if (avalonia) {
+```xaml
+xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui"
+...
+
+
+
+
+
+
+
+
+
+
+
+
+```
+}
+@if (wpf) {
+```xaml
+xmlns:shared="http://schemas.actiprosoftware.com/winfx/xaml/shared"
+xmlns:themes="http://schemas.actiprosoftware.com/winfx/xaml/themes"
+xmlns:views="http://schemas.actiprosoftware.com/winfx/xaml/views"
+...
+
+
+
+
+
+
+
+
+
+```
+}
+
+## Items Header and Footer
+
+![Screenshot](../images/settings-expander-header-footer.png)
+
+*SettingsExpander showing ItemsHeader and ItemsFooter*
+
+[SettingsExpander](xref:@ActiproUIRoot.Controls.Views.SettingsExpander) allows for additional content to be displayed above and below the child settings. Any content supported by `ContentPresenter` can be defined in the [ItemsHeader](xref:@ActiproUIRoot.Controls.Views.SettingsExpander.ItemsHeader) or [ItemsFooter](xref:@ActiproUIRoot.Controls.Views.SettingsExpander.ItemsFooter).
+
+The following sample demonstrates adding an informational message in the [ItemsHeader](xref:@ActiproUIRoot.Controls.Views.SettingsExpander.ItemsHeader):
+
+@if (avalonia) {
+```xaml
+xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui"
+...
+
+
+
+ Any content can be displayed above the child settings
+
+
+
+
+
+```
+}
+@if (wpf) {
+```xaml
+xmlns:views="http://schemas.actiprosoftware.com/winfx/xaml/views"
+...
+
+
+
+ Any content can be displayed above the child settings
+
+
+
+
+
+```
+}
+
+> [!NOTE]
+> In some scenarios, content may not be automatically detected. For instance, if a `DataTemplate` is used to define content without setting the corresponding content property, the control will not know that content is available. Use the [IsItemsHeaderVisible](xref:@ActiproUIRoot.Controls.Views.SettingsExpander.IsItemsHeaderVisible) and [IsItemsFooterVisible](xref:@ActiproUIRoot.Controls.Views.SettingsExpander.IsItemsHeaderVisible) properties to manually control the visibility of each content area.
+
+## Wrapping
+
+![Screenshot](../images/settings-expander-wrapping.png)
+
+*SettingsExpander displayed in the unwrapped and wrapped states*
+
+If enough space is available, the `Content` (Editor) of the setting is displayed to the right of the [Header](xref:@ActiproUIRoot.Controls.Views.SettingsExpander.Header) and/or [Description](xref:@ActiproUIRoot.Controls.Views.SettingsExpander.Description) with default right alignment. When the width of the expander is less than or equal to the [WrapThreshold](xref:@ActiproUIRoot.Controls.Views.SettingsExpander.WrapThreshold), the `Content` will be wrapped to the bottom of the expander with default left alignment.
+
+Use the [IsWrapped](xref:@ActiproUIRoot.Controls.Views.SettingsExpander.IsWrapped) property to manually control wrap behavior. When set to `null` (the default), wrapping is based on the [WrapThreshold](xref:@ActiproUIRoot.Controls.Views.SettingsExpander.WrapThreshold). Set the property to `true` to force wrapping at any width, and `false` to prevent wrapping at any width.
+
+> [!NOTE]
+> Wrapping is only applicable if [Header](xref:@ActiproUIRoot.Controls.Views.SettingsExpander.Header) and/or [Description](xref:@ActiproUIRoot.Controls.Views.SettingsExpander.Description) are defined. Otherwise, the `Content` (Editor) will always be aligned left, by default.
+
+## Animation
+
+Fluent animation in the control is enabled by default but can be disabled by setting the [IsAnimationEnabled](xref:@ActiproUIRoot.Controls.Views.SettingsExpander.IsAnimationEnabled) property to `false`.
+
+@if (avalonia) {
+
+## Pseudo-classes
+
+The following pseudo-classes are available and can be used when styling the control:
+
+| Class | Description |
+| ----- | ----- |
+| `:expanded` | Added when the control is expanded. |
+| `:wrapped` | Added when the `Content` (Editor) has wrapped due to the available width being less than or equal to the [WrapThreshold](xref:@ActiproUIRoot.Controls.SettingsExpander.WrapThreshold) or when [IsWrapped](xref:@ActiproUIRoot.Controls.SettingsExpander.IsWrapped) is set to `true`. |
+}
+
+@if (avalonia) {
+## Theme Resources
+
+The following theme resources are available for customizing the appearance of the control:
+
+| Theme Resource | Description |
+| ----- | ----- |
+| [Container1BackgroundBrush](xref:@ActiproUIRoot.Themes.ThemeResourceKind.Container1BackgroundBrush) | The default `Background`. |
+| [Container2BackgroundBrush](xref:@ActiproUIRoot.Themes.ThemeResourceKind.Container1BackgroundBrush) | The default `Background` of a clickable card when the mouse is over the control. |
+| [Container3BackgroundBrush](xref:@ActiproUIRoot.Themes.ThemeResourceKind.Container1BackgroundBrush) | The default `Background` of a clickable card when the control is pressed. |
+| [Container1BorderBrush](xref:@ActiproUIRoot.Themes.ThemeResourceKind.Container1BorderBrush) | The default `BorderBrush`. |
+| [Container2BorderBrush](xref:@ActiproUIRoot.Themes.ThemeResourceKind.Container1BorderBrush) | The default `BorderBrush` of a clickable card when the mouse is over the control. |
+| [Container3BorderBrush](xref:@ActiproUIRoot.Themes.ThemeResourceKind.Container1BorderBrush) | The default `BorderBrush` of a clickable card when the control is pressed. |
+| [SettingsCardBorderThickness](xref:@ActiproUIRoot.Themes.ThemeResourceKind.SettingsCardBorderThickness) | The default `BorderThickness`. |
+| [SettingsCardCornerRadius](xref:@ActiproUIRoot.Themes.ThemeResourceKind.SettingsCardCornerRadius) | The default `CornerRadius`. |
+| [DefaultFontSizeExtraSmall](xref:@ActiproUIRoot.Themes.ThemeResourceKind.DefaultFontSizeExtraSmall) | The default `FontSize` of the [Description](xref:@ActiproUIRoot.Controls.SettingsExpander.Description) content. |
+| [DefaultForegroundBrush](xref:@ActiproUIRoot.Themes.ThemeResourceKind.DefaultForegroundBrush) | The default `Foreground`. |
+| [DefaultForegroundBrushTertiary](xref:@ActiproUIRoot.Themes.ThemeResourceKind.DefaultForegroundBrushTertiary) | The default `Foreground` of the [Description](xref:@ActiproUIRoot.Controls.SettingsExpander.Description) content. |
+| [DefaultForegroundBrushDisabled](xref:@ActiproUIRoot.Themes.ThemeResourceKind.DefaultForegroundBrushDisabled) | The default `Foreground` when the control is disabled. |
+| [SettingsCardPadding](xref:@ActiproUIRoot.Themes.ThemeResourceKind.SettingsCardPadding) | The default `Padding`. |
+| [SettingsCardHeaderIconLength](xref:@ActiproUIRoot.Themes.ThemeResourceKind.SettingsCardHeaderIconLength) | The default `Width` and `Height` of the [HeaderIcon](xref:@ActiproUIRoot.Controls.SettingsExpander.HeaderIcon). |
+| [SettingsCardWrapThreshold](xref:@ActiproUIRoot.Themes.ThemeResourceKind.SettingsCardWrapThreshold) | The default [WrapThreshold](xref:@ActiproUIRoot.Controls.SettingsExpander.WrapThreshold). |
+
+See the [Theme Assets](../../themes/theme-assets.md) topic for more details on working with theme resources.
+}
+@if (wpf) {
+## Theme Assets
+
+See the [Theme Reusable Assets](../../themes/reusable-assets.md) topic for more details on using and customizing theme assets. The following reusable assets are used by [SettingsExpander](xref:@ActiproUIRoot.Controls.Views.SettingsExpander):
+
+| Asset Resource Key | Description |
+|-----|-----|
+| [ContainerBackgroundLowestBrushKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.ContainerBackgroundLowestBrushKey) | The default `Background`. |
+| [ContainerBackgroundLowerBrushKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.ContainerBackgroundLowerBrushKey) | The default `Background` when the mouse is over the control. |
+| [ContainerBackgroundLowBrushKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.ContainerBackgroundLowBrushKey) | The default `Background` when the control is pressed. |
+| [ContainerBorderLowerBrushKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.ContainerBorderLowerBrushKey) | The default `BorderBrush`. |
+| [ContainerBorderLowBrushKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.ContainerBorderLowBrushKey) | The default `BorderBrush` when the mouse is over the control. |
+| [ContainerBorderMidLowBrushKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.ContainerBorderMidLowBrushKey) | The default `BorderBrush` when the control is pressed. |
+| [SettingsCardBorderNormalThicknessKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.SettingsCardBorderNormalThicknessKey) | The default `BorderThickness`. |
+| [SettingsCardBorderNormalCornerRadiusKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.SettingsCardBorderNormalCornerRadiusKey) | The default [CornerRadius](xref:@ActiproUIRoot.Controls.Views.SettingsExpander.CornerRadius). |
+| [SmallFontSizeDoubleKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.SmallFontSizeDoubleKey) | The default `FontSize` of the [Description](xref:@ActiproUIRoot.Controls.Views.SettingsExpander.Description) content. |
+| [ContainerForegroundLowestNormalBrushKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.ContainerForegroundLowestNormalBrushKey) | The default `Foreground`. |
+| [ContainerForegroundLowestSubtleBrushKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.ContainerForegroundLowestSubtleBrushKey) | The default `Foreground` of the [Description](xref:@ActiproUIRoot.Controls.Views.SettingsExpander.Description) content. |
+| [ContainerForegroundLowestDisabledBrushKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.ContainerForegroundLowestDisabledBrushKey) | The default `Foreground` when the control is disabled. |
+| [SettingsCardPaddingNormalThicknessKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.SettingsCardPaddingNormalThicknessKey) | The default `Padding`. |
+| [SettingsCardHeaderIconLengthDoubleKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.SettingsCardHeaderIconLengthDoubleKey) | The default `Width` and `Height` of the [HeaderIcon](xref:@ActiproUIRoot.Controls.Views.SettingsExpander.HeaderIcon). |
+| [SettingsCardWrapThresholdDoubleKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.SettingsCardWrapThresholdDoubleKey) | The default [WrapThreshold](xref:@ActiproUIRoot.Controls.Views.SettingsExpander.WrapThreshold). |
+}
\ No newline at end of file
diff --git a/Documentation/topics/views/controls/settings-group.md b/Documentation/topics/views/controls/settings-group.md
new file mode 100644
index 00000000..7e792db9
--- /dev/null
+++ b/Documentation/topics/views/controls/settings-group.md
@@ -0,0 +1,248 @@
+---
+title: "SettingsGroup"
+page-title: "SettingsGroup - Views Controls"
+order: 7
+---
+# SettingsGroup
+
+The [SettingsCard](settings-card.md), [SettingsExpander](settings-expander.md), and [SettingsGroup](xref:@ActiproUIRoot.Controls.Views.SettingsGroup) controls are used together to organize and present configurable settings.
+
+![Screenshot](../images/settings-examples.png)
+
+*SettingsCard and SettingsExpander displayed within a SettingsGroup*
+
+A [SettingsGroup](xref:@ActiproUIRoot.Controls.Views.SettingsGroup) is used to organize one or more [SettingsCard](settings-card.md) or [SettingsExpander](settings-expander.md) instances under an optional header.
+
+![Screenshot](../images/settings-group.png)
+
+*SettingsGroup with optional header and description displaying a SettingsCard and SettingsExpander as child settings*
+
+## Primary Content Areas
+
+The [SettingsGroup](xref:@ActiproUIRoot.Controls.Views.SettingsGroup) control is defined by multiple content areas:
+
+- [Header](xref:@ActiproUIRoot.Controls.Views.SettingsGroup.Header) - The primary label for the group.
+- [Description](xref:@ActiproUIRoot.Controls.Views.SettingsGroup.Description) - An additional description for the group.
+
+Each content area can optionally be set to any value supported by `ContentPresenter` and the layout will adjust to only show the areas where content is defined.
+
+> [!NOTE]
+> In some scenarios, content may not be automatically detected. For instance, if a `DataTemplate` is used to define content without setting the corresponding content property, the control will not know that content is available. Use the [IsHeaderVisible](xref:@ActiproUIRoot.Controls.Views.SettingsGroup.IsHeaderVisible) and [IsDescriptionVisible](xref:@ActiproUIRoot.Controls.Views.SettingsGroup.IsDescriptionVisible) properties to manually control the visibility of each content area.
+
+### Header and Description
+
+The [Header](xref:@ActiproUIRoot.Controls.Views.SettingsGroup.Header) and [Description](xref:@ActiproUIRoot.Controls.Views.SettingsGroup.Description) are typically `string` values describing the group, and both are optional. The following demonstrates how to create a [SettingsGroup](xref:@ActiproUIRoot.Controls.Views.SettingsGroup) with a header and description:
+
+@if (avalonia) {
+```xaml
+xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui"
+...
+
+
+
+
+
+```
+}
+@if (wpf) {
+```xaml
+xmlns:views="http://schemas.actiprosoftware.com/winfx/xaml/views"
+...
+
+
+
+
+
+```
+}
+
+## Items (Child Settings)
+
+The [SettingsGroup](xref:@ActiproUIRoot.Controls.Views.SettingsGroup) is an `ItemsControl` that supports defining one or more [SettingsCard](settings-card.md) or [SettingsExpander](settings-expander.md) instances as child settings that displayed within the group.
+
+The following sample demonstrates defining a [SettingsGroup](xref:@ActiproUIRoot.Controls.Views.SettingsGroup) with multiple child settings:
+
+@if (avalonia) {
+```xaml
+xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui"
+...
+
+
+
+ ...
+
+
+
+
+
+
+
+
+
+
+
+```
+}
+@if (wpf) {
+```xaml
+xmlns:shared="http://schemas.actiprosoftware.com/winfx/xaml/shared"
+xmlns:views="http://schemas.actiprosoftware.com/winfx/xaml/views"
+...
+
+
+
+ ...
+
+
+
+
+
+
+
+```
+}
+
+See the [SettingsCard](settings-card.md) and [SettingsExpander](settings-expander.md) topics for more details.
+
+### Spacing
+
+Each [SettingsCard](settings-card.md) or [SettingsExpander](settings-expander.md) within a group is automatically spaced out to improve visibility. Use the [Spacing](xref:@ActiproUIRoot.Controls.Views.SettingsGroup.Spacing) property to change the amount of spacing between each item.
+
+## Items Header and Footer
+
+![Screenshot](../images/settings-group-header-footer.png)
+
+*SettingsGroup showing ItemsHeader and ItemsFooter*
+
+[SettingsGroup](xref:@ActiproUIRoot.Controls.Views.SettingsGroup) allows for additional content to be displayed above and below the child settings. Any content supported by `ContentPresenter` can be defined in the [ItemsHeader](xref:@ActiproUIRoot.Controls.Views.SettingsGroup.ItemsHeader) or [ItemsFooter](xref:@ActiproUIRoot.Controls.Views.SettingsGroup.ItemsFooter).
+
+The following sample demonstrates adding an informational message in the [ItemsHeader](xref:@ActiproUIRoot.Controls.Views.SettingsGroup.ItemsHeader):
+
+@if (avalonia) {
+```xaml
+xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui"
+...
+
+
+
+
+ Any content can be displayed in the header
+
+
+
+
+
+
+```
+}
+@if (wpf) {
+```xaml
+xmlns:views="http://schemas.actiprosoftware.com/winfx/xaml/views"
+...
+
+
+
+
+
+ Any content can be displayed above the child settings
+
+
+
+
+
+
+```
+}
+
+> [!NOTE]
+> In some scenarios, content may not be automatically detected. For instance, if a `DataTemplate` is used to define content without setting the corresponding content property, the control will not know that content is available. Use the [IsItemsHeaderVisible](xref:@ActiproUIRoot.Controls.Views.SettingsGroup.IsItemsHeaderVisible) and [IsItemsFooterVisible](xref:@ActiproUIRoot.Controls.Views.SettingsGroup.IsItemsHeaderVisible) properties to manually control the visibility of each content area.
+
+## StackPanel and Margin
+
+The [SettingsGroup](xref:@ActiproUIRoot.Controls.Views.SettingsGroup) is designed to be stacked vertically within a `StackPanel` with minimal effort. As part of this design, each [SettingsGroup](xref:@ActiproUIRoot.Controls.Views.SettingsGroup) has a default `Margin` applied which includes spacing on the bottom. This will consistently separate one group from the group below it but does introduce extra spacing below the last item in a `StackPanel`. For many common layouts, this extra spacing may be inconsequential. If necessary, explicitly set the `Margin` of the last group to `0` to avoid the spacing.
+
+The following sample demonstrates a common layout for defining multiple groups:
+
+@if (avalonia) {
+```xaml
+xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui"
+...
+
+
+
+ ...
+
+
+
+ ...
+
+
+
+ ...
+
+
+
+```
+}
+@if (wpf) {
+```xaml
+xmlns:views="http://schemas.actiprosoftware.com/winfx/xaml/views"
+...
+
+
+
+ ...
+
+
+
+ ...
+
+
+
+ ...
+
+
+
+```
+}
+
+
+@if (avalonia) {
+## Theme Resources
+
+The following theme resources are available for customizing the appearance of the control:
+
+| Theme Resource | Description |
+| ----- | ----- |
+| [HeadingFontFamily](xref:@ActiproUIRoot.Themes.ThemeResourceKind.HeadingFontFamily) | The default `FontFamily` for the [Header](xref:@ActiproUIRoot.Controls.SettingsGroup.Header) content. |
+| [HeadingFontSizeExtraSmall](xref:@ActiproUIRoot.Themes.ThemeResourceKind.HeadingFontSizeExtraSmall) | The default `FontSize` for the [Header](xref:@ActiproUIRoot.Controls.SettingsGroup.Header) content. |
+| [DefaultFontSizeSmall](xref:@ActiproUIRoot.Themes.ThemeResourceKind.DefaultFontSizeSmall) | The default `FontSize` for the [Description](xref:@ActiproUIRoot.Controls.SettingsGroup.Description) content. |
+| [HeadingFontWeightExtraSmall](xref:@ActiproUIRoot.Themes.ThemeResourceKind.HeadingFontWeightExtraSmall) | The default `FontWeight` for the [Header](xref:@ActiproUIRoot.Controls.SettingsGroup.Header) content. |
+| [DefaultForegroundBrush](xref:@ActiproUIRoot.Themes.ThemeResourceKind.DefaultForegroundBrush) | The default `Foreground`. |
+| [DefaultForegroundBrushTertiary](xref:@ActiproUIRoot.Themes.ThemeResourceKind.DefaultForegroundBrushTertiary) | The default `Foreground` of the [Description](xref:@ActiproUIRoot.Controls.SettingsGroup.Description) content. |
+| [DefaultForegroundBrushDisabled](xref:@ActiproUIRoot.Themes.ThemeResourceKind.DefaultForegroundBrushDisabled) | The default `Foreground` when the control is disabled. |
+| [SettingsGroupMargin](xref:@ActiproUIRoot.Themes.ThemeResourceKind.SettingsGroupMargin) | The default `Margin`. |
+| [SettingsGroupPadding](xref:@ActiproUIRoot.Themes.ThemeResourceKind.SettingsGroupPadding) | The default `Padding`. |
+| [SettingsGroupSpacing](xref:@ActiproUIRoot.Themes.ThemeResourceKind.SettingsGroupSpacing) | The default [Spacing](xref:@ActiproUIRoot.Controls.SettingsGroup.Spacing). |
+
+See the [Theme Assets](../../themes/theme-assets.md) topic for more details on working with theme resources.
+}
+@if (wpf) {
+## Theme Assets
+
+See the [Theme Reusable Assets](../../themes/reusable-assets.md) topic for more details on using and customizing theme assets. The following reusable assets are used by [SettingsGroup](xref:@ActiproUIRoot.Controls.Views.SettingsGroup):
+
+| Asset Resource Key | Description |
+|-----|-----|
+| [ContainerForegroundLowestNormalBrushKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.ContainerForegroundLowestNormalBrushKey) | The default `Foreground`. |
+| [ContainerForegroundLowestSubtleBrushKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.ContainerForegroundLowestSubtleBrushKey) | The default `Foreground` of the [Description](xref:@ActiproUIRoot.Controls.Views.SettingsGroup.Description) content. |
+| [ContainerForegroundLowestDisabledBrushKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.ContainerForegroundLowestDisabledBrushKey) | The default `Foreground` when the control is disabled. |
+| [SettingsGroupMarginNormalThicknessKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.SettingsGroupMarginNormalThicknessKey) | The default `Margin`. |
+| [SettingsGroupPaddingNormalThicknessKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.SettingsGroupPaddingNormalThicknessKey) | The default `Padding`. |
+| [SettingsGroupSpacingDoubleKey](xref:@ActiproUIRoot.Themes.AssetResourceKeys.SettingsGroupSpacingDoubleKey) | The default [Spacing](xref:@ActiproUIRoot.Controls.Views.SettingsGroup.Spacing). |
+}
\ No newline at end of file
diff --git a/Documentation/topics/views/images/settings-card-wrapping.png b/Documentation/topics/views/images/settings-card-wrapping.png
new file mode 100644
index 00000000..b4654a1b
Binary files /dev/null and b/Documentation/topics/views/images/settings-card-wrapping.png differ
diff --git a/Documentation/topics/views/images/settings-card.png b/Documentation/topics/views/images/settings-card.png
new file mode 100644
index 00000000..95992331
Binary files /dev/null and b/Documentation/topics/views/images/settings-card.png differ
diff --git a/Documentation/topics/views/images/settings-examples.png b/Documentation/topics/views/images/settings-examples.png
new file mode 100644
index 00000000..0c429ef5
Binary files /dev/null and b/Documentation/topics/views/images/settings-examples.png differ
diff --git a/Documentation/topics/views/images/settings-expander-header-footer.png b/Documentation/topics/views/images/settings-expander-header-footer.png
new file mode 100644
index 00000000..8ed7ebb8
Binary files /dev/null and b/Documentation/topics/views/images/settings-expander-header-footer.png differ
diff --git a/Documentation/topics/views/images/settings-expander-wrapping.png b/Documentation/topics/views/images/settings-expander-wrapping.png
new file mode 100644
index 00000000..9a9bc16e
Binary files /dev/null and b/Documentation/topics/views/images/settings-expander-wrapping.png differ
diff --git a/Documentation/topics/views/images/settings-expander.png b/Documentation/topics/views/images/settings-expander.png
new file mode 100644
index 00000000..fa85061a
Binary files /dev/null and b/Documentation/topics/views/images/settings-expander.png differ
diff --git a/Documentation/topics/views/images/settings-group-header-footer.png b/Documentation/topics/views/images/settings-group-header-footer.png
new file mode 100644
index 00000000..95176708
Binary files /dev/null and b/Documentation/topics/views/images/settings-group-header-footer.png differ
diff --git a/Documentation/topics/views/images/settings-group.png b/Documentation/topics/views/images/settings-group.png
new file mode 100644
index 00000000..332859f2
Binary files /dev/null and b/Documentation/topics/views/images/settings-group.png differ
diff --git a/Documentation/topics/views/index.md b/Documentation/topics/views/index.md
index af2ddd32..cd920c10 100644
--- a/Documentation/topics/views/index.md
+++ b/Documentation/topics/views/index.md
@@ -7,11 +7,11 @@ order: 1
Actipro Views is a suite of controls and panels that supports fluid animations of the child elements arrangement. The controls offer stunning effects, life like interaction, and are highly configurable. Different animations can be applied to elements entering or leaving the panel, as well as elements simply moving to a new location or changing size. Several built-in animations are provided that allow elements to be smoothly moved, sized, faded, scaled, rotated, or translated.
-Several animated panels are provided, including drop-in replacements for `Canvas`, `DockPanel`, `StackPanel`, and `WrapPanel`. A "switch" panel is also included that delegates the layout of the child elements, which allows for the layout to be dynamically changed during runtime. Custom panels can be created that automatically support animation and can be used in the "switch" panel.
+![Screenshot](images/settings-examples.png)
-![Screenshot](images/taskboard-task-planning.png)
+Several controls are included such as those for building a settings interface (`SettingsCard`, `SettingsExpander`, and `SettingsGroup`), a `TaskBoard` for visually organizing tasks, `Book` for presenting a page turning interface, and `InertiaScrollViewer` for a smoothly animated variation of `ScrollViewer`.
-Other controls are included such as a `TaskBoard` for visually organizing tasks, `Book` for presenting a page turning interface, and `InertiaScrollViewer` for a smoothly animated variation of `ScrollViewer`.
+Animated panels are also provided, including drop-in replacements for `Canvas`, `DockPanel`, `StackPanel`, and `WrapPanel`. A "switch" panel is also included that delegates the layout of the child elements, which allows for the layout to be dynamically changed during runtime. Custom panels can be created that automatically support animation and can be used in the "switch" panel.
## Features
@@ -19,6 +19,7 @@ Other controls are included such as a `TaskBoard` for visually organizing tasks,
- [Book](controls/book.md) - An `ItemsControl` that presents the items as pages in a book.
- [InertiaScrollViewer](controls/inertia-scroll-viewer.md) - A smooth-scrolling `ScrollViewer`-like control that reacts to touch and continues gliding to a stop when flicked.
+- [SettingsCard](controls/settings-card.md), [Settings Expander](controls/settings-expander.md), and [SettingsGroup](controls/settings-group.md) - A collection of controls used together to organize and present configurable settings.
- [TaskBoard](controls/taskboard.md) - Provides a board of reorderable columns and cards.
### Built-in Panels
diff --git a/Samples/PrismIntegration/PrismIntegration.csproj b/Samples/PrismIntegration/PrismIntegration.csproj
index 26257c4d..f814956f 100644
--- a/Samples/PrismIntegration/PrismIntegration.csproj
+++ b/Samples/PrismIntegration/PrismIntegration.csproj
@@ -8,7 +8,7 @@
Actipro.ico
- 24.1.1.0
+ 24.1.2.0ActiproSoftware.Windows.PrismIntegrationActipro Software LLC
diff --git a/Samples/SampleBrowser/ActiproSoftware.References.props b/Samples/SampleBrowser/ActiproSoftware.References.props
index a9cd23ef..2a87475f 100644
--- a/Samples/SampleBrowser/ActiproSoftware.References.props
+++ b/Samples/SampleBrowser/ActiproSoftware.References.props
@@ -8,7 +8,7 @@
https://www.actiprosoftware.com/docs/controls/wpf/nuget
-->
- 24.1.1
+ 24.1.2
diff --git a/Samples/SampleBrowser/ProductSamples/BarsSamples/Common/BarManager.cs b/Samples/SampleBrowser/ProductSamples/BarsSamples/Common/BarManager.cs
index 972713ab..5239a5e6 100644
--- a/Samples/SampleBrowser/ProductSamples/BarsSamples/Common/BarManager.cs
+++ b/Samples/SampleBrowser/ProductSamples/BarsSamples/Common/BarManager.cs
@@ -358,6 +358,7 @@ private void RegisterControlViewModels() {
viewModels.Register(BarControlKeys.QuickStylesGallery, key
=> new BarGalleryViewModel(key, "Styles", SetTextStyleCommand, CreateTextStyleBarGalleryItemViewModelsCollection()) {
+ CanRibbonAutoScrollToSelectedItem = false,
CollapsedButtonDescription = "Styles give your document a consistent, polished look.",
ItemTemplateSelector = this.GalleryItemTemplateSelector,
KeyTipText = "L",
diff --git a/Samples/SampleBrowser/ProductSamples/BarsSamples/QuickStart/Backstage/MainWindow.xaml b/Samples/SampleBrowser/ProductSamples/BarsSamples/QuickStart/Backstage/MainWindow.xaml
index 703428de..e94103d4 100644
--- a/Samples/SampleBrowser/ProductSamples/BarsSamples/QuickStart/Backstage/MainWindow.xaml
+++ b/Samples/SampleBrowser/ProductSamples/BarsSamples/QuickStart/Backstage/MainWindow.xaml
@@ -20,7 +20,8 @@
-
@@ -206,37 +207,41 @@
+
-
-
+
+
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
- Label for third sample button:
-
+ Label for third sample button:
+
diff --git a/Samples/SampleBrowser/ProductSamples/BarsSamples/QuickStart/Backstage/MainWindow.xaml.cs b/Samples/SampleBrowser/ProductSamples/BarsSamples/QuickStart/Backstage/MainWindow.xaml.cs
index b8cba2be..0b618674 100644
--- a/Samples/SampleBrowser/ProductSamples/BarsSamples/QuickStart/Backstage/MainWindow.xaml.cs
+++ b/Samples/SampleBrowser/ProductSamples/BarsSamples/QuickStart/Backstage/MainWindow.xaml.cs
@@ -18,6 +18,7 @@ public partial class MainWindow : INotifyPropertyChanged {
private int backstageMinHeaderWidth = 0;
private int backstageMaxHeaderWidth = 300;
private bool canClose = true;
+ private bool canSelectFirstTabOnOpen = true;
private bool isBackstageOpen = true;
private bool isFirstBackstage = true;
private bool sampleButton3CanCloseBackstage = true;
@@ -140,6 +141,20 @@ public bool CanClose {
}
}
}
+
+ ///
+ /// Gets or sets if the first tab should be selected when the Backstage is opened.
+ ///
+ /// true if the first tab should be selected when the Backstage is opened; otherwise false.
+ public bool CanSelectFirstTabOnOpen {
+ get => canSelectFirstTabOnOpen;
+ set {
+ if (canSelectFirstTabOnOpen != value) {
+ canSelectFirstTabOnOpen = value;
+ NotifyPropertyChanged(nameof(CanSelectFirstTabOnOpen));
+ }
+ }
+ }
///
/// Gets or sets if the backstage is open.
diff --git a/Samples/SampleBrowser/ProductSamples/BarsSamples/QuickStart/Footer/MainControl.xaml b/Samples/SampleBrowser/ProductSamples/BarsSamples/QuickStart/Footer/MainControl.xaml
index 53d9b75f..ef147d63 100644
--- a/Samples/SampleBrowser/ProductSamples/BarsSamples/QuickStart/Footer/MainControl.xaml
+++ b/Samples/SampleBrowser/ProductSamples/BarsSamples/QuickStart/Footer/MainControl.xaml
@@ -33,9 +33,8 @@
Actipro Ribbon includes a built-in footer for displaying additional content below the Ribbon. The footer
can be set to any content and is great for tips or notifications.
- This sample has been configured with an
- image and a custom background color to draw attention to the message. By default, the footer will have the
- same background brush as the Quick Access Toolbar.
+ This sample has been configured with an image. The background color can be changed to draw attention to the message.
+ By default, the footer will have the same background brush as the Quick Access Toolbar.
The footer fully supports the Quick Access Toolbar displaying below the Ribbon.
diff --git a/Samples/SampleBrowser/ProductSamples/BarsSamples/QuickStart/Footer/OptionsViewModel.cs b/Samples/SampleBrowser/ProductSamples/BarsSamples/QuickStart/Footer/OptionsViewModel.cs
index e9ac32b3..32d47f1c 100644
--- a/Samples/SampleBrowser/ProductSamples/BarsSamples/QuickStart/Footer/OptionsViewModel.cs
+++ b/Samples/SampleBrowser/ProductSamples/BarsSamples/QuickStart/Footer/OptionsViewModel.cs
@@ -67,7 +67,7 @@ public Thickness Padding {
/// Gets or sets the location of the Quick Access Toolbar.
///
/// One of the values.
- [DisplayName("QAT Location")]
+ [DisplayName("QAT location")]
public RibbonQuickAccessToolBarLocation QuickAccessToolBarLocation {
get => qatLocation;
set {
diff --git a/Samples/SampleBrowser/ProductSamples/BarsSamples/QuickStart/Footer/SampleControlBase.cs b/Samples/SampleBrowser/ProductSamples/BarsSamples/QuickStart/Footer/SampleControlBase.cs
index 9436cebf..30473cbf 100644
--- a/Samples/SampleBrowser/ProductSamples/BarsSamples/QuickStart/Footer/SampleControlBase.cs
+++ b/Samples/SampleBrowser/ProductSamples/BarsSamples/QuickStart/Footer/SampleControlBase.cs
@@ -38,13 +38,13 @@ public SampleControlBase() {
///
/// A new .
private RibbonViewModel InitializeRibbonViewModels() {
- // The focus of this sample is the Ribbon Footer, so base the MVVM- and XAML-based samples
+ // The focus of this sample is the Ribbon Footer, so the MVVM- and XAML-based samples
// will reuse the same core Ribbon MVVM configuration for non-footer configuration to keep
// sample focused only on the footer configuration
- var ribbon = SampleViewModelFactory.CreateDefaultRichTextEditorRibbonWindowViewModel().Ribbon;
- ribbon.IsApplicationButtonVisible = false;
- ribbon.IsCollapsible = false;
- return ribbon;
+ var ribbonViewModel = SampleViewModelFactory.CreateDefaultRichTextEditorRibbonWindowViewModel().Ribbon;
+ ribbonViewModel.IsApplicationButtonVisible = false;
+ ribbonViewModel.IsCollapsible = false;
+ return ribbonViewModel;
}
///
diff --git a/Samples/SampleBrowser/ProductSamples/BarsSamples/QuickStart/Footer/SampleMvvmControl.xaml.cs b/Samples/SampleBrowser/ProductSamples/BarsSamples/QuickStart/Footer/SampleMvvmControl.xaml.cs
index 78e46d6f..f59e21d3 100644
--- a/Samples/SampleBrowser/ProductSamples/BarsSamples/QuickStart/Footer/SampleMvvmControl.xaml.cs
+++ b/Samples/SampleBrowser/ProductSamples/BarsSamples/QuickStart/Footer/SampleMvvmControl.xaml.cs
@@ -67,7 +67,7 @@ protected override void UpdateFooter() {
FooterViewModel.Padding = Options.Padding;
FooterViewModel.Kind = Options.FooterKind;
- // A footer is only visible with the RibbonViewModel.Footer property is populated
+ // A footer is only visible when the RibbonViewModel.Footer property is populated
Ribbon.Footer = Options.IsFooterVisible
? FooterViewModel
: null;
diff --git a/Samples/SampleBrowser/ProductSamples/BarsSamples/QuickStart/FooterInfoBar/MainControl.xaml b/Samples/SampleBrowser/ProductSamples/BarsSamples/QuickStart/FooterInfoBar/MainControl.xaml
new file mode 100644
index 00000000..134a4eaf
--- /dev/null
+++ b/Samples/SampleBrowser/ProductSamples/BarsSamples/QuickStart/FooterInfoBar/MainControl.xaml
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Actipro Ribbon includes a built-in footer for displaying additional content below the Ribbon. The footer
+ can be set to any content and is great for tips or notifications.
+
+ This sample has been configured with an InfoBar that allows for the configuration of multiple severity
+ levels, pre-defined or custom images, optional actions/content, and a close button.
+
+ Click the 'Close' button on the InfoBar to hide the MVVM or XAML sample footer. Use the corresponding
+ 'Show Footer' button to re-display the footer.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Samples/SampleBrowser/ProductSamples/BarsSamples/QuickStart/FooterInfoBar/OptionsViewModel.cs b/Samples/SampleBrowser/ProductSamples/BarsSamples/QuickStart/FooterInfoBar/OptionsViewModel.cs
new file mode 100644
index 00000000..f3061bb7
--- /dev/null
+++ b/Samples/SampleBrowser/ProductSamples/BarsSamples/QuickStart/FooterInfoBar/OptionsViewModel.cs
@@ -0,0 +1,93 @@
+using ActiproSoftware.Windows;
+using ActiproSoftware.Windows.Controls;
+using ActiproSoftware.Windows.Controls.Bars;
+using System.ComponentModel;
+using System.Windows;
+using System.Windows.Input;
+
+namespace ActiproSoftware.ProductSamples.BarsSamples.QuickStart.FooterInfoBar {
+
+ ///
+ /// Defines configurable options for this sample.
+ ///
+ public class OptionsViewModel : ObservableObjectBase {
+
+ private bool canClose = true;
+ private bool isIconVisible = true;
+ private Thickness padding = new Thickness(10, 5, 10, 5);
+ private RibbonQuickAccessToolBarLocation qatLocation = RibbonQuickAccessToolBarLocation.Below;
+ private InfoBarSeverity severity = InfoBarSeverity.Success;
+ private ICommand showFooterMvvmCommand;
+ private ICommand showFooterXamlCommand;
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+ // PUBLIC PROCEDURES
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ ///
+ /// Gets or sets if the info bar can be closed.
+ ///
+ /// true if the info bar can be closed; otherwise false.
+ public bool CanClose {
+ get => canClose;
+ set => SetProperty(ref canClose, value);
+ }
+
+ ///
+ /// Gets or sets if the info bar icon is visible.
+ ///
+ /// true if the info bar icon is visible; otherwise false.
+ public bool IsIconVisible {
+ get => isIconVisible;
+ set => SetProperty(ref isIconVisible, value);
+ }
+
+ ///
+ /// Gets or sets the padding for the info bar.
+ ///
+ /// A value.
+ public Thickness Padding {
+ get => padding;
+ set => SetProperty(ref padding, value);
+ }
+
+ ///
+ /// Gets or sets the location of the Quick Access Toolbar.
+ ///
+ /// One of the values.
+ [DisplayName("QAT location")]
+ public RibbonQuickAccessToolBarLocation QuickAccessToolBarLocation {
+ get => qatLocation;
+ set => SetProperty(ref qatLocation, value);
+ }
+
+ ///
+ /// Gets of sets the severity of the info bar.
+ ///
+ /// One of the values.
+ public InfoBarSeverity Severity {
+ get => severity;
+ set => SetProperty(ref severity, value);
+ }
+
+ ///
+ /// Gets or sets the command that will be executed to show the MVVM-based footer.
+ ///
+ /// An .
+ public ICommand ShowFooterMvvmCommand {
+ get => showFooterMvvmCommand;
+ set => SetProperty(ref showFooterMvvmCommand, value);
+ }
+
+ ///
+ /// Gets or sets the command that will be executed to show the XAML-based footer.
+ ///
+ /// An .
+ public ICommand ShowFooterXamlCommand {
+ get => showFooterXamlCommand;
+ set => SetProperty(ref showFooterXamlCommand, value);
+ }
+
+ }
+
+}
diff --git a/Samples/SampleBrowser/ProductSamples/BarsSamples/QuickStart/FooterInfoBar/SampleControlBase.cs b/Samples/SampleBrowser/ProductSamples/BarsSamples/QuickStart/FooterInfoBar/SampleControlBase.cs
new file mode 100644
index 00000000..0f4275cf
--- /dev/null
+++ b/Samples/SampleBrowser/ProductSamples/BarsSamples/QuickStart/FooterInfoBar/SampleControlBase.cs
@@ -0,0 +1,115 @@
+using ActiproSoftware.ProductSamples.BarsSamples.Common;
+using ActiproSoftware.Windows.Controls.Bars.Mvvm;
+using System.ComponentModel;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace ActiproSoftware.ProductSamples.BarsSamples.QuickStart.FooterInfoBar {
+
+ ///
+ /// Provides the base user control of shared logic for this sample that is extended for MVVM- and XAML-based samples.
+ ///
+ public abstract class SampleControlBase : UserControl {
+
+ #region Dependency Properties
+
+ public static readonly DependencyProperty OptionsProperty = DependencyProperty.Register(nameof(Options), typeof(OptionsViewModel), typeof(SampleControlBase), new PropertyMetadata(null, OnOptionsPropertyValueChanged));
+
+ #endregion Dependency Properties
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+ // OBJECT
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public SampleControlBase() {
+ // Initialize the Ribbon view models (used by both XAML and MVVM samples for the Ribbon configuration not related to the footer)
+ this.Ribbon = InitializeRibbonViewModels();
+ }
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+ // NON-PUBLIC PROCEDURES
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ ///
+ /// Occurs when the dependency property value has changed.
+ ///
+ /// The sender of the event.
+ /// The containing data related to this event.
+ private static void OnOptionsPropertyValueChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
+ => ((SampleControlBase)obj).OnOptionsPropertyValueChanged(e.OldValue as OptionsViewModel, e.NewValue as OptionsViewModel);
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+ // PUBLIC PROCEDURES
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ ///
+ /// Initializes the view models for ribbon.
+ ///
+ /// A new .
+ protected virtual RibbonViewModel InitializeRibbonViewModels() {
+ // The focus of this sample is the Ribbon Footer, so base the MVVM- and XAML-based samples
+ // will reuse the same core Ribbon MVVM configuration for non-footer configuration to keep
+ // sample focused only on the footer configuration
+ var ribbonViewModel = SampleViewModelFactory.CreateDefaultRichTextEditorRibbonWindowViewModel().Ribbon;
+ ribbonViewModel.IsApplicationButtonVisible = false;
+ ribbonViewModel.IsCollapsible = false;
+ return ribbonViewModel;
+ }
+
+ ///
+ /// Handles a change in one of the individual property values on .
+ ///
+ /// The sender of the event.
+ /// The event data.
+ protected virtual void OnOptionsPropertyChanged(object sender, PropertyChangedEventArgs args) {
+ if (Ribbon == null)
+ return;
+
+ // Synchronize the footer with current options
+ UpdateFooter();
+ }
+
+ ///
+ /// Handles a change in the dependency property value.
+ ///
+ /// The old value.
+ /// The new value.
+ protected virtual void OnOptionsPropertyValueChanged(OptionsViewModel oldValue, OptionsViewModel newValue) {
+ // Stop listening for changes
+ if (oldValue != null)
+ oldValue.PropertyChanged -= OnOptionsPropertyChanged;
+
+ // Listen for changes
+ if (newValue != null)
+ newValue.PropertyChanged += OnOptionsPropertyChanged;
+
+ // Synchronize the footer with current options
+ UpdateFooter();
+
+ }
+
+ ///
+ /// Gets or sets the options associated with this control.
+ ///
+ public OptionsViewModel Options {
+ get => (OptionsViewModel)GetValue(OptionsProperty);
+ set => SetValue(OptionsProperty, value);
+ }
+
+ ///
+ /// Gets the view model for the Ribbon control.
+ ///
+ /// A .
+ public RibbonViewModel Ribbon { get; private set; }
+
+ ///
+ /// Updates the footer based on the current sample options.
+ ///
+ protected virtual void UpdateFooter() { /* no op */ }
+
+ }
+
+}
diff --git a/Samples/SampleBrowser/ProductSamples/BarsSamples/QuickStart/FooterInfoBar/SampleMvvmControl.xaml b/Samples/SampleBrowser/ProductSamples/BarsSamples/QuickStart/FooterInfoBar/SampleMvvmControl.xaml
new file mode 100644
index 00000000..2a37be44
--- /dev/null
+++ b/Samples/SampleBrowser/ProductSamples/BarsSamples/QuickStart/FooterInfoBar/SampleMvvmControl.xaml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Samples/SampleBrowser/ProductSamples/BarsSamples/QuickStart/FooterInfoBar/SampleMvvmControl.xaml.cs b/Samples/SampleBrowser/ProductSamples/BarsSamples/QuickStart/FooterInfoBar/SampleMvvmControl.xaml.cs
new file mode 100644
index 00000000..9920d953
--- /dev/null
+++ b/Samples/SampleBrowser/ProductSamples/BarsSamples/QuickStart/FooterInfoBar/SampleMvvmControl.xaml.cs
@@ -0,0 +1,108 @@
+using ActiproSoftware.Windows.Controls.Bars.Mvvm;
+using ActiproSoftware.Windows.Input;
+using System.Windows;
+
+namespace ActiproSoftware.ProductSamples.BarsSamples.QuickStart.FooterInfoBar {
+
+ ///
+ /// Provides the user control for this sample that uses an MVVM-based ribbon configuration.
+ ///
+ public partial class SampleMvvmControl : SampleControlBase {
+
+ private RibbonFooterViewModel footerViewModel;
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+ // OBJECT
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public SampleMvvmControl() {
+ InitializeComponent();
+
+ // Configure this code-behind to be the view model for this sample
+ this.DataContext = this;
+ }
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+ // NON-PUBLIC PROCEDURES
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ ///
+ /// Gets the view model for the footer.
+ ///
+ /// A value.
+ private RibbonFooterViewModel FooterViewModel {
+ get {
+ if (footerViewModel is null) {
+ footerViewModel = new RibbonFooterViewModel() {
+
+ // The RibbonFooterInfoBarContentViewModel can be used to define a footer
+ // with features supported by the InfoBar control
+ Content = new RibbonFooterInfoBarContentViewModel() {
+ CanClose = Options?.CanClose ?? true,
+ IsIconVisible = Options?.CanClose ?? true,
+ Message = "Use an info bar for essential app messages",
+ Padding = Options?.Padding ?? new Thickness(),
+ Title = "InfoBar",
+ Severity = Options?.Severity ?? Windows.Controls.InfoBarSeverity.Information,
+ },
+
+ // Footer must not have padding so InfoBar can display edge-to-edge
+ Padding = new Thickness(),
+ };
+ }
+ return footerViewModel;
+ }
+ }
+
+ ///
+ /// Shows the footer.
+ ///
+ private void ShowFooter() {
+ // When the footer is closed the view model is cleared. Show the footer again
+ // by re-assigning the view model that defines the footer
+ Ribbon.Footer = this.FooterViewModel;
+ }
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+ // PUBLIC PROCEDURES
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ ///
+ protected override RibbonViewModel InitializeRibbonViewModels() {
+ var ribbonViewModel = base.InitializeRibbonViewModels();
+
+ // Initialize the ribbon with a footer already displayed
+ ribbonViewModel.Footer = this.FooterViewModel;
+
+ return ribbonViewModel;
+ }
+
+ ///
+ protected override void OnOptionsPropertyValueChanged(OptionsViewModel oldValue, OptionsViewModel newValue) {
+ // Configure the command to show the MVVM-based footer
+ if (newValue is not null)
+ newValue.ShowFooterMvvmCommand = new DelegateCommand
+ Themes
+
+
+ Shared
diff --git a/Samples/SampleBrowser/SampleBrowser/Models/ProductData.xaml b/Samples/SampleBrowser/SampleBrowser/Models/ProductData.xaml
index ed135ec8..d3b2016b 100644
--- a/Samples/SampleBrowser/SampleBrowser/Models/ProductData.xaml
+++ b/Samples/SampleBrowser/SampleBrowser/Models/ProductData.xaml
@@ -406,6 +406,7 @@
Summary="Advanced fluent ribbons, toolbars, menus and related controls">
+
@@ -426,6 +427,7 @@
+
@@ -703,10 +705,16 @@
+
+
+
+
+
+
@@ -717,6 +725,7 @@
+
@@ -834,7 +843,9 @@
+
+
@@ -849,12 +860,14 @@
+
+
diff --git a/Samples/SampleBrowser/SampleBrowser/ViewModels/ApplicationViewModel.cs b/Samples/SampleBrowser/SampleBrowser/ViewModels/ApplicationViewModel.cs
index 2c44efb3..d43faf23 100644
--- a/Samples/SampleBrowser/SampleBrowser/ViewModels/ApplicationViewModel.cs
+++ b/Samples/SampleBrowser/SampleBrowser/ViewModels/ApplicationViewModel.cs
@@ -77,11 +77,11 @@ public class ApplicationViewModel : ObservableObjectBase {
private const int MaximumSearchResults = 50;
- private const string DefaultSampleUri = null;
- // private const string DefaultSampleUri = "https://ActiproSoftware/SampleBrowser/Documents/ProductOverviews/Themes";
- // private const string DefaultSampleUri = "https://ActiproSoftware/ProductSamples/SharedSamples/QuickStart/AvatarIntro/MainControl";
+ private const string DefaultSampleUri = null;
+ // private const string DefaultSampleUri = "https://ActiproSoftware/SampleBrowser/Documents/ProductOverviews/Themes";
+ // private const string DefaultSampleUri = "https://ActiproSoftware/ProductSamples/ViewsSamples/Demo/ApplicationSettings/MainControl";
- private const string OnlineDocumentationUrl = "https://www.actiprosoftware.com/docs/controls/wpf/index";
+ private const string OnlineDocumentationUrl = "https://www.actiprosoftware.com/docs/controls/wpf/index";
/////////////////////////////////////////////////////////////////////////////////////////////////////
// OBJECT
@@ -157,8 +157,8 @@ private ProductItemInfo FindProductInfo(Uri uri) {
///
/// The file system path to the sample project's folder.
private static string GetSampleProjectPath() {
- var uri = new Uri(Assembly.GetEntryAssembly().GetName().CodeBase);
- var path = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(uri.LocalPath), @"..\..\.."));
+ var location = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
+ var path = Path.GetFullPath(Path.Combine(location, @"..\..\.."));
return path;
}
diff --git a/Samples/SampleBrowser/SampleBrowser/Views/ApplicationStyles.xaml b/Samples/SampleBrowser/SampleBrowser/Views/ApplicationStyles.xaml
index e0197eec..1eb35928 100644
--- a/Samples/SampleBrowser/SampleBrowser/Views/ApplicationStyles.xaml
+++ b/Samples/SampleBrowser/SampleBrowser/Views/ApplicationStyles.xaml
@@ -592,44 +592,55 @@
-
-
+
+
+
+
@@ -690,9 +701,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
diff --git a/Samples/WindowsWorkflowIntegration/WindowsWorkflowIntegration.csproj b/Samples/WindowsWorkflowIntegration/WindowsWorkflowIntegration.csproj
index 511feae0..69b453da 100644
--- a/Samples/WindowsWorkflowIntegration/WindowsWorkflowIntegration.csproj
+++ b/Samples/WindowsWorkflowIntegration/WindowsWorkflowIntegration.csproj
@@ -8,7 +8,7 @@
Actipro.ico
- 24.1.1.0
+ 24.1.2.0ActiproSoftware.Windows.WindowsWorkflowIntegrationActipro Software LLC
@@ -33,8 +33,8 @@
-
-
+
+
\ No newline at end of file
diff --git a/Source/Bars.Mvvm/Bars.Mvvm.csproj b/Source/Bars.Mvvm/Bars.Mvvm.csproj
index c369fa45..be915e59 100644
--- a/Source/Bars.Mvvm/Bars.Mvvm.csproj
+++ b/Source/Bars.Mvvm/Bars.Mvvm.csproj
@@ -8,9 +8,9 @@
Bars.MvvmActipro Bars MVVM (for WPF)Common view models, templates, and other types used when implementing Bars controls with MVVM (Model-View-ViewModel) patterns.
- Actipro UI Controls WPF XAML MVVM MMoodel View ViewModel Bars
+ Actipro UI Controls WPF XAML MVVM Model View ViewModel Bars
- 24.1.1.0
+ 24.1.2.0ActiproSoftwareActipro Software LLC
@@ -34,7 +34,7 @@
-
+
diff --git a/Source/Bars.Mvvm/Products/Bars.Mvvm/AssemblyInfo.cs b/Source/Bars.Mvvm/Products/Bars.Mvvm/AssemblyInfo.cs
index a9465fec..1a345539 100644
--- a/Source/Bars.Mvvm/Products/Bars.Mvvm/AssemblyInfo.cs
+++ b/Source/Bars.Mvvm/Products/Bars.Mvvm/AssemblyInfo.cs
@@ -46,5 +46,5 @@
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
-[assembly: AssemblyVersion("24.1.1.0")] // WPF
-[assembly: AssemblyInformationalVersion("24.1.1.0")] // WPF
+[assembly: AssemblyVersion("24.1.2.0")] // WPF
+[assembly: AssemblyInformationalVersion("24.1.2.0")] // WPF
diff --git a/Source/Bars.Mvvm/UI/Controls.Bars.Mvvm/TemplateSelectors/RibbonFooterContentTemplateSelector.cs b/Source/Bars.Mvvm/UI/Controls.Bars.Mvvm/TemplateSelectors/RibbonFooterContentTemplateSelector.cs
index 904c7c68..88d07933 100644
--- a/Source/Bars.Mvvm/UI/Controls.Bars.Mvvm/TemplateSelectors/RibbonFooterContentTemplateSelector.cs
+++ b/Source/Bars.Mvvm/UI/Controls.Bars.Mvvm/TemplateSelectors/RibbonFooterContentTemplateSelector.cs
@@ -20,6 +20,7 @@ public class RibbonFooterContentTemplateSelector : DataTemplateSelector {
public RibbonFooterContentTemplateSelector() {
var dictionary = BarsMvvmResourceDictionary.Instance;
+ this.InfoBarDataTemplate = dictionary[BarsMvvmResourceKeys.RibbonFooterContentInfoBarDataTemplate] as DataTemplate;
this.SimpleDataTemplate = dictionary[BarsMvvmResourceKeys.RibbonFooterContentSimpleDataTemplate] as DataTemplate;
}
@@ -30,10 +31,17 @@ public RibbonFooterContentTemplateSelector() {
///
public override DataTemplate SelectTemplate(object item, DependencyObject container)
=> item switch {
+ RibbonFooterInfoBarContentViewModel _ => this.InfoBarDataTemplate,
RibbonFooterSimpleContentViewModel _ => this.SimpleDataTemplate,
_ => base.SelectTemplate(item, container)
};
+ ///
+ /// Gets or sets the to use for a .
+ ///
+ /// The to use.
+ public DataTemplate InfoBarDataTemplate { get; set; }
+
///
/// Gets or sets the to use for a .
///
diff --git a/Source/Bars.Mvvm/UI/Controls.Bars.Mvvm/ViewModels/BarControls/BarGalleryViewModel.cs b/Source/Bars.Mvvm/UI/Controls.Bars.Mvvm/ViewModels/BarControls/BarGalleryViewModel.cs
index 22f6d36c..48222e32 100644
--- a/Source/Bars.Mvvm/UI/Controls.Bars.Mvvm/ViewModels/BarControls/BarGalleryViewModel.cs
+++ b/Source/Bars.Mvvm/UI/Controls.Bars.Mvvm/ViewModels/BarControls/BarGalleryViewModel.cs
@@ -20,6 +20,7 @@ public class BarGalleryViewModel : BarGalleryViewModelBase, IHasVariantImages {
private bool canCategorize = true;
private bool canFilter;
+ private bool canRibbonAutoScrollToSelectedItem;
private DataTemplate categoryHeaderTemplate;
private string collapsedButtonDescription;
private bool hasCategoryHeaders = true;
@@ -198,6 +199,23 @@ public bool CanFilter {
}
}
+ ///
+ /// Gets or sets whether to automatically scroll a ribbon gallery to the selected item on selection changes.
+ ///
+ ///
+ /// true if the ribbon gallery selected item should automatically be scrolled into view on selection changes; otherwise, false.
+ /// The default value is false.
+ ///
+ public bool CanRibbonAutoScrollToSelectedItem {
+ get => canRibbonAutoScrollToSelectedItem;
+ set {
+ if (canRibbonAutoScrollToSelectedItem != value) {
+ canRibbonAutoScrollToSelectedItem = value;
+ this.NotifyPropertyChanged(nameof(CanRibbonAutoScrollToSelectedItem));
+ }
+ }
+ }
+
///
/// Gets or sets a for category headers when categorization is enabled.
///
diff --git a/Source/Bars.Mvvm/UI/Controls.Bars.Mvvm/ViewModels/BarControls/RibbonControlGroupViewModel.cs b/Source/Bars.Mvvm/UI/Controls.Bars.Mvvm/ViewModels/BarControls/RibbonControlGroupViewModel.cs
index cd6a16a3..56f38fb0 100644
--- a/Source/Bars.Mvvm/UI/Controls.Bars.Mvvm/ViewModels/BarControls/RibbonControlGroupViewModel.cs
+++ b/Source/Bars.Mvvm/UI/Controls.Bars.Mvvm/ViewModels/BarControls/RibbonControlGroupViewModel.cs
@@ -42,10 +42,10 @@ public HorizontalAlignment HorizontalContentAlignment {
public ObservableCollection Items { get; } = new ObservableCollection();
///
- /// Gets or sets an that indicates how variant sizes should be applied to items.
+ /// Gets or sets an that indicates how variant sizes should be applied to items.
///
///
- /// An that indicates how variant sizes should be applied to items.
+ /// An that indicates how variant sizes should be applied to items.
/// The default value is .
///
public ItemVariantBehavior ItemVariantBehavior {
diff --git a/Source/Bars.Mvvm/UI/Controls.Bars.Mvvm/ViewModels/BarControls/RibbonFooterInfoBarContentViewModel.cs b/Source/Bars.Mvvm/UI/Controls.Bars.Mvvm/ViewModels/BarControls/RibbonFooterInfoBarContentViewModel.cs
new file mode 100644
index 00000000..d202589b
--- /dev/null
+++ b/Source/Bars.Mvvm/UI/Controls.Bars.Mvvm/ViewModels/BarControls/RibbonFooterInfoBarContentViewModel.cs
@@ -0,0 +1,166 @@
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media;
+
+namespace ActiproSoftware.Windows.Controls.Bars.Mvvm {
+
+ ///
+ /// Represents a view model for image and text content within a ribbon footer.
+ ///
+ public class RibbonFooterInfoBarContentViewModel : ObservableObjectBase {
+
+ private object action;
+ private DataTemplate actionTemplate;
+ private DataTemplateSelector actionTemplateSelector;
+ private bool canClose = true;
+ private object content;
+ private DataTemplate contentTemplate;
+ private DataTemplateSelector contentTemplateSelector;
+ private ImageSource iconSource;
+ private bool isIconVisible = true;
+ private string message;
+ private Thickness padding = new Thickness(10, 5, 10, 5);
+ private InfoBarSeverity severity = InfoBarSeverity.Information;
+ private string title;
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+ // PUBLIC PROCEDURES
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ ///
+ /// Gets or sets the optional action to be displayed in the info bar.
+ ///
+ /// The action.
+ public object Action {
+ get => action;
+ set => SetProperty(ref action, value);
+ }
+
+ ///
+ /// Gets or sets the used to display the .
+ ///
+ /// The used to display the .
+ public DataTemplate ActionTemplate {
+ get => actionTemplate;
+ set => SetProperty(ref actionTemplate, value);
+ }
+
+ ///
+ /// Gets or sets the that picks a used to display the .
+ ///
+ /// The that picks a used to display the .
+ public DataTemplateSelector ActionTemplateSelector {
+ get => actionTemplateSelector;
+ set => SetProperty(ref actionTemplateSelector, value);
+ }
+
+ ///
+ /// Gets or sets whether the info bar can be closed by the user.
+ ///
+ ///
+ /// true if the info bar can be closed; otherwise, false.
+ /// The default value is true.
+ ///
+ public bool CanClose {
+ get => canClose;
+ set => SetProperty(ref canClose, value);
+ }
+
+ ///
+ /// Gets or sets the that defines the icon.
+ ///
+ /// The that defines the icon.
+ public ImageSource IconSource {
+ get => iconSource;
+ set => SetProperty(ref iconSource, value);
+ }
+
+ ///
+ /// Gets or sets the optional content to be displayed in the info bar.
+ ///
+ /// The content.
+ public object Content {
+ get => content;
+ set => SetProperty(ref content, value);
+ }
+
+ ///
+ /// Gets or sets the used to display the .
+ ///
+ /// The used to display the .
+ public DataTemplate ContentTemplate {
+ get => contentTemplate;
+ set => SetProperty(ref contentTemplate, value);
+ }
+
+ ///
+ /// Gets or sets the that picks a used to display the .
+ ///
+ /// The that picks a used to display the .
+ public DataTemplateSelector ContentTemplateSelector {
+ get => contentTemplateSelector;
+ set => SetProperty(ref contentTemplateSelector, value);
+ }
+
+ ///
+ /// Gets or sets whether the icon is visible.
+ ///
+ ///
+ /// true if the icon should be visible; otherwise, false.
+ /// The default value is true.
+ ///
+ public bool IsIconVisible {
+ get => isIconVisible;
+ set => SetProperty(ref isIconVisible, value);
+ }
+
+ ///
+ /// Gets or sets the message content.
+ ///
+ /// The message content.
+ public string Message {
+ get => message;
+ set => SetProperty(ref message, value);
+ }
+
+ ///
+ /// Gets or sets the padding inside the control.
+ ///
+ ///
+ /// The padding inside the control.
+ /// The default value is 10,5.
+ ///
+ public Thickness Padding {
+ get => padding;
+ set => SetProperty(ref padding, value);
+ }
+
+ ///
+ /// Gets of sets the severity of the info bar.
+ ///
+ ///
+ /// One of the values.
+ /// The default value is .
+ ///
+ public InfoBarSeverity Severity {
+ get => severity;
+ set => SetProperty(ref severity, value);
+ }
+
+ ///
+ /// Gets or sets the title content.
+ ///
+ /// The title content.
+ public string Title {
+ get => title;
+ set => SetProperty(ref title, value);
+ }
+
+ ///
+ public override string ToString() {
+ return $"{this.GetType().FullName}[Title='{this.Title}']";
+ }
+
+ }
+
+}
diff --git a/Source/Bars.Mvvm/UI/Controls.Bars.Mvvm/ViewModels/BarControls/RibbonViewModel.cs b/Source/Bars.Mvvm/UI/Controls.Bars.Mvvm/ViewModels/BarControls/RibbonViewModel.cs
index e73d7024..a8d358c4 100644
--- a/Source/Bars.Mvvm/UI/Controls.Bars.Mvvm/ViewModels/BarControls/RibbonViewModel.cs
+++ b/Source/Bars.Mvvm/UI/Controls.Bars.Mvvm/ViewModels/BarControls/RibbonViewModel.cs
@@ -1,6 +1,8 @@
-using ActiproSoftware.Windows.Themes;
+using ActiproSoftware.Windows.Input;
+using ActiproSoftware.Windows.Themes;
using System.Collections.ObjectModel;
using System.Windows;
+using System.Windows.Input;
namespace ActiproSoftware.Windows.Controls.Bars.Mvvm {
@@ -12,6 +14,7 @@ public class RibbonViewModel : ObservableObjectBase {
private RibbonApplicationButtonViewModel applicationButton;
private RibbonBackstageViewModel backstage;
private bool canChangeLayoutMode = true;
+ private ICommand clearFooterCommand;
private Size collapseThresholdSize = new Size(270, 170);
private RibbonFooterViewModel footer;
private bool isApplicationButtonVisible = true;
@@ -46,6 +49,9 @@ public RibbonViewModel(RibbonLayoutMode layoutMode) {
this.userInterfaceDensity = (layoutMode == RibbonLayoutMode.Classic)
? UserInterfaceDensity.Compact
: UserInterfaceDensity.Spacious;
+
+ // Initialize the clear footer command
+ this.clearFooterCommand = new DelegateCommand(_ => this.Footer = null);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -96,7 +102,24 @@ public bool CanChangeLayoutMode {
}
}
}
-
+
+ ///
+ /// Gets or sets a command that, when invoked, will clear the footer.
+ ///
+ ///
+ /// An .
+ /// The default value is a command that sets the property to null.
+ ///
+ public ICommand ClearFooterCommand {
+ get => clearFooterCommand;
+ set {
+ if (clearFooterCommand != value) {
+ clearFooterCommand = value;
+ this.NotifyPropertyChanged(nameof(ClearFooterCommand));
+ }
+ }
+ }
+
///
/// Gets or sets the threshold that triggers a ribbon collapse if the ribbon is sized smaller than the threshold.
///
diff --git a/Source/Bars.Mvvm/UI/Controls.Bars.Mvvm/ViewModels/GalleryItems/FontSizeBarGalleryItemViewModel.cs b/Source/Bars.Mvvm/UI/Controls.Bars.Mvvm/ViewModels/GalleryItems/FontSizeBarGalleryItemViewModel.cs
index 594d9641..36ea9469 100644
--- a/Source/Bars.Mvvm/UI/Controls.Bars.Mvvm/ViewModels/GalleryItems/FontSizeBarGalleryItemViewModel.cs
+++ b/Source/Bars.Mvvm/UI/Controls.Bars.Mvvm/ViewModels/GalleryItems/FontSizeBarGalleryItemViewModel.cs
@@ -124,9 +124,7 @@ public static CollectionViewSource CreateDefaultCollectionViewSource(bool catego
/// The string category name.
public static string DefaultCategory => SR.GetString(SRName.UIGalleryItemCategoryFontSizesText);
- ///
///
- ///
public override bool IsLabelVisible => true;
///
diff --git a/Source/Bars.Mvvm/UI/Themes/BarsMvvmResourceDictionary.xaml b/Source/Bars.Mvvm/UI/Themes/BarsMvvmResourceDictionary.xaml
index 7ee81c96..b0548156 100644
--- a/Source/Bars.Mvvm/UI/Themes/BarsMvvmResourceDictionary.xaml
+++ b/Source/Bars.Mvvm/UI/Themes/BarsMvvmResourceDictionary.xaml
@@ -31,6 +31,7 @@
+
@@ -195,6 +196,7 @@
AboveMenuItems="{Binding AboveMenuItems}"
AreSurroundingSeparatorsAllowedOnMenu="{Binding AreSurroundingSeparatorsAllowed}"
BelowMenuItems="{Binding BelowMenuItems}"
+ CanAutoScrollToSelectedItem="{Binding CanRibbonAutoScrollToSelectedItem}"
CanCategorizeOnMenu="{Binding CanCategorize}"
CanCloneToRibbonQuickAccessToolBar="{Binding CanCloneToRibbonQuickAccessToolBar}"
CanFilterOnMenu="{Binding CanFilter}"
@@ -304,7 +306,7 @@
/>
-
+
@@ -354,7 +356,7 @@
-
+
-
+
+
+
+
+
/// Initializes the class.
///
static BarsMvvmResourceKeys() {
// Ensure the resources are registered in the app
- ThemeManager.RegisterThemeCatalog(nameof(BarsMvvmThemeCatalog), new BarsMvvmThemeCatalog());
+ ThemeManager.RegisterThemeCatalog(nameof(BarsMvvmThemeCatalog), new BarsMvvmThemeCatalog());
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -448,11 +449,18 @@ public static ResourceKey BarGalleryItemSymbolDataTemplate
/// A resource key.
public static ResourceKey BarGalleryItemTextStyleDataTemplate
=> (barGalleryItemTextStyleDataTemplate ??= new ComponentResourceKey(typeof(BarsMvvmResourceKeys), nameof(BarGalleryItemTextStyleDataTemplate)));
-
+
/////////////////////////////////////////////////////////////////////////////////////////////////////
// RESOURCE KEYS (RIBBON FOOTER CONTENT DATA TEMPLATES)
/////////////////////////////////////////////////////////////////////////////////////////////////////
-
+
+ ///
+ /// Gets the for an that may be applied to ribbon footer content.
+ ///
+ /// A resource key.
+ public static ResourceKey RibbonFooterContentInfoBarDataTemplate
+ => (ribbonFooterContentInfoBarDataTemplate ??= new ComponentResourceKey(typeof(BarsMvvmResourceKeys), nameof(RibbonFooterContentInfoBarDataTemplate)));
+
///
/// Gets the for an that may be applied to ribbon footer content.
///
diff --git a/Source/DataGrid.Contrib/DataGrid.Contrib.csproj b/Source/DataGrid.Contrib/DataGrid.Contrib.csproj
index fd42f6d7..ba086137 100644
--- a/Source/DataGrid.Contrib/DataGrid.Contrib.csproj
+++ b/Source/DataGrid.Contrib/DataGrid.Contrib.csproj
@@ -10,7 +10,7 @@
Common extensions, behaviors, and themes for the WPF DataGrid control.Actipro UI Controls WPF XAML DataGrid
- 24.1.1.0
+ 24.1.2.0ActiproSoftwareActipro Software LLC
@@ -34,7 +34,7 @@
-
+
diff --git a/Source/DataGrid.Contrib/Products/DataGrid/Contrib/AssemblyInfo.cs b/Source/DataGrid.Contrib/Products/DataGrid/Contrib/AssemblyInfo.cs
index 1bacb19b..e5a3d64d 100644
--- a/Source/DataGrid.Contrib/Products/DataGrid/Contrib/AssemblyInfo.cs
+++ b/Source/DataGrid.Contrib/Products/DataGrid/Contrib/AssemblyInfo.cs
@@ -52,8 +52,8 @@
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
-[assembly: AssemblyVersion("24.1.1.0")] // WPF
-[assembly: AssemblyInformationalVersion("24.1.1.0")] // WPF
+[assembly: AssemblyVersion("24.1.2.0")] // WPF
+[assembly: AssemblyInformationalVersion("24.1.2.0")] // WPF
namespace ActiproSoftware.Products.DataGrid.Contrib {
diff --git a/Source/Editors.Interop.DataGrid/Editors.Interop.DataGrid.csproj b/Source/Editors.Interop.DataGrid/Editors.Interop.DataGrid.csproj
index 61b3f3f3..f38fb2b8 100644
--- a/Source/Editors.Interop.DataGrid/Editors.Interop.DataGrid.csproj
+++ b/Source/Editors.Interop.DataGrid/Editors.Interop.DataGrid.csproj
@@ -10,7 +10,7 @@
Provides interoperability between Actipro's WPF Editors product and the WPF DataGrid.Actipro UI Controls WPF XAML Editors DataGrid
- 24.1.1.0
+ 24.1.2.0ActiproSoftwareActipro Software LLC
@@ -34,7 +34,7 @@
-
+
diff --git a/Source/Editors.Interop.DataGrid/Products/Editors.Interop.DataGrid/AssemblyInfo.cs b/Source/Editors.Interop.DataGrid/Products/Editors.Interop.DataGrid/AssemblyInfo.cs
index 96d5e9f9..70e4b15a 100644
--- a/Source/Editors.Interop.DataGrid/Products/Editors.Interop.DataGrid/AssemblyInfo.cs
+++ b/Source/Editors.Interop.DataGrid/Products/Editors.Interop.DataGrid/AssemblyInfo.cs
@@ -43,5 +43,5 @@
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
-[assembly: AssemblyVersion("24.1.1.0")] // WPF
-[assembly: AssemblyInformationalVersion("24.1.1.0")] // WPF
+[assembly: AssemblyVersion("24.1.2.0")] // WPF
+[assembly: AssemblyInformationalVersion("24.1.2.0")] // WPF