1

In my MainPage.xaml I have a CollectionView in a frame and three image buttons in a frame

I'd like the first button to be visible and when I tap it it makes the other two buttons visible and tap again and make the other two buttons invisible.

Seems pretty straightfoward and I can get it working IF they are all visible at first.

If however the other two buttons start off invisible then the button will not respond.

Aside: I also note that hot reload doesn't seem to work if changes made to the controls(views) inside a frame. I tried without the frames and no difference.

Here's the code: MainPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:Census.ViewModels"
             x:Class="Census.MainPage">
  
  <Grid
    RowDefinitions="*, 65, 100"
    RowSpacing="10">
    
    <Frame Grid.Row="0"
           CornerRadius="10"
           BorderColor="White"
           BackgroundColor="Black"
           Margin="0,0,0,0">
      
      <CollectionView ItemsSource="{Binding FriendsOC}"
                      SelectionMode="Single"
                      SelectedItem="{Binding SelectedItem}"
                      SelectionChangedCommand="{Binding SelectionChangedCommand}"
                      SelectionChangedCommandParameter="{Binding .}" >

        <CollectionView.ItemTemplate>
          <DataTemplate>
            <Grid ColumnDefinitions="*, 200">
              <Label Grid.Column="0"
                     Text="{Binding FName}"
                     FontSize="20"
                     TextColor="Yellow" />
              <Label Grid.Column="1"
                     Text="{Binding LName}"
                     FontSize="20"
                     TextColor="Yellow" />
            </Grid>
          </DataTemplate>
        </CollectionView.ItemTemplate>
      </CollectionView>      
      
    </Frame>

    <Frame Grid.Row="1"
           CornerRadius="10"
           BorderColor="White"
           BackgroundColor="Black"
           HeightRequest="60"
           Margin="0,0,0,0"
           Padding="0,2,0,0">

      <Grid ColumnDefinitions="*, *, *">
        <ImageButton Grid.Column="0" 
                     Source="nullx.svg"
                     BorderColor="Yellow"
                     BorderWidth="2"
                     WidthRequest="45"
                     HeightRequest="45"
                     Command="{Binding RevealCommand}"/>
        <ImageButton Grid.Column="1" 
                     Source="nullx.svg"
                     BorderColor="Green"
                     BorderWidth="2"
                     WidthRequest="45"
                     HeightRequest="45"
                     IsVisible="{Binding ImportVisible}"
                     Command="{Binding ImportFriendsCommand}"/>
        <ImageButton Grid.Column="2" 
                     Source="nullx.svg"
                     BorderColor="Red"
                     BorderWidth="2"
                     WidthRequest="45"
                     HeightRequest="45"
                     IsVisible="{Binding DestroyVisible}"
                     Command="{Binding DestroyCommand}"/>
      </Grid>
    </Frame>

    <Button Grid.Row="2"
            Text="Add"
            Command="{Binding AddFriendCommand}" 
            WidthRequest="100"
            Margin="25,25,25,25"/>
  </Grid>
</ContentPage>

MainPage.xaml.cs

namespace Census;

public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();
    BindingContext = new CensusViewModel();
  }
  protected override void OnAppearing()
  {
    base.OnAppearing();
    //ImportVisible = false;  <--things I tried to no avail
    //DestroyVisible = false;
    //FriendsList.ItemsSource = await App.Friends.GetFriendsAsync();  //because App.xaml.cs is where th db code is
  }

}

and the viewmodel

namespace Census.ViewModels;

public partial class CensusViewModel : ObservableObject
{
  [ObservableProperty]
  public bool importVisible = true;

  [ObservableProperty]
  public bool destroyVisible = true;

...


 //Reveal Actions
  public ICommand RevealCommand => new Command(() =>
  {
    Console.WriteLine("Reveal");
    ImportVisible = !ImportVisible;
    DestroyVisible = !DestroyVisible;
  });

...
}

This works fine

but if I do

  [ObservableProperty]
  public bool importVisible = false;

  [ObservableProperty]
  public bool destroyVisible = false;

It works in terms of hiding the two buttons, but does not respond if I tap the first button, except it does hit the code and change the properties.

Now in my head I am thinking of a question I asked here .net Maui databinding to shell flyout item IsVisible property

I've tried different variation on a theme but haven't been able to figure out what I could do. (Hence why I use the code binding in the codebehind as per the solution.

Just seems so bizarre that it works when the properties start off true and works fine, but not when false.

I've spent a good many hours on this by the way so I do try hard to figure it out myself.

ToolmakerSteve
  • 18,547
  • 14
  • 94
  • 196
gfmoore
  • 976
  • 18
  • 31
  • *"Just seems so bizarre that it works when the properties start off true and works fine, but not when false."* I recall similar issues in Xamarin Forms. I suspect "something" only gets wired up during InitializeComponent, but is skipped for hidden elements. Can you make a minimum example repo, and post an issue in .Net Maui github? – ToolmakerSteve Jun 20 '22 at 20:36
  • Yes it suddenly came to me and is similar to an issue I had with making Flyout items invisible. The buttons are in a grid, making them invisible means that they are not in the internal list for items in the grid, therefore they cannot be made visible, because they aren't in the list. Unfortunately unlike the flyoutitems there is no Shell.FlyoutItemIsVisible property. I'm not sure what the work around might be. Make them visible and then at some point in the lifecycle make them invisible - do you know what event might be a likely candidate?Something like OnPageFinallyLoadedAndRendered – gfmoore Jun 20 '22 at 20:44
  • I would make a repo, but I've stuffed up my github for this project and I'm awaiting an answer on how to repair it https://stackoverflow.com/questions/72678456/visual-studio-community-2022-and-git-github-push-solution-to-recreated-repo – gfmoore Jun 20 '22 at 20:46
  • Ok. Unfortunately no such event exists. In XF, I invented one by custom code in each platform's PageRenderer, that ran an `Action` the FIRST time a page was rendered. I haven't tried to do that for Maui yet. – ToolmakerSteve Jun 20 '22 at 20:47
  • A work-around, if it is acceptable to have "blank space" where the control would be, is to have visible, but set opacity near-zero, using a boolean-to-opacity IValueConverter. (If set exactly zero, on iOS the native controller decides "its invisible", so may still not get hooked up.) – ToolmakerSteve Jun 20 '22 at 20:51
  • Made a new repo and opened a bug report. That's an interesting idea, I'll give it a go :) – gfmoore Jun 20 '22 at 21:27

0 Answers0