Skip to main content
PI AF SDK
PI System Development
UI Customization

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

4 min read

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

#PI AF SDK
#C#
#AFElement
#AFTreeView
#Custom Icon
#ImageList

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.

Sign in to comment

Join the conversation by signing in to your account.

Comments (0)

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

    Dynamically Changing AFElement Icons in AFTreeView with Custom Images | Pisharp Blog | PISharp