0
votes

I have a template frame that provides some padding and accepts multiple elements:

[Xamarin.Forms.ContentProperty("Contents")]
public class ContentFrame : StackLayout
{
    public StackLayout ContentStack = new StackLayout();
    public IList<View> Contents { get => ContentStack.Children; }

    public ContentFrame()
    {
        CustomFrame cf = new CustomFrame()
        {
            Content = ContentStack,
            HasShadow = false,
        };
        cf.SetDynamicResource(BackgroundColorProperty, "ContentFrameBackgroundColor");
        cf.SetDynamicResource(Frame.CornerRadiusProperty, "ContentFrameCornerRadius");
        cf.SetDynamicResource(MarginProperty, "ContentFrameMargin");
        this.Children.Add(cf);
    }

I would like to add child labels like this: c1.Children.Add - But when I do this the BackgroundColor, CornerRadius and Margin don't get used (see first part of image for ABC and ABC)

The only way I can get it to use these is by exposing ContentStack as a public property and by adding to that (see below for ABC and GHI)

public class TestPage : HeadingView
{
    public TestPage() : base()
    {
        var s = new Stack();

        var c1 = new ContentFrame();
        c1.Children.Add(new Label() { Text = "ABC" });
        c1.Children.Add(new Label() { Text = "DEF" });

        var c2 = new ContentFrame();
        c2.ContentStack.Children.Add(new Label() { Text = "DEF" });
        c2.ContentStack.Children.Add(new Label() { Text = "GHI" });

        s.Children.Add(c1);
        s.Children.Add(c2);

        this.InnerContent = s;
    }
}

Question > Can anyone explain why the first case (with get => ContentStack.Children) doesn't show the frame background, radius etc.

enter image description here

1
the first case is adding to the outer stacklayout (outside the frame), the 2nd case is adding to the inner stacklayout (inside the frame)Jason
Oh I see now. Can you suggest a way that I could fix this problem and have them both add to the inner stacklayout? I can understand what you have said but I am not sure how to change it. The end result I would like is to not have to make ContentStack public.Alan2
I would just create an Add method on the class that does what you wantJason
Are you suggesting a method that would allow me to remove this ".ContentStack.Children." ? Can you give an example of what you mean. ThanksAlan2
Yes, ContentStack does not need to be public. Add a public method that will handle that inner logic for you. You can also allow it to accept multiple controls and add them all at once.Jason

1 Answers

0
votes

make ContentStack private and add a method to expose the add functionality

private StackLayout ContentStack = new StackLayout();

public void Add(View view)
{
  this.ContentStack.Children.Add(view);
}

if you want to add multiple you could also do

public void Add(List<View> views)
{
  foreach(var v in views) 
  {
    this.ContentStack.Children.Add(v);
  }
}