1
votes

I'm current using Xamarin Forms with MVVM Light to create a cross platform Android/iOS app.

My problem is that I try to use a switch to show/hide a ListView beneath the switch.

EDIT: Problem is still the same, but I discovered that if the list IsVisible=true when navigating to the page, it is rendered correctly. Seems like it can't be IsVisible=false from start.

When I turn on the switch the first time, the ListView is only shown partly. If I switch it off, then on again, the entire ListView is rendered. Images can explain better:

  1. First image shows the state before the switch is turned ON

Before switch has been turned on

  1. Second image show the state where the switch has been turned ON once. The background of the ListView is Aqua to see it better

After swtich has been turned on first time

  1. Third image show the state where the switch has been turned ON, OFF, ON. Background of ListView still Aqua, but everything is shown as it should.

enter image description here

The switch is bound to a bool in the ViewModel and ListView IsVisible is bound to a bool in the ViewModel. When the switch is turned on it changes the IsVisible property to true, which should show the List the first time too.

XAML View Code snippet:

<Grid Padding="0, 10, 0, 0" VerticalOptions="Start" Grid.Row="0" BackgroundColor="{Binding Source={x:Static color:ColorService.BackgroundColor}}">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>

            <Label Text="Show list" Grid.Column="0" HorizontalOptions="Start" VerticalOptions="Center" TextColor="{Binding Source={x:Static color:ColorService.TextColor}}"/>
            <Switch IsToggled="{Binding IsCustomTeamNamesSwitchToggled}" Grid.Column="0" VerticalOptions="Center" HorizontalOptions="End" >
                <Switch.HeightRequest>
                    <OnPlatform x:TypeArguments="x:Double">
                      <OnPlatform.iOS>
                        30
                      </OnPlatform.iOS>
                      <OnPlatform.Android>
                       50
                      </OnPlatform.Android>
                    </OnPlatform>
                </Switch.HeightRequest>
                <Switch.WidthRequest>
                    <OnPlatform x:TypeArguments="x:Double">
                      <OnPlatform.iOS>
                        50
                      </OnPlatform.iOS>
                      <OnPlatform.Android>
                       100
                      </OnPlatform.Android>
                    </OnPlatform>
                </Switch.WidthRequest>
            </Switch>
        </Grid>

        <ListView ItemsSource="{Binding TeamNameList}" Grid.Row="1" x:Name="listview" IsVisible="{Binding IsListVisible}" BackgroundColor="{Binding Source={x:Static color:ColorService.BorderColor}}">
            <ListView.ItemTemplate>
              <DataTemplate>
                <ViewCell>
                  <ViewCell.View>
                    <Grid Padding="15, 0, 0, 0">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="20"/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>

                        <Label Text="{Binding TeamShortName}" Grid.Column="0" VerticalOptions="Center" TextColor="{Binding Source={x:Static color:ColorService.TextColor}}"/>
                        <Entry Text="{Binding TeamName, Mode=TwoWay}" Grid.Column="1" VerticalOptions="Center" Placeholder="Placeholder" TextColor="{Binding Source={x:Static color:ColorService.TextColor}}"/>
                    </Grid>
                  </ViewCell.View>
                </ViewCell>
              </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>

ViewModel code snippet:

private ObservableCollection<Team> _teamNameList = new ObservableCollection<Team>();
    public ObservableCollection<Team> TeamNameList {
        get {
            return _teamNameList;
        }
        set {
            _teamNameList = value;
            RaisePropertyChanged("TeamNameList");
        }
    }

    private bool _isListVisible;
    public bool IsListVisible {
        get {
            return _isListVisible;
        }
        set {
            _isListVisible = value;
            RaisePropertyChanged ("IsListVisible");
        }
    }

    private bool _isCustomTeamNamesSwitchToggled;
    public bool IsCustomTeamNamesSwitchToggled {
        get {
            return _isCustomTeamNamesSwitchToggled;
        }
        set {
            _isCustomTeamNamesSwitchToggled = value;
            RaisePropertyChanged ("IsCustomTeamNamesSwitchToggled");

            if (_isCustomTeamNamesSwitchToggled)
                IsListVisible = true;
            else
                IsListVisible = false;
        }
    }

Tell me if you need to see some code, or anything else :)

Thanks!

1
Post a code snippet so we can see what we are dealing with.Joel Dean
Added some code from View and ViewModel :)Jonas Jensen
Just to confirm you can try removing the "next" button at the bottom. I have had a terrible time so far of putting list views and buttons on pages as the list view has a hard time sizing itself relative to other controls.ClintL

1 Answers

0
votes

We had the same issue with XF, our solution until this is fixed was to extend the element (basicaly just inherit from it) and OnPropertyChanged if its the isvisible set to true, do a this.FadeTo(1f, 50);. Works most of the time for this issue.

UPDATE

After we debuged even more, what we found was that this is happening because our managed object (list view, button, etc) Hidden property is updated. This is actually udated but the native elements property does not get updated, so it causes this issue. Doing the fix above works almost always, but it is still just a work around.

I have not used Xamarin Forms for a while now so I suggest trying to see if it still happend since animating things is quite a heavy process on the phone.

Vitor