How to add support Adding/Removing Item/Items in Xaml in Runtime?

Mahdi Hosseini 310 Reputation points
2026-06-04T10:20:16.9233333+00:00

we can easily add/remove items in combobox in runtime like:

<ComboBox>
    <ComboBoxItem/>
    <ComboBoxItem/>
    <ComboBoxItem/>
</ComboBox>

now i want to support current approach in my control.

i started with a single item but i get error in xaml in runtime

User's image

this is my Renderer property:

public RendererBase Renderer
{
    get { return (RendererBase)GetValue(RendererProperty); }
    set { SetValue(RendererProperty, value); }
}

public static readonly DependencyProperty RendererProperty =
    DependencyProperty.Register(nameof(Renderer), typeof(RendererBase), typeof(ShaderBackground), new PropertyMetadata(null, OnRendererChanged));

private static void OnRendererChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    var ctl = (ShaderBackground)d;
    ctl.rendererBase = (RendererBase)e.NewValue;
}

and this is my RendererBase:

public class RendererBase : DependencyObject, IRenderer

and IRenderer:

internal interface IRenderer : IDisposable

Windows development | WinUI

2 answers

Sort by: Most helpful
  1. Nancy Vo (WICLOUD CORPORATION) 8,155 Reputation points Microsoft External Staff Moderator
    2026-06-05T03:04:20.2933333+00:00

    Hello @Mahdi Hosseini ,

    Thanks for your question.

    Your control only has a single Renderer property, so XAML doesn't know where to put child items. To support adding/removing multiple renderers like ComboBox does, I recommend switching to a collection. You can refer to the following steps and code examples:

    1. Add [ContentProperty] and replace Renderer with a collection.
    [ContentProperty(nameof(Renderers))]
    public class ShaderBackground : Control
    {
        public ObservableCollection<RendererBase> Renderers { get; }
            = new ObservableCollection<RendererBase>();
    
        public ShaderBackground()
        {
            Renderers.CollectionChanged += OnRenderersChanged;
        }
    
        private void OnRenderersChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.NewItems != null)
                foreach (RendererBase r in e.NewItems)
                { /* attach/start renderer */ }
    
            if (e.OldItems != null)
                foreach (RendererBase r in e.OldItems)
                    r.Dispose();
        }
    }
    
    1. Use it in XAML like ComboBox
    <local:ShaderBackground>
        <local:GlowRenderer />
        <local:BlurRenderer />
        <local:NoiseRenderer />
    </local:ShaderBackground>
    
    1. Add or remove at runtime
    myShaderBackground.Renderers.Add(new GlowRenderer());
    
    myShaderBackground.Renderers.Remove(glowRenderer);
    

    I hope this addresses your question. If this response was helpful, please consider following the guidance to provide feedback.

    Was this answer helpful?


  2. AI answer

    2026-06-04T10:20:47.4766667+00:00

    RendererBase and its concrete implementations must be creatable by the XAML loader. The error “Type X cannot be created in XAML” means the type does not satisfy the requirements for XAML construction.

    To support usage like:

    <local:ShaderBackground x:Name="ShaderSample">
        <local:ShaderBackground.Renderer>
            <local:SnowRenderer />
        </local:ShaderBackground.Renderer>
    </local:ShaderBackground>
    

    ensure all of the following:

    1. RendererBase must be public
    public class RendererBase : DependencyObject, IRenderer
    {
    }
    
    1. IRenderer must be public (or remove it from the public API surface of the property)
    public interface IRenderer : IDisposable
    {
    }
    
    1. The concrete renderer (SnowRenderer) must be public and have a public parameterless constructor
    public sealed class SnowRenderer : RendererBase
    {
        public SnowRenderer() { }
    }
    
    1. The dependency property type must be the base type that XAML can instantiate
    public static readonly DependencyProperty RendererProperty =
        DependencyProperty.Register(
            nameof(Renderer),
            typeof(RendererBase),
            typeof(ShaderBackground),
            new PropertyMetadata(null, OnRendererChanged));
    
    public RendererBase Renderer
    {
        get => (RendererBase)GetValue(RendererProperty);
        set => SetValue(RendererProperty, value);
    }
    
    1. The namespace where SnowRenderer is declared must be mapped in XAML, for example:
    xmlns:local="using:App1"
    

    After these changes and a full rebuild, the XAML loader can create SnowRenderer and assign it to the Renderer property at runtime, similar to how ComboBoxItem elements are created and added to a ComboBox.

    For adding/removing multiple items at runtime (like ComboBox items), expose a collection property (for example, an ObservableCollection<RendererBase>) and manipulate it in code, or bind it to a collection in a view model. The XAML loader will populate the collection from nested elements in XAML, and at runtime items can be added/removed from that collection.


    References:

    AI-generated content may be incorrect. Read our transparency notes for more information.

    Was this answer helpful?

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.