Question

I want to create an easy-to-use Loading overlay. For this I wanted to use Adorners. The problem is: I want to show a progress-circle. For this I need a control.

I tried to render the control, but I can't see anything:

        protected override void OnRender(DrawingContext drawingContext)
    {
        Size parentSize = this.AdornedElement.DesiredSize;

        drawingContext.DrawRectangle(new SolidColorBrush(Color.FromArgb((byte)(255 * 0.30), 0, 0, 0)), null,
            new Rect(0, 0, parentSize.Width, parentSize.Height));

        RenderTargetBitmap target = new RenderTargetBitmap(50, 50, 96, 96,
            PixelFormats.Pbgra32);
        target.Render(_ring);
        drawingContext.DrawImage(target,
            new Rect(parentSize.Width / 2 - target.Width / 2, parentSize.Height / 2 - target.Height / 2, target.Width, target.Height));

        double textUpperPos = parentSize.Height / 2 + target.Height / 2 + 10;
        target = new RenderTargetBitmap((int)parentSize.Width - 30, (int)parentSize.Height - (int)textUpperPos - 10, 96, 96,
            PixelFormats.Pbgra32);
        drawingContext.DrawImage(target,
            new Rect(parentSize.Width / 2 - target.Width / 2, textUpperPos, target.Width, target.Height));
    }

The gray background is visible, but none of the controls (TextBlock & ProgressCircle). Is this even possible using this method? Is there a better way?

I want an overlay which can be applied with max. 1-3 lines of code. Non-XAML.

Thanks :)

Was it helpful?

Solution 2

I recently found an article which was nearly not able to find via Google. It showed how to solve this problem (non-XAML way):

You have to use VisualCollection and ContentPresenter. Some minor additions and it work's perfect.

        public LoadingAdorner(UIElement adornedElement)
        : base(adornedElement)
    {
        if (DesignerProperties.GetIsInDesignMode(this)) return;

        _visuals = new VisualCollection(this);
        _contentPresenter = new ContentPresenter();
        _visuals.Add(_contentPresenter);

        _grid = new Grid
        {
            HorizontalAlignment = HorizontalAlignment.Stretch,
            VerticalAlignment = VerticalAlignment.Stretch
        };
        _contentPresenter.Content = _grid; // Or the single control you want to display

        // Add your controls here to grid
    }

    protected override int VisualChildrenCount
    {
        get { return _visuals.Count; }
    }

    protected override Visual GetVisualChild(int index)
    {
        return _visuals[index];
    }

    protected override Size MeasureOverride(Size constraint)
    {
        _contentPresenter.Measure(constraint);
        return _contentPresenter.DesiredSize;
    }

    protected override Size ArrangeOverride(Size finalSize)
    {
        _contentPresenter.Arrange(new Rect(0, 0, finalSize.Width, finalSize.Height));
        return _contentPresenter.RenderSize;
    }

OTHER TIPS

I have done some research for a similar solution.

You might find this article interesting:

http://www.codeproject.com/Articles/57984/WPF-Loading-Wait-Adorner

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top