Dynamically Changing AFElement Icons in AFTreeView with Custom Images
Learn how to selectively change icons for AFElements in an AFTreeView, preserving default icons and ensuring consistent display with your own 20x16 pixel images.
Roshan Soni
Dynamically Changing AFElement Icons in AFTreeView with Custom Images
Customizing the visual representation of AFElements in the OSIsoft PI System's AFTreeView can be tremendously helpful for highlighting specific items or improving the overall user experience. One common request is to dynamically change the icon for particular AFElements at runtime, based on certain conditions. However, doing this while preserving the tree's default icons can present challenges. Let's walk through best practices for achieving this, based on real engineering questions and lessons learned.
The Challenge: Custom Icons without Losing Defaults
When trying to update the icon for certain nodes in AFTreeView, a naive approach might be to replace the existing ImageList with a new one containing custom icons. Unfortunately, this replaces all existing icons in the tree, leading to a loss of the default images that make PI AF intuitive to use.
The key, therefore, is to add your custom icons to the existing ImageList rather than replace it. This preserves all built-in icons while allowing you to reference your new images on specific nodes.
Step-by-Step Solution
1. Prepare Your Icon Image
The images used in AFTreeView should be 20x16 pixels (width x height). Using a different size (such as 24x24) can result in no icon being displayed or inconsistent formatting.
Bitmap image = new Bitmap(Properties.Resources.MyCustomIcon, new Size(20, 16));
2. Add the Custom Icon to the Existing ImageList
The AFTreeView's ImageList property gives you access to the collection of images. Add your new icon like this:
int prevLastIndex = afTreeView1.ImageList.Images.Count - 1;
afTreeView1.ImageList.Images.AddStrip(image);
Note: AddStrip is used for adding multi-frame bitmaps. For a single image, use Add instead:
afTreeView1.ImageList.Images.Add(image);
3. Update the Node’s Icon
To apply the custom icon to specific nodes based on runtime conditions, set the node’s ImageIndex and SelectedImageIndex to the index of your newly added icon:
treeNode.ImageIndex = prevLastIndex + 1; // Or the appropriate index
// To use the same icon when selected
treeNode.SelectedImageIndex = prevLastIndex + 1;
4. Tie Logic to Your Conditions
As the tree is built, or in response to a user action, evaluate the condition for each AFElement and assign the icon as needed.
foreach (TreeNode node in afTreeView1.Nodes)
{
if (ShouldHighlight(node))
{
node.ImageIndex = customIconIndex;
node.SelectedImageIndex = customIconIndex;
}
}
Additional Tips
- Avoid replacing the ImageList: Always add to the existing ImageList to preserve native icons.
- Keep image sizes consistent: Use 20x16 px for all your icons.
- Consider accessibility: Use icons with sufficient contrast and clarity for different backgrounds.
Conclusion
By working with the existing ImageList and setting the appropriate indices on each node, you can effectively highlight and distinguish AFElements in the AFTreeView. This approach provides flexibility to support dynamic requirements, guiding users' attention without compromising the familiar PI experience.
Looking for code samples or troubleshooting tips? Drop your challenges in the comments below!
Tags
About Roshan Soni
Expert in PI System implementation, industrial automation, and data management. Passionate about helping organizations maximize the value of their process data through innovative solutions and best practices.
No comments yet
Be the first to share your thoughts on this article.
Related Articles
Enhancing PI ProcessBook Trends with Banding and Zones: User Needs, Workarounds, and the Road Ahead
A look at the user demand for trend banding/zoning in OSIsoft PI ProcessBook, current VBA workarounds, UI challenges, and how future PI Vision releases aim to address these visualization needs.
Roshan Soni
Migrating PIAdvCalcFilVal Uptime Calculations from PI DataLink to PI OLEDB
Learn how to translate PI DataLink's PIAdvCalcFilVal advanced calculations—like counting uptime based on conditions—into efficient PI OLEDB SQL queries. Explore three practical approaches using PIAVG, PIINTERP, and PICOunt tables, and get tips for validation and accuracy.
Roshan Soni
Understanding PI Web API WebID Encoding: Can You Generate WebIDs Client-Side?
Curious about how PI Web API generates WebIDs and whether you can encode them client-side using GUIDs or paths? This article explores the encoding mechanisms, current documentation, and best practices for handling WebIDs in your applications.
Roshan Soni