Bug 56914 - Specifying BackgroundColor colors Frame outside the outline
Summary: Specifying BackgroundColor colors Frame outside the outline
Status: CONFIRMED
Alias: None
Product: Forms
Classification: Xamarin
Component: Windows (show other bugs)
Version: 2.3.4
Hardware: PC Windows
: Normal normal
Target Milestone: ---
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2017-05-27 13:08 UTC by ewi.b
Modified: 2018-03-25 00:13 UTC (History)
10 users (show)

Tags: uwp, frame, borderradius, backgroundcolor, ac
Is this bug a regression?: ---
Last known good build:


Attachments
Screenshots (19.74 KB, image/png)
2017-05-27 13:08 UTC, ewi.b
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report for Bug 56914 on Developer Community or GitHub if you have new information to add and do not yet see a matching new report.

If the latest results still closely match this report, you can use the original description:

  • Export the original title and description: Developer Community HTML or GitHub Markdown
  • Copy the title and description into the new report. Adjust them to be up-to-date if needed.
  • Add your new information.

In special cases on GitHub you might also want the comments: GitHub Markdown with public comments

Related Links:
Status:
CONFIRMED

Description ewi.b 2017-05-27 13:08:32 UTC
Created attachment 22528 [details]
Screenshots

Whenever I try to make a Frame with rounded corners, the Frame is colored outside the outline, too.
When I check the Live Visual Tree during runtime, it seems like on UWP Frame renders a Border inside of a Panel.
The issue is caused by only the Panel being colored. When changing Panel's Background in Live Visual Tree to Transparent, the Border is also colored Transparent.

However, if I define a custom Renderer for Frame, it will behave differently. In this case I only do "base.OnElementChanged(e)" and set Control's Background to my specified color. It still also colors the Panel, where the Border is in, but if I change Panel's Background to Transparent in LVT, it shows up as expected.
(I would work around this, if I knew how to access this specific Panel during runtime from code.)

In XAML:
<StackLayout>
    <Frame HeightRequest="200" BackgroundColor="Orange" OutlineColor="Green" CornerRadius="20">
        <Label Text="Default Renderer"></Label>
    </Frame>
    <local:MyFrame HeightRequest="200" BackgroundColor="Orange"  OutlineColor="Green" CornerRadius="20">
        <Label Text="Custom Renderer"></Label>
    </local:MyFrame>
</StackLayout>

In MyFrameRenderer:
protected override void OnElementChanged(ElementChangedEventArgs<Frame> e)
{
    base.OnElementChanged(e);
    if(Control != null)
    {
        var nativeControl = (Windows.UI.Xaml.Controls.Border)Control;
        var panel = nativeControl.Parent as Windows.UI.Xaml.Controls.Panel;
        var color = e.NewElement.BackgroundColor;
        var nativeColor = Windows.UI.Color.FromArgb (
                                                     (byte)(color.A * 255),
                                                     (byte)(color.R * 255),
                                                     (byte)(color.G * 255),
                                                     (byte)(color.B * 255));
        nativeControl.Background = new Windows.UI.Xaml.Media.SolidColorBrush(nativeColor);
    }
}
Comment 1 ewi.b 2017-05-27 13:12:19 UTC
Sorry, forgot to delete this line:
        var panel = nativeControl.Parent as Windows.UI.Xaml.Controls.Panel;

It's unnecessary. Tried to access the above Panel, but returns null, because Renderer is set as Parent...
Comment 2 Paul DiPietro [MSFT] 2017-06-01 16:25:50 UTC
Setting to confirmed for now until further investigation. Still occurs on 2.3.5-pre3.
Comment 3 ewi.b 2017-06-02 08:36:56 UTC
It almost looks like UpdateBackground() in VisualElementRenderer causes this issue.

protected virtual void UpdateBackgroundColor()

{

	Color backgroundColor = Element.BackgroundColor;

	var control = Control as Control;

	if (control != null)

	{

		if (!backgroundColor.IsDefault)

		{

			control.Background = backgroundColor.ToBrush();

		}

		else

		{

			control.ClearValue(Windows.UI.Xaml.Controls.Control.BackgroundProperty);

		}

	}

	else

	{

		if (!backgroundColor.IsDefault)

		{

			Background = backgroundColor.ToBrush();

		}

		else

		{

			ClearValue(BackgroundProperty);

		}

	}

}

The Panel's coloring is caused by the control being null when this method is called.
It seems to be called in ViewRenderer's OnElementChanged(e). When I override UpdateBackground() in my custom renderer, it's called once with Control being null.

Finally, I was able to fix this in my custom renderer, this is the full Code:

using SpareTime;
using SpareTime.UWP;
using Xamarin.Forms.Platform.UWP;
using Xamarin.Forms;

[assembly: ExportRenderer(typeof(MyFrame), typeof(MyFrameRenderer))]
namespace SpareTime.UWP
{
    class MyFrameRenderer : FrameRenderer
    {
        private Color backgroundColor;
        protected override void OnElementChanged(ElementChangedEventArgs<Frame> e)
        {
            base.OnElementChanged(e);
            if(Control != null)
            {
                backgroundColor = e.NewElement.BackgroundColor;
                UpdateBackgroundColor();
            }
        }

        protected override void UpdateBackgroundColor()
        {
            //base.UpdateBackgroundColor();
            if(Control != null) { 
                var nativeControl = (Windows.UI.Xaml.Controls.Border)Control;
                var nativeColor = Windows.UI.Color.FromArgb(
                                                                (byte)(backgroundColor.A * 255),
                                                                (byte)(backgroundColor.R * 255),
                                                                (byte)(backgroundColor.G * 255),
                                                                (byte)(backgroundColor.B * 255));
                nativeControl.Background = new Windows.UI.Xaml.Media.SolidColorBrush(nativeColor);
            }
        }

    }
}

As you can see, I don't call base.UpdateBackgroundColor(), check for null and if it is I do nothing. Also I make my renderer call UpdateBackground() itself.

My suggestion: In FrameRenderer, add the line UpdateBackground() to OnElementChanged(e) and override UpdateBackground() with a solution similar to mine.

Hope, I could help. :)
Comment 4 Happypig375 2017-11-14 09:13:21 UTC
+1 for this issue... Now I cannot use a "CircleLayout" with background colors... Please fix!!!
Comment 5 Sascha Martinetz 2018-01-29 09:32:59 UTC
I second that..  please fix this.
Comment 6 Will 2018-03-20 15:48:37 UTC
I'm also experiencing this issue. The solution above works fine for me when I set the background color, but actually in my app the background color is bound to some text contained within the frame, and only the first element on the page seems to receive the correct color, the rest end up transparent.
Comment 7 Will 2018-03-20 16:41:31 UTC
The problem seems to be the binding is called after OnElementChanged. I resolved this by adding to the above code:

        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);

            if (Control != null && sender is Frame frame && e.PropertyName==nameof(frame.BackgroundColor))
            {
                backgroundColor = frame.BackgroundColor;
                UpdateBackgroundColor();
            }
        }
Comment 8 Shimmy 2018-03-25 00:13:02 UTC
Same issue here.
Are you planning to work on this?