5
votes

My CommandBarhas its IsOpen property set to true in XAML and therefore the is text for each button is visible as I want the descriptions to remain visible.

When I click on ellipses button, it hides the text and the second time I click on it, I get the following error:

No installed components were detected. Cannot resolve TargetName HighContrastBorder.

There is something awkward going on with the UI and maybe it's related to this but I can't figure out what or why:

enter image description here

As you can see my buttons' text are cut-off for the various buttons I'm displaying:

Code wise, there's nothing special about it as far as I can see:

<Page.BottomAppBar>
    <CommandBar IsOpen="True" 
                ClosedDisplayMode="Compact" 
                IsSticky="True"
                Visibility="{Binding 
                CommandBarViewModel.IsCommandBarVisible, 
                Converter={StaticResource BoolToVisibilityConverter}}"
                Background="{ThemeResource SystemControlBackgroundAccentBrush}">

        <AppBarButton 
            Icon="Add" 
            Label="Add" 
            Foreground="White"
            Command="{Binding CommandBarViewModel.AddCommand}"
            Visibility="{Binding CommandBarViewModel.IsAddVisible,
                         Converter={StaticResource BoolToVisibilityConverter}}"/>

        <AppBarButton 
            Icon="Refresh" 
            Label="Refresh" 
            Foreground="White" 
            Command="{Binding CommandBarViewModel.RefreshListCommand}" 
            Visibility="{Binding 
            CommandBarViewModel.IsRefreshListVisible, 
            Converter={StaticResource BoolToVisibilityConverter}}"/>
    </CommandBar>
</Page.BottomAppBar>

There is no InnerException and the exception is thrown from App.g.i.cs

#if DEBUG && !DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION
 UnhandledException += (sender, e) =>
        {
            if (global::System.Diagnostics.Debugger.IsAttached) 
            global::System.Diagnostics.Debugger.Break();
        };
#endif

Any ideas about both my issue i.e. text cut-off and unhandled exception?

Thanks

UPDATE - 1:

When I remove the binded property (CommandBarViewModel.IsCommandBarVisible) from the Visible property for the CommandBar and hardcode it to Visible, the error moves down the line and instead of occurring in the App.g.i.cs, it is now occurring binded property of the first button it is trying to set the visibility on i.e.

        <AppBarButton 
            Icon="Add" 
            Label="Add" 
            Foreground="White"
            Command="{Binding CommandBarViewModel.AddCommand}"
            Visibility="{Binding CommandBarViewModel.IsAddVisible,
                         Converter={StaticResource BoolToVisibilityConverter}}"/>

But this time I get the following error:

An exception of type 'System.Runtime.InteropServices.COMException' 
occurred in GalaSoft.MvvmLight.dll but was not handled in user code

WinRT information: Cannot resolve TargetName HighContrastBorder.

Additional information: No installed components were detected.

Similar as you can see, but it seem to be coming from MVVMLight??? Makes no sense!

Any suggestions/ideas on how to resolve this?

UPDATE - 2:

If I remove all the Visibility properties (and their corresponding binding), the command is displayed accordingly (i.e. no more cut-off text) and I can click on the ellipses button over and over again and it no longer crashes!!

So it's definitely related to the Visibility and binding it to a property to the view model, but what exactly, I have no idea.

Could it be the ViewModel is only constructed when the page loads and at this stage it is too late for the CommandBar and it's buttons to be initialized correctly.

Odd as everything regarding showing/hidding buttons works as expected except that my text is cut-off and I can't click on the ellipses button or it crashes.

UPDATE - 3:

I found a work-around and I'm not jumping up and down about it as I feel it is wrong but for now it will do. In order to circumvent this error, I make sure that I set the command bar and buttons to visible when I initialize my ViewModel, then hide them accordingly based on the page it's on.

public class AppShellViewModel { public void AppShellViewModel { this.CommandBarViewModel.IsCommandBarVisible = true; this.CommandBarViewModel.IsAddVisible = true; this.CommandBarViewModel.IsRefreshVisible = true; this.CommandBarViewModel.IsCancelVisible = true; }

...

\\Hide buttons accordingly in the various parts of your app.
this.CommandBarViewModel.IsCancelVisible = false;

}

Personally I feel like it's a bug with the CommandBar control and buttons as I should be able to hide it (and its buttons) from the get go and it should

a) be able to handle this without any errors. b) be able to "redraw" itself correctly without having text-cut off.

I could be wrong of course and it could be something to do with my code, but from my perspective, removing the visibility binding fixes it and making it visible first fixes it, so it seems to be pointing down this way.

UPDATE - 4:

Here is the actual code. I've simplified it as much as I could (i.e. removed namespaces, DataTemplates, Main content, etc...), leaving just the CommandBar and its buttons. Hopefully this will help.

As you can see when using mvvmlight, my source is set to Locatorand my path is set to the relevant ViewModel, in this instance, AppShellViewModel.

Yet as explained to Grace, when I use x:bind instead of binding, I get the following error:

Invalid binding path 'CommandBarViewModel.IsCommandBarVisible' :
Property 'CommandBarViewModel' can't be found on type 'AppShell'    
MyApp ..\MyApp\Views\AppShell.xaml


XAML Code:

    <Page.Resources>
        <converters:NullToVisibilityConverter x:Key="NullToVisibilityConverter" />
        <converters:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
        <x:Double x:Key="EllipseDimension">30</x:Double>
    </Page.Resources>

    <Page.BottomAppBar>
        <CommandBar x:Name="AppBar"
                    IsOpen="{x:Bind CommandBarViewModel.IsCommandBarVisible}" 
                    ClosedDisplayMode="Compact" 
                    IsSticky="{x:Bind CommandBarViewModel.IsCommandBarVisible}"
                    Visibility="{x:Bind CommandBarViewModel.IsCommandBarVisible, 
Converter={StaticResource BoolToVisibilityConverter}}"
                    Background="{ThemeResource SystemControlBackgroundAccentBrush}"
                    IsEnabled="{x:Bind IsNotBusy}">
            <AppBarButton 
                Icon="Add" 
                Label="Add" 
                Foreground="White"
                Command="{x:Bind CommandBarViewModel.RegisterCommand}"
                Visibility="{x:Bind CommandBarViewModel.IsRegisterVisible, 
Converter={StaticResource BoolToVisibilityConverter}}"/>

            <AppBarButton 
                Icon="Refresh" 
                Label="Refresh" 
                Foreground="White" 
                Command="{x:Bind CommandBarViewModel.RefreshListCommand}" 
                Visibility="{x:Bind CommandBarViewModel.IsRefreshListVisible, 
Converter={StaticResource BoolToVisibilityConverter}}"/>
        </CommandBar>
    </Page.BottomAppBar>
</Page>

Thanks.

2

2 Answers

1
votes

I create a sample project with your code:

xaml:

<Page
    x:Class="CommandBarSample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:CommandBarSample"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" x:Name="root">

    </Grid>

    <Page.BottomAppBar>

            <CommandBar IsOpen="True" 
                IsSticky="True"
                        ClosedDisplayMode="Compact"
                Background="{ThemeResource SystemControlBackgroundAccentBrush}">

                <AppBarButton 
            Icon="Add" 
            Label="Add" 
            Foreground="White"
            Command="{Binding CommandBarViewModel.RegisterCardCommand}"
            />

                <AppBarButton 
            Icon="Refresh" 
            Label="Refresh" 
            Foreground="White" 
            Command="{Binding CommandBarViewModel.RefreshCardListCommand}" 
            />
            </CommandBar>

    </Page.BottomAppBar>
</Page>

xaml.cs:

Default template, not change anything.

I can not reproduce your exception and UI bug, here is my guess: somewhere in your project, you mention HighContrastBorder as a Target for style. I would suggest you to find and fix it somewhere else, your posted code is working. My build is 14316 desktop.

UPDATE

I add Visibility="{Binding ShowButton}" to the AppBarButton, add this.DataContext = this; to the contructor of the xaml.cs

Add the following in xaml.cs:

private bool _ShowButton = true;

        public bool ShowButton
        {
            get
            {
                return _ShowButton;
            }
            set
            {
                Set(ref _ShowButton, value);
            }
        }

        private void Set(ref bool _ShowButton, bool value, [CallerMemberName] string property = "")
        {
            _ShowButton = value;
            NotifyPropertyChanged(property);
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }

When I change ShowButton value, the Visibility update accordingly.

1
votes

There is no InnerException and the exception is thrown from App.g.i.cs

#if DEBUG && !DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION
 UnhandledException += (sender, e) =>
        {
            if (global::System.Diagnostics.Debugger.IsAttached) 
            global::System.Diagnostics.Debugger.Break();
        };
#endif

I can reproduce this problem when the Add button or the Refresh button is set to invisible at the very beginning when code is running.

To solve this problem, you can use x:Bind instead of Binding. {x:Bind} executes special-purpose code, which it generates at compile-time, and {Binding} uses general-purpose runtime object inspection.

If you set "false"(invisible) to the IsAddVisible or IsRefreshListVisible at first, it doesn't generate the matched AppbarButton, the error will happen using Binding. For example, you use x:Bind to set invisible to the Refresh Button and visible to the Add button, you will find there is no space for Refresh Button in the CommandBar, the Add button will replace the it. This can confirm my opinion, if you set false to the AppbarButton when the Commandbar is initialized, it doesn't generate this button.

No installed components were detected. Cannot resolve TargetName HighContrastBorder

If you check the template of CommandBar you will see there is a Rectangle named HighContrastBorder inside of the CommandBar.

Or you can use Live Visual Tree to find this HighContrastBorder when your code is running:

enter image description here

As you can see, it is a Rectangle in the ContentRoot of the CommandBar.

I can't reproduce either this problem, or the text cut-off problem, they works always fine by my side. I'm using MVVM, but I didn't use MVVMLight to test the problem. Maybe you can share your sample.