Search code examples
uwpwinui-3winui

Defining buttons in XAML for usercontrol


I am wanting to write a user control that contains a customizable CommandBar. There are standard items which are always present in the command bar, and the page hosting the user control can define additional items.

I have tried to implement it like this:

User control

        private ICommandBarElement[] _toolbarItems;

        public ICommandBarElement[] ToolbarItems
        {
            get => _toolbarItems;
            set
            {
                _toolbarItems = value;
                if (_toolbarItems.Length == 0)
                    removeToolbarItems();
                else
                    addToolbarItems();
            }
        }

Hosting page

        <local:HostControl x:Name="ctl">
            <local:HostControl.ToolbarItems>
                <AppBarButton Icon="Save" Content="Save" />
                <AppBarButton Icon="SaveLocal" Content="Save" />
                <AppBarButton Icon="AddFriend" Content="Friend" />
            </local:HostControl.ToolbarItems>
        </local:HostControl>

When I compile the application, compilation fails so I can't even debug. The error I get is

Xaml Internal Error error WMC9999: Object reference not set to an instance of an object.

There is no line reference, but removing the <local:HostControl.ToolbarItems> node will cause it to compile, so the error must be how I'm defining the property in the user control.

How do I do it so I am able to define elements for the CommandBar inside of the host page xaml?


Solution

  • You should create a DependencyProperty.

    HostControl.xaml.cs

    public sealed partial class HostControl : UserControl
    {
        public HostControl()
        {
            this.InitializeComponent();
            this.Loaded += HostControl_Loaded;
        }
    
        private void HostControl_Loaded(object sender, RoutedEventArgs e)
        {
            this.CommandBar.PrimaryCommands.Clear();
    
            foreach (var item in ToolbarItems)
            {
                this.CommandBar.PrimaryCommands.Add(item);
            }
        }
    
        public IList<ICommandBarElement> ToolbarItems
        {
            get { return (IList<ICommandBarElement>)GetValue(ToolbarItemsProperty); }
            set { SetValue(ToolbarItemsProperty, value); }
        }
    
        public static readonly DependencyProperty ToolbarItemsProperty = DependencyProperty.Register(
            nameof(ToolbarItems),
            typeof(IList<ICommandBarElement>),
            typeof(HostControl),
            new PropertyMetadata(new List<ICommandBarElement>());
    }