New to Telerik UI for WinForms? Download free 30-day trial

How to display screen tip on RadGridView using BackgroundWorker

Environment

Product Version Product Author
2022.1.222 RadGridView for WinForms Dinko Krastev

Solution

In the following example, we are going to display screentip in RadGridView using BackgroundWorker. We can create a class that derives from RadOffice2007ScreenTipElement. Inside the class, we can create our BackgroundWorker and subscribe to its DoWork and RunWorkerCompleted events. Then we should define a StartOperation method, which starts the BackgroundWorker instance. In addition, we can notify the user of the operation by changing the text of the MainTextLabel element.

gridview-async-screentip


public class AsyncRadOffice2007ScreenTipElement : RadOffice2007ScreenTipElement
{
    private BackgroundWorker backgroundWorker;

    public AsyncRadOffice2007ScreenTipElement()
    {
        this.backgroundWorker = new BackgroundWorker();
        this.backgroundWorker.DoWork += this.OnDoWork;
        this.backgroundWorker.RunWorkerCompleted += this.OnRunWorkerCompleted;
    }

    protected override Type ThemeEffectiveType
    {
        get { return typeof(RadOffice2007ScreenTipElement); }
    }

    public event DoWorkEventHandler OperationPerforming;

    protected virtual void OnOperationPerforming(DoWorkEventArgs e)
    {
        DoWorkEventHandler handler = this.OperationPerforming;

        if (handler != null)
        {
            handler(this, e);
        }
    }

    public event RunWorkerCompletedEventHandler OperationCompleted;

    protected virtual void OnOperationCompleted(RunWorkerCompletedEventArgs e)
    {
        RunWorkerCompletedEventHandler handler = this.OperationCompleted;

        if (handler != null)
        {
            handler(this, e);
        }
    }

    public void StartOperation(object arguments)
    {
        this.ResetVisualStyles();

        this.CaptionVisible = false;
        this.MainTextLabel.Text = "Loading content...";

        this.UpdateLayout();

        this.backgroundWorker.RunWorkerAsync(arguments);
    }

    private void ResetVisualStyles()
    {
        this.ResetValues(this.MainTextLabel);
        this.ResetValues(this.CaptionLabel);
        this.ResetValues(this.FooterTextLabel);
    }

    private void ResetValues(RadLabelElement element)
    {
        element.ResetValue(RadLabelElement.MarginProperty, ValueResetFlags.Local);
        element.ResetValue(RadLabelElement.ImageProperty, ValueResetFlags.Local);
        element.ResetValue(RadLabelElement.ImageAlignmentProperty, ValueResetFlags.Local);
        element.ResetValue(RadLabelElement.TextImageRelationProperty, ValueResetFlags.Local);
        element.ResetValue(RadLabelElement.TextProperty, ValueResetFlags.Local);
        element.ResetValue(RadLabelElement.MarginProperty, ValueResetFlags.Local);
    }

    protected override void DisposeManagedResources()
    {
        base.DisposeManagedResources();

        if (this.backgroundWorker != null)
        {
            this.backgroundWorker.Dispose();
            this.backgroundWorker = null;
        }
    }

    private void OnDoWork(object sender, DoWorkEventArgs e)
    {
        this.OnOperationPerforming(e);
    }

    private void OnRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        this.ResetVisualStyles();
        this.ResetValue(RadOffice2007ScreenTipElement.CaptionVisibleProperty, ValueResetFlags.Local);

        if (e.Cancelled || e.Error != null)
        {
            if (this.ElementTree != null)
            {
                this.ElementTree.Control.Hide();
            }
        }
        else
        {
            this.OnOperationCompleted(e);
        }
    }
}

What's left to use our async custom screentip and replace the default one. This can be done in the ScreenTipNeeded event handler of the RadGridView. Before you start the operation and pass the necessary arguments, we should subscribe to the OperationCompleted and OperationPerforming events. The first event occurs when the operation is completed and can be used to initialize the screen tip's UI by using the operation's result. The second event is the actual operation.


private void OnScreenTipNeeded(object sender, Telerik.WinControls.ScreenTipNeededEventArgs e)
{
    GridCellElement cellElement = e.Item as GridCellElement;

    if (cellElement != null)
    {
        AsyncRadOffice2007ScreenTipElement screenTip = new AsyncRadOffice2007ScreenTipElement();
        screenTip.OperationCompleted += this.OnScreenTipOperationCompleted;
        screenTip.OperationPerforming += this.OnScreenTipOperationPerforming;
        screenTip.MainTextLabel.LabelImage.ImageScaling = Telerik.WinControls.Enumerations.ImageScaling.SizeToFit;
        screenTip.MainTextLabel.LabelImage.ScaleSize = new Size(screenTip.MainTextLabel.LabelImage.ScaleSize.Width+100, screenTip.MainTextLabel.LabelImage.ScaleSize.Height);
        screenTip.EnableCustomSize = true;
        screenTip.StartOperation(3000);

        cellElement.ScreenTip = screenTip;
    }
}

private void OnScreenTipOperationPerforming(object sender, DoWorkEventArgs e)
{
    // Here you should perform the highly intensive and performance heavy operation
    int delay = (int)e.Argument;
    Thread.Sleep(delay);
    e.Result = String.Format("Operation completed {0}ms", delay);
}

private void OnScreenTipOperationCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    RadOffice2007ScreenTipElement screenTipElement = sender as RadOffice2007ScreenTipElement;
    screenTipElement.CaptionLabel.Text = "Operation finished!!!";           
    screenTipElement.MainTextLabel.Text = Convert.ToString(e.Result);
}

In this article