Search code examples
xamluwp-xamlstylingwinui-3winui

InfoBar with enabled message text selection


Is it possible to somehow set the IsTextSelectionEnabled="True" property of the WinUI 3 InfoBar's message without copying the whole control template from source?

I've tried without success some setters, or using ContentTemplate to add a custom TextBlock, but that causes the action button to be above the message, which I don't want.

<InfoBar x:Name="errorBar" Severity="Error" IsOpen="False" VerticalAlignment="Bottom"
         Margin="50" Loaded="ErrorBar_Loaded">
    <InfoBar.ContentTemplate>
        <DataTemplate x:DataType="x:String">
            <TextBlock x:Name="Message"
                       Text="{x:Bind}"
                       IsTextSelectionEnabled="True"/>
        </DataTemplate>
    </InfoBar.ContentTemplate>
    <InfoBar.ActionButton>
        <Button Content="Action" Click="InfoBarButton_Click" />
    </InfoBar.ActionButton>
</InfoBar>

Solution

  • If you don't want to overridD the Xaml, you will need to do it in the Code-behind. Based on the source code of the InfoBar, we could know the name of the TextBlock for message. It is called Message. So we could use VisualTreeHelper to get the TextBlock control from the InfoBar and change its property.

    I've made a sample here and you could refer to it:

    MainPage.Cs:

            private void myButton_Click(object sender, RoutedEventArgs e)
        {
            myButton.Content = "Clicked";
    
          
           UpdateAvailableNotification.IsOpen = !UpdateAvailableNotification.IsOpen;
    
            TextBlock textBlock = TryFindChildByName(UpdateAvailableNotification, "Message") as TextBlock;
            textBlock.IsTextSelectionEnabled = true;
          
        }
    
        public static DependencyObject TryFindChildByName(DependencyObject parant, string ControlName)
        {
            int count = VisualTreeHelper.GetChildrenCount(parant);
    
            for (int i = 0; i < count; i++)
            {
                var MyChild = VisualTreeHelper.GetChild(parant, i);
                if (MyChild is FrameworkElement && ((FrameworkElement)MyChild).Name == ControlName)
                    return MyChild;
    
                var FindResult = TryFindChildByName(MyChild, ControlName);
                if (FindResult != null)
                    return FindResult;
            }
    
            return null;
        }
    

    MainPage.Xaml:

        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
    
        <InfoBar x:Name="UpdateAvailableNotification"
                Title="Update available."
                Message="Restart the application to apply the latest update.">
        </InfoBar>
    
        <Button x:Name="myButton" Click="myButton_Click">Click Me</Button>
        
        
    </StackPanel>
    

    The result:

    enter image description here