windowsforms-devexpress-dot-xtraeditors-80edb00d.md
Allows you to customize and display an SVG image and enables end-user interaction with individual image elements.
Namespace : DevExpress.XtraEditors
Assembly : DevExpress.Utils.v25.2.dll
NuGet Packages : DevExpress.Utils, DevExpress.Wpf.Core
[DXLicenseWinForms]
public class SvgImageBox :
ControlBase,
ISupportInitialize,
ISvgImageBox,
ISupportDXSkinColors,
IContextItemCollectionOwner,
IContextItemCollectionOptionsOwner,
ISupportContextItemsCursor,
IToolTipControlClient,
ISupportToolTipsForm,
IXtraResizableControl
<DXLicenseWinForms>
Public Class SvgImageBox
Inherits ControlBase
Implements ISupportInitialize,
ISvgImageBox,
ISupportDXSkinColors,
IContextItemCollectionOwner,
IContextItemCollectionOptionsOwner,
ISupportContextItemsCursor,
IToolTipControlClient,
ISupportToolTipsForm,
IXtraResizableControl
Both the SvgImageBox and DevExpress.XtraEditors.PictureEdit controls can display SVG images. Compared to the PictureEdit, the SvgImageBox provides the following additional features:
You can specify an SVG image and its zoom mode at design time and runtime. Use the SvgImageBox.SvgImage and SvgImageBox.SizeMode properties.
svgImageBox1.SvgImage = DevExpress.Utils.Svg.SvgImage.FromFile("theater.svg");
svgImageBox1.SizeMode = DevExpress.XtraEditors.SvgImageSizeMode.Squeeze;
SvgImageBox1.SvgImage = DevExpress.Utils.Svg.SvgImage.FromFile("theater.svg")
SvgImageBox1.SizeMode = DevExpress.XtraEditors.SvgImageSizeMode.Squeeze
An SVG image typically consists of multiple elements, which can be of two types:
Image elements are presented by SvgImageItem class objects. If an SvgImageItem is a group element, its SvgImageItem.IsGroup setting returns true.
At design time, click the control’s smart tag and select Customize.
This action opens the control’s designer, which allows you to access the hierarchical structure of the image items and change their appearance settings and visibility.
To allow users to customize image items at runtime, you can open this customization dialog in code, as demonstrated below. Ensure your project references the DevExpress.XtraDialogs assembly.
using (var customizationForm = new DevExpress.Utils.Design.SvgImageBoxCustomizationForm(svgImageBox1)) {
if (customizationForm.ShowDialog(this) == DialogResult.OK) {
//...
}
}
Using customizationForm = New DevExpress.Utils.Design.SvgImageBoxCustomizationForm(svgImageBox1)
If customizationForm.ShowDialog(Me) = DialogResult.OK Then
'...
End If
End Using
Note
For information on how the SvgImageBox displays image elements defined via the “use” element, see the SvgImageItem.Id topic.
In code, you can access the image elements by iterating through the following item collections:
RootItems - Provides access to a collection of root (bottommost) SVG items. Each item in this collection is an SvgImageItem class object.
SvgImageItem.Items - Gets the current group’s children.
svgImageBox1.RootItems[0].Visible = false;
svgImageBox1.RootItems[7].Items[0].Visible = false;
svgImageBox1.RootItems[0].Visible = False
svgImageBox1.RootItems[7].Items[0].Visible = False
To access individual items in code, you first need to know an item’s identifier. The following properties can be helpful in this case.
SvgImageItem.Id - Gets or sets the item’s unique identifier. The SVG image format allows IDs to be assigned to items via the id attribute. SvgImageItems that correspond to elements with missing id attributes have their Id properties set to null.
SvgImageItem.Tag - Use this property to associate custom data with the item. If image items in the source SVG file have empty IDs, use the Tag property to specify custom IDs (when required).
Given that you know an item’s ID or Tag, you can find this item using the following API:
The following code searches for items whose IDs start with the “background_pressed” sub-string and then hides these items.
var items = svgImageBox1.FindItems(item => item.Id != null && item.Id.StartsWith("background_pressed"));
items.ForEach(item => item.Visible = false);
Dim items = SvgImageBox1.FindItems(Function(item) item.Id IsNot Nothing AndAlso item.Id.StartsWith("background_pressed"))
items.ForEach(Sub(item) item.Visible = False)
Use the following properties to customize items’ appearance settings in the normal, hovered and selected states.
SvgImageBox.ItemAppearance - The default appearance settings applied to all image items.
SvgImageItem.Appearance - A specific item’s appearance settings, which override the default appearance settings. You can customize the appearance settings of individual items in the Designer and in code.
The SvgImageBox control allows you to respond to the mouse cursor moving over image items. When the mouse cursor enters an image element’s path or bounds, this element becomes “hovered”.
Hovered elements can display tooltips. See this property for more information: SvgImageBox.ToolTipController.
You can access the currently hovered item with the SvgImageBox.HoveredItem property. To test whether the item is hovered, see SvgImageItem.Hovered.
Hovered elements are painted according to the appearance settings specified by the SvgImageBox.ItemAppearance.Hovered and SvgImageItem.Appearance.Hovered properties. These appearance settings are initially empty. Thus, hovered items are not highlighted by default.
svgImageBox1.ItemAppearance.Hovered.BorderColor = Color.FromArgb(255, 128, 128);
svgImageBox1.ItemAppearance.Hovered.BorderThickness = 1;
SvgImageBox1.ItemAppearance.Hovered.BorderColor = Color.FromArgb(255, 128, 128)
SvgImageBox1.ItemAppearance.Hovered.BorderThickness = 1
The following events fire when the mouse cursor moves over image items:
The SvgImageBox.ItemHitTestType property specifies whether to perform hit-testing by items’ graphical paths or bounding boxes. The property accepts the following values:
Precise - An item is detected when a point is within the item’s graphical path. Groups do not have visible contours, and, thus, they cannot be hit-tested and selected in this mode.
BoundingBox - An item is detected when a point is within the item’s bounding rectangle. Groups are hit-tested in this mode when a point is within a rectangle within which all child items lie. This hit-test mode allows groups to be hovered (HoveredItem) and selected.
Note
The SvgImageBox control initially allows users to hot-track and then select any primitive visual element (text, path objects, rectangles, etc.) with the mouse. In default Precise hit-test mode, groups are not hot-tracked and selected. See the SvgImageBox.QueryHoveredItem topic for an example of how to treat (hover over and select) groups and their inner visual primitives as a whole.
When a user clicks an item, it is automatically selected. There is no visual difference between selected and non-selected items, unless you specify distinct appearance settings for selected items via the SvgImageBox.ItemAppearance.Selected and/or SvgImageItem.Appearance.Selected property.
svgImageBox1.ItemAppearance.Selected.BorderColor = Color.FromArgb(192, 192, 255);
svgImageBox1.ItemAppearance.Selected.BorderThickness = 0.8F;
svgImageBox1.ItemAppearance.Selected.BorderColor = Color.FromArgb(192, 192, 255)
svgImageBox1.ItemAppearance.Selected.BorderThickness = 0.8F
The SvgImageBox control supports two selection modes (SvgImageBox.OptionsSelection.SelectionMode):
To access currently selected items, select/deselect items and respond to item selection changes, use the following API:
The following code locates and selects an item by its ID (SvgImageItem.Id).
var item1 = svgImageBox1.FindItemById("seat_12");
svgImageBox1.Selection.Add(item1);
Dim item1 = svgImageBox1.FindItemById("seat_12")
svgImageBox1.Selection.Add(item1)
Note
Groups are not selected by default when a user clicks within their bounds, since groups are not visual elements; they are just containers of visual primitives. If you need to treat (hover over and select) a group and its inner visual primitives as a whole, enable BoundingBox hit-test mode and handle the SvgImageBox.QueryHoveredItem event, as demonstrated in the example below.
The SvgImageBox control initially allows users to hover and select primitive visual elements (text, path objects, rectangles, etc.) with the mouse. This example prevents primitive elements from being hovered/selected. A user will be able to only hover and select entire groups. The example also shows how to access the selection in code.
Note
The complete sample code is available in the SvgImage Box module in the XtraEditors MainDemo.
Assume that an SVG image contains ‘seat’ image elements. Each ‘seat’ element is a group that consists of multiple elements (text, path objects and nested groups).
The structure of this image element is shown below:
To allow entire groups (seats) to be hovered and selected, use the following steps.
Enable the BoundingBox hit-test type via the SvgImageBox.ItemHitTestType property. This hit-test mode allows groups to be hit-tested, and thus hovered and selected.
Specify the appearance settings to paint the hovered and selected image elements.
Handle the SvgImageBox.QueryHoveredItem event. When a user hovers over an inner element of a ‘seat’ group, the QueryHoveredItem event handler sets the ‘seat’ group as hovered instead. If a user then clicks the hovered element with the mouse, this element (the ‘seat’ group) is selected.
Access selected elements (‘seat’ groups) with the SvgImageBox.Selection property
svgImageBox.ItemAppearance.Selected.FillColor = DevExpress.LookAndFeel.DXSkinColors.IconColors.Blue;
svgImageBox.ItemAppearance.Hovered.FillColor = DevExpress.LookAndFeel.DXSkinColors.IconColors.Blue;
svgImageBox.ItemHitTestType = DevExpress.XtraEditors.ItemHitTestType.BoundingBox;
//...
// SvgImageBox.QueryHoveredItem event handler.
void OnSvgImageBoxQueryHoveredItem(object sender, SvgImageQueryHoveredItemEventArgs e) {
if(e.HoveredItem != null && !CheckSeatId(e.HoveredItem))
e.HoveredItem = e.HoveredItem.FindAncestors(a => CheckSeatId(a)).FirstOrDefault();
}
bool CheckSeatId(SvgImageItem svgImageItem) {
return svgImageItem.Id != null && svgImageItem.Id.StartsWith("seat");
}
// SvgImageBox.SelectionChanged event handler.
// Access selected elements.
void OnSvgImageBoxSelectionChanged(object sender, EventArgs e) {
selectedItemsListBox.Items.Clear();
foreach(var item in svgImageBox.Selection) {
string itemDisplayName = string.Format("Seat number: {0}", ((string)item.Tag).ToUpper());
selectedItemsListBox.Items.Add(itemDisplayName);
}
}
svgImageBox.ItemHitTestType = DevExpress.XtraEditors.ItemHitTestType.BoundingBox
svgImageBox.ItemAppearance.Hovered.FillColor = DevExpress.LookAndFeel.DXSkinColors.IconColors.Blue
svgImageBox.ItemAppearance.Selected.FillColor = DevExpress.LookAndFeel.DXSkinColors.IconColors.Blue
'...
' SvgImageBox.QueryHoveredItem event handler.
Private Sub OnSvgImageBoxQueryHoveredItem(ByVal sender As Object, ByVal e As SvgImageQueryHoveredItemEventArgs) Handles svgImageBox.QueryHoveredItem
If e.HoveredItem IsNot Nothing AndAlso (Not CheckSeatId(e.HoveredItem)) Then
e.HoveredItem = e.HoveredItem.FindAncestors(Function(a) CheckSeatId(a)).FirstOrDefault()
End If
End Sub
Private Function CheckSeatId(ByVal svgImageItem As SvgImageItem) As Boolean
Return svgImageItem.Id IsNot Nothing AndAlso svgImageItem.Id.StartsWith("seat")
End Function
' SvgImageBox.SelectionChanged event handler.
' Access selected elements.
Private Sub OnSvgImageBoxSelectionChanged(ByVal sender As Object, ByVal e As EventArgs) Handles svgImageBox.SelectionChanged
selectedItemsListBox.Items.Clear()
For Each item In svgImageBox.Selection
Dim itemDisplayName As String = String.Format("Seat number: {0}", CStr(item.Tag).ToUpper())
selectedItemsListBox.Items.Add(itemDisplayName)
Next item
End Sub
You can find the complete sample code in the SvgImage Box module in the XtraEditors MainDemo.
The following events allow you to perform actions when an item is clicked and right-clicked:
The following example shows how to handle the SvgImageBox.PopupMenuShowing event to display a context menu for image items. The menu contains commands to hide and show image items.
private void svgImageBox1_PopupMenuShowing(object sender, DevExpress.XtraEditors.SvgImagePopupMenuShowingEventArgs e) {
SvgImageBox control = sender as SvgImageBox;
SvgImageItem item = e.Item;
// If you hover over a hidden item, the e.Item event parameter returns null.
// Use the GetItemsAt method to get a hidden item at the clicked point.
if (item == null)
item = control.GetItemsAt(e.Point).FirstOrDefault();
if (item == null) return;
string menuItemCaption = item.ActualVisible ? "Hide" : "Show";
DXMenuItem menuItem = new DXMenuCheckItem(menuItemCaption);
menuItem.Click += MenuItem_Click;
menuItem.Tag = item;
e.Menu.Items.Add(menuItem);
}
private void MenuItem_Click(object sender, EventArgs e) {
DXMenuItem menuItem = sender as DXMenuItem;
SvgImageItem item = menuItem.Tag as SvgImageItem;
item.Visible = !item.Visible;
}
Private Sub SvgImageBox1_PopupMenuShowing(sender As Object, e As DevExpress.XtraEditors.SvgImagePopupMenuShowingEventArgs) Handles SvgImageBox1.PopupMenuShowing
Dim control As SvgImageBox = TryCast(sender, SvgImageBox)
Dim item As SvgImageItem = e.Item
If item Is Nothing Then item = control.GetItemsAt(e.Point).FirstOrDefault()
If item Is Nothing Then Return
Dim menuItemCaption As String = If(item.ActualVisible, "Hide", "Show")
Dim menuItem As DXMenuItem = New DXMenuCheckItem(menuItemCaption)
AddHandler menuItem.Click, AddressOf MenuItem_Click
menuItem.Tag = item
e.Menu.Items.Add(menuItem)
End Sub
Private Sub MenuItem_Click(ByVal sender As Object, ByVal e As EventArgs)
Dim menuItem As DXMenuItem = TryCast(sender, DXMenuItem)
Dim item As SvgImageItem = TryCast(menuItem.Tag, SvgImageItem)
item.Visible = Not item.Visible
End Sub
Class
Object MarshalByRefObject Component Control DevExpress.XtraEditors.XtraControl ControlBase SvgImageBox
See Also