Siticone Logo
Siticone UI
DOCS
v2025.12.15
Docs Expressive Panel

Siticone Expressive Panel

The SiticoneExpressivePanel is a specialized container control designed to enhance perceived performance during data loading. Instead of displaying a blank screen or a simple spinner, it overlays a sophisticated Skeleton Loading animation (Shimmer or Pulse) over its child controls. It automatically generates "bones" based on the size and location of existing controls, creating a high-fidelity placeholder that matches your layout perfectly.

Loading Configuration

Properties that control the activation and style of the skeleton loading effect.

Property Type Description & Usage Example
IsLoading bool panel.IsLoading = true; The master switch for the control. When set to true, the skeleton overlay appears and the animation begins. When false, the overlay disappears, revealing the actual child controls.
AnimationMode ExpressivePanelAnimationMode panel.AnimationMode = ExpressivePanelAnimationMode.Shimmer; Determines the visual style of the loading effect.
  • Shimmer: A light gradient wipes across the bones (Standard Modern UI).
  • Pulse: The bones fade in and out of opacity.
AnimationInterval int panel.AnimationInterval = 20; The speed of the animation frame updates in milliseconds. Lower values create smoother but faster animations.

Appearance & Visuals

Customize the colors and geometry of the skeleton bones to match your application's theme.

Property Type Description & Usage Example
SkeletonColor Color panel.SkeletonColor = Color.FromArgb(224, 224, 224); The base background color of the skeleton bones (the inactive part).
HighlightColor Color panel.HighlightColor = Color.White; For Shimmer: The color of the moving gradient wipe.
For Pulse: The color the bones fade towards during the animation cycle.
BorderRadius int panel.BorderRadius = 4; The roundness of the bone corners in pixels. Set to 1 for sharp rectangles.
AutoCirclePictureBoxes bool panel.AutoCirclePictureBoxes = true; When true, automatically renders PictureBox and SiticonePictureBox controls as perfect circles (avatars), overriding the BorderRadius.

Virtual Mode

Virtual Mode allows the panel to display a loading animation even when there are no actual controls inside it. This is ideal for "List" or "Grid" scenarios where content is loaded dynamically and hasn't been created yet.

Property Type Description & Usage Example
UseVirtualMode bool panel.UseVirtualMode = true; If true, ignores child controls and instead draws a simulated list based on the properties below.
VirtualItemCount int panel.VirtualItemCount = 5; The number of fake rows/items to simulate drawing.
VirtualItemHeight int panel.VirtualItemHeight = 60; The vertical height allocated to each virtual row.

Public Methods

AddIgnoredControl(Control c)
// Marks a specific control to be ignored by the skeleton renderer.
// This control will not have a "bone" drawn over it, effectively making it invisible
// during the loading state.
public void SetupPanel()
{
                // Ignore the background label or divider
    expressivePanel1.AddIgnoredControl(lblTitleSeparator);
}
Use this to exclude decorative elements or containers that shouldn't appear in the loading skeleton.

Events

Events Wiring & Descriptions
// 1. StateChanged Event
// Fires whenever IsLoading is toggled. Useful for syncing UI status bars.
panel.StateChanged += (s, e) => 
{
    lblStatus.Text = e.IsLoading ? "Fetching Data..." : "Ready";
};

// 2. DrawBone Event
// Advanced: Fires before every single bone is drawn.
// Allows you to customize the geometry or color of specific items.
panel.DrawBone += (s, e) => 
{
                // Check which control is being drawn
                if (e.SourceControl == btnSubmit) 
    {
                // Draw a custom oval for the submit button instead of a rounded rect
        e.Graphics.FillEllipse(Brushes.LightGray, e.Bounds);
        
                // Tell the panel we handled the drawing, so it doesn't draw the default bone
        e.Handled = true;
    }
};

// 3. AnimationTick Event
// Fires on every timer tick (frame). Use sparingly for complex logic.
panel.AnimationTick += (s, e) => 
{
                // Custom logic per frame
};

Detailed Usage Examples

Example 1: Basic Data Loading

The most common use case: covering a form while fetching data asynchronously.

C# - Async Data Load
private async void LoadUserProfile_Click(object sender, EventArgs e)
{
                // 1. Start the Skeleton Loading Effect
    userProfilePanel.AnimationMode = ExpressivePanelAnimationMode.Shimmer;
    userProfilePanel.IsLoading = true;

                try
    {
                // 2. Simulate heavy network task (2 seconds)
                var userData = await UserRepository.GetByIdAsync(currentUserId);
        
                // 3. Populate the UI controls (which are currently hidden by the skeleton)
        lblUsername.Text = userData.Name;
        lblEmail.Text = userData.Email;
        picAvatar.Image = userData.ProfileImage;
    }
                finally
    {
                // 4. Turn off loading to reveal the populated controls
        userProfilePanel.IsLoading = false;
    }
}

Example 2: Virtual Mode (Simulating Lists)

Use this when the panel is empty at start-up, but you want to imply that a list of items is about to appear. Virtual Mode draws a standardized "Avatar + Title + Subtitle" layout repeatedly.

C# - Virtual List Simulation
public void InitializeListLoader()
{
                // Configure Virtual Mode settings
    expressivePanel1.UseVirtualMode = true;
    expressivePanel1.VirtualItemCount = 6;      // Draw 6 fake rows
    expressivePanel1.VirtualItemHeight = 70;    // Each row is 70px tall
    
                // Styling
    expressivePanel1.SkeletonColor = Color.FromArgb(240, 240, 240);
    expressivePanel1.HighlightColor = Color.White;
    
                // Start loading immediately
    expressivePanel1.IsLoading = true;
    
                // Fetch data...
                LoadDataAsync();
}

private async void LoadDataAsync()
{
                await Task.Delay(1500);
    
                // Important: Disable Virtual Mode when real controls are added
    expressivePanel1.UseVirtualMode = false;
    expressivePanel1.IsLoading = false;
    
                // Add real controls to the panel here...
}

Example 3: Dark Mode Configuration

Skeleton loading looks different in dark mode. The bones need to be lighter than the background, but not too bright.

C# - Dark Theme Setup
private void ApplyDarkTheme()
{
                // Panel background is dark
    expressivePanel1.BackColor = Color.FromArgb(30, 30, 30);
    
                // Bones should be slightly lighter than background
    expressivePanel1.SkeletonColor = Color.FromArgb(45, 45, 45);
    
                // Shimmer highlight should be even lighter to stand out
    expressivePanel1.HighlightColor = Color.FromArgb(60, 60, 60);
    
                // Use Pulse animation for a more subtle effect in dark mode
    expressivePanel1.AnimationMode = ExpressivePanelAnimationMode.Pulse;
    expressivePanel1.AnimationInterval = 25;
}

Enumerations

ExpressivePanelAnimationMode Enum
public enum ExpressivePanelAnimationMode
{
                // A linear gradient wipe effect (classic "Shimmer").
                // Best for high-contrast loading states.
    Shimmer,
    
                // Opacity fading in and out.
                // Best for subtle, less distracting loading states.
    Pulse
}