In This Article

Icon Presenter

The IconPresenter class is a ContentPresenter specifically for presenting icons based on any object-based value. This class defines a DefaultContentTemplate that is automatically applied when an explicit ContentTemplate is unassigned.

Instead of forcing an icon to be based on an IImage, this approach allows any value to define an icon provided an appropriate IDataTemplate is also defined for non-visual values.

Tip

The default control theme for IconPresenter will set the DefaultContentTemplate to an instance of ImageDataTemplateSelector that is predefined to support IImage and GeometryStream value types in additional to custom logic for string values.

ImageDataTemplateSelector

The ImageDataTemplateSelector class is a special IDataTemplate that allows multiple child IDataTemplate definitions to be defined for each supported value Type. For a given value, the matching IDataTemplate will be determined based on the Type of that value, each inherited Type, or the Type of each implemented interface. If a match is not available, a DefaultTemplate can also be defined.

The following example demonstrates how to define an IDataTemplate that works for IImage and StreamGeometry value types:

xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui"
...

<actipro:ImageDataTemplateSelector>

	<DataTemplate x:DataType="IImage">
		<actipro:DynamicImage Source="{Binding}" />
	</DataTemplate>

	<DataTemplate x:DataType="StreamGeometry">
		<PathIcon Data="{Binding}" />
	</DataTemplate>

</actipro:ImageDataTemplateSelector>

Since IImage and StreamGeometry are common value types, the IDataTemplate entries defined above are available as static resources that can easily be reused. The following demonstrates how to update the above sample to resuse the default templates:

xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui"
...

<actipro:ImageDataTemplateSelector>

	<StaticResource ResourceKey="{x:Static actipro:ImageDataTemplateSelector.DefaultIImageDataTemplateKey}" />
	<StaticResource ResourceKey="{x:Static actipro:ImageDataTemplateSelector.DefaultStreamGeometryDataTemplateKey}" />

</actipro:ImageDataTemplateSelector>
Tip

It is highly recommended to resuse the existing IDataTemplate resources so that any future changes to the default templates will be automatically included in any custom implementations of ImageDataTemplateSelector.

Integration with Image Provider

When the ImageDataTemplateSelector attempts to select an IDataTemplate for a string value, it will first attempt to resolve an image from the default Image Provider (as defined by ImageProvider.Default) by calling the GetImageSource method overload that accepts a string value as a key. If a value is returned by the Image Provider, the IDataTemplate will be matched based on the Type of the returned value. If a value is not returned, a match will be attempted on the string data type.

Important

Image Provider can support loading relative and absolute resources using a string formatted as a path (e.g., "avares://MyAssembly/Images/Icons/MyIcon.png" or /Images/Icons/MyIcon.png). To support relative paths, a base Uri must be assigned to ImageProvider.RelativePathBaseUri or an exception will be thrown. Since only one base Uri can be defined, relatives paths can only be used with a single assembly.

Adding a Custom Icon Data Type

Adding global support for a custom icon data type is as simple as replacing the IconPresenter.DefaultContentTemplate property with one that defines an IDataTemplate for the custom type.

The following example defines an implicit Style for IconPresenter that updates the DefaultContentTemplate property with one that supports a custom value type. In this example, MyIconKind is expected to be an enum value type that identifies an icon, and MyIconControl is a Control that knows how to render the appropriate icon for the enum value.

<Application ...
	xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui"
	xmlns:controlsPrimitives="using:ActiproSoftware.UI.Avalonia.Controls.Primitives"
	xmlns:local="using:MyApplication.Namespace"
	>

	...

	<Application.Styles>

		<!-- Configure custom icon support -->
		<Style Selector="controlsPrimitives|IconPresenter">
			<Setter Property="DefaultContentTemplate">
				<actipro:ImageDataTemplateSelector>

					<!-- Reuse the pre-defined data templates -->
					<StaticResource ResourceKey="{x:Static actipro:ImageDataTemplateSelector.DefaultIImageDataTemplateKey}" />
					<StaticResource ResourceKey="{x:Static actipro:ImageDataTemplateSelector.DefaultStreamGeometryDataTemplateKey}" />

					<!-- Add a custom data template -->
					<DataTemplate x:DataType="local:MyIconKind">
						<local:MyIconControl Kind="{Binding}" />
					</DataTemplate>

				</actipro:ImageDataTemplateSelector>
			</Setter>
		</Style>

	</Application.Styles>

</Application>

Using Icon Presenter

The IconPresenter is a primitive that derives from ContentPresenter and should only be directly used within a ControlTheme, but options are available to easily take advantage of IconPresenter without using it directly.

ContentControl Theme

Use a ContentControl with the theme-icon-presenter class style name and a default template will be applied that uses IconPresenter instead of ContentPresenter.

The following example demonstrates how to use a ContentControl whose content is bound to a value type supported by IconPresenter:

<ContentControl Classes="theme-icon-presenter" Content="{Binding Icon}" />

IconControlConverter

The IconControlConverter is a value converter that can be used with bindings to effectively wrap the bound value as the content of a ContentControl that will use IconPresenter to present the value.

The following example demonstrates how to use IconControlConverter with the MenuItem.Icon property that expects a control as the value:

xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui"
...
<UserControl.Resources>
	<actipro:IconControlConverter x:Key="IconControlConverter" />
</UserControl.Resources>
...

<MenuItem Icon="{Binding Icon, Converter={StaticResource IconControlConverter}}" ... />