Flexible TitleBar UserControl

Eduardo Gomez 4,156 Reputation points
2023-07-02T16:00:11.21+00:00

I made a Title bar as UserControl

  <Grid
        Height="32"
        Background="Transparent">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="50" />
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>
        <!--  Add your UI elements and styling here  -->
        <BitmapIcon
            x:Name="icon"
            Loaded="icon_Loaded"
            VerticalAlignment="Center"
            UriSource="{x:Bind ImageSource, Mode=OneWay}" />
        <TextBlock
            Grid.Column="1"
            VerticalAlignment="Center"
            Text="{x:Bind Text, Mode=OneWay}"/>

    </Grid>

So, I can reuse it in my app

As you can see everything is working fine

User's image

the problems are that I don't want any icon in this window

   public sealed partial class AppTitleBarControl : UserControl {

        public string ImageSource {
            get { return (string)GetValue(ImageSourceProperty); }
            set { SetValue(ImageSourceProperty, value); }
        }

        public string Text {
            get { return (string)GetValue(TextProperty); }
            set { SetValue(TextProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Text.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty TextProperty =
            DependencyProperty.Register(
                "Text", typeof(string), typeof(AppTitleBarControl), null);

        // Using a DependencyProperty as the backing store for ImageSource. This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ImageSourceProperty =
            DependencyProperty.Register(
                "ImageSource", typeof(string), typeof(AppTitleBarControl), null);

        public AppTitleBarControl() {
            InitializeComponent();
        }

        private void icon_Loaded(object sender, RoutedEventArgs e) {

            var icon = sender as BitmapIcon;
            if (string.IsNullOrEmpty(ImageSource)) {
                icon.Visibility = Visibility.Collapsed;
            } else {
                icon.Visibility = Visibility.Visible;
            }
        }
    }
}]


So what I did is to do a null check


    <StackPanel>
        <demy:AppTitleBarControl
            x:Name="AppBar"
            ImageSource="{x:Null}"
            Text="Login" />
    </StackPanel>

When I run, I get an exception

{"Value does not fall within the expected range."}

Windows development | Windows App SDK
0 comments No comments
{count} votes

Answer accepted by question author
  1. Xiaopo Yang - MSFT 12,736 Reputation points Microsoft External Staff
    2023-07-04T07:43:56.68+00:00

    The following code is a workaround for me.

    <!-- Copyright (c) Microsoft Corporation and Contributors. -->
    <!-- Licensed under the MIT License. -->
    
    <UserControl
        x:Class="App2CSharp.UserControl1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:App2CSharp"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid
            Height="32"
            Background="Transparent">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>
            <TextBlock
                Grid.Column="1"
                Margin="5,0,0,0"
                VerticalAlignment="Center"
                Text="{x:Bind Text}" 
                Visibility="{x:Bind l}"/>
        </Grid>
    </UserControl>
    
    
        public sealed partial class UserControl1 : UserControl
        {
            Visibility l;
            public string Text
            {
                get { return (string)GetValue(TextProperty); }
                set { SetValue(TextProperty, value); }
            }
    
            // Using a DependencyProperty as the backing store for Text.  This enables animation, styling, binding, etc...
            public static readonly DependencyProperty TextProperty =
                DependencyProperty.Register(
                    "Text", typeof(string), typeof(UserControl1), new PropertyMetadata(null, OnTextPropertyChanged));
    
            private static void OnTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                var control = (UserControl1)d;
                if (string.IsNullOrEmpty(e.NewValue as string))
                {
                    control.l = Visibility.Collapsed;
                }
            }
    
            public UserControl1()
            {
                this.InitializeComponent();
            }
        }
        
        
    
    <local:UserControl1 Text=""/>
        ```
    
    
    0 comments No comments

1 additional answer

Sort by: Most helpful
  1. Xiaopo Yang - MSFT 12,736 Reputation points Microsoft External Staff
    2023-07-03T01:59:53.64+00:00

    Probably BitmapIcon do not accept null as a value (whether through markup or code) due to their internal implementation. See {x:Null}.

    You can try to specify ImageSource to "", empty string. But why not use Image.ImageFailed Event?


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.