Search code examples
c#xamlxamarinxamarin.formscontentproperty

How to fix "The property Content is set more than once" error in XAML when overriding the ContentProperty of ContentPage


Here is the code I have:

<?xml version="1.0" encoding="UTF-8" ?>
<pages:PopupPage
    x:Class="Memorise.DecksTab.CopyDeckPopup"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:pages="clr-namespace:Rg.Plugins.Popup.Pages;assembly=Rg.Plugins.Popup">
    <Label />
    <Label />
</pages:PopupPage>

With backing code: csharp

[ContentProperty("Contents")]
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class CopyDeckPopup : Rg.Plugins.Popup.Pages.PopupPage
{
    StackLayout contentStack { get; } = new StackLayout()
    {
        Spacing = 0,
        Padding = new Thickness(0),
        Orientation = StackOrientation.Vertical
    };
     public IList<View> Contents { get => contentStack.Children; }

     public CopyDeckPopup(string clickedDeckName, string clickedDeckDescription)
     {
         BindingContext = new CopyDeckPopupViewModel(clickedDeckName, clickedDeckDescription);
         InitializeComponent();
         Content = contentStack;
     
}

In the first XAML I am getting an error on the 2nd Label saying

The property "Content" is set more than once


Solution

  • I can reproduce the behavior.

    Nevertheless, on my side even though VS displays that warning/error if i run the project it deploys correctly and both labels are displayed.

    It seems that VS does not recognize that the ContentProperty is being overriden, and supposes instead that you are trying to add both Labels to Content, which is wrong since you are adding them to your custom ContentProperty Contents!

    Please run the project and let me know if the deploy fails...

    UPDATE

    The whole issue looks to me like a limitation of VS. At the end it is just a warning, and you should be able to ignore it without any danger.

    If on the other hand you opt to set the labels on code you could write

    public CopyDeckPopup(string clickedDeckName, string clickedDeckDescription)
    {
        BindingContext = new CopyDeckPopupViewModel(clickedDeckName, clickedDeckDescription);
        InitializeComponent();
        Content = contentStack;
        Contents.Add(new Label() { Text = "ABC" });
        Contents.Add(new Label() { Text = "DEF" });
    }
    

    But now this looks redundant since as i understand ContentProperty's is an attribute that the

    XAML processor uses to determine the content property.

    Decorating types with ContentPropertyAttribute allows shorter XAML syntax.

    If you code everything on C# just use the good old Stacklayout and write your code like

    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class CopyDeckPopup : Rg.Plugins.Popup.Pages.PopupPage
    {
        public CopyDeckPopup(string clickedDeckName, string clickedDeckDescription)
        {
            BindingContext = new CopyDeckPopupViewModel(clickedDeckName, clickedDeckDescription);
            InitializeComponent();
    
            StackLayout contentStack = new StackLayout()
            {
                Spacing = 0,
                Padding = new Thickness(0),
                Orientation = StackOrientation.Vertical,
                Children =
                {
                    new Label() { Text = "ABC" },
                    new Label() { Text = "ABC" }
                }
    
            };
    
            Content = contentStack;
         
    }