Flexible TitleBar UserControl

Eduardo Gomez 3,431 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 App SDK
Windows App SDK
A set of Microsoft open-source libraries, frameworks, components, and tools to be used in apps to access Windows platform functionality on many versions of Windows. Previously known as Project Reunion.
808 questions
0 comments No comments
{count} votes

Accepted answer
  1. Xiaopo Yang - MSFT 12,726 Reputation points Microsoft Vendor
    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,726 Reputation points Microsoft Vendor
    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 Answers by the question author, which helps users to know the answer solved the author's problem.