0

I am trying to use a converter for my page, but to no avail.

The important parts of the page are one switch, and two listviews. These Listview are one above the other and only one of them should be displayed depending on the state of the switch. The state of the switch should also be changeable from the application in a few cases.

To that effect, I have a boolean property (isPrimaryBin) that, when true, the first listview (primaryBinListView) should be visible and the secondary should be hidden (secondaryBinListView).

When isPrimaryBin change to false, secondaryBinListview become visible and primaryListView becomes hidden.

One last thing, to make it more intuitive, it's important that the switch should not be toggled when isPrimaryBin is true and be toggled when isPrimaryBin is false. (Due to labels being on both sides of the switch and it symbolizing a switch from one bin to the other)

At first I tried to create a second property that would output the opposite of isPrimaryBin, but I would never hit the onPropertyChanged. So I learned how to make converter and made one. At first, it wouldn't hit it. I fiddled with it, realized that I had to add it to the resource dictionary. Then it started looping on itself. Page stuck in an infinite loop. I managed to stop this behavior, but now it no longer update the page. despite the switch being changed, primaryBinListview is always visible and secondaryBinListView is always hidden. The switch change state. It does go through the property. It does go through the converter. I have no idea why nothing changes while it clearly goes through all the steps.

Now onto the code. Let's start with the property:

public bool isPrimaryBin {
        get { return _isPrimaryBin; }
        set {
            if (_isPrimaryBin != value) {
                _isPrimaryBin = value;
                OnPropertyChanged();
            }
        }
    }

Then the convertor

public class inverseBoolConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return !((bool)value);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return !(bool)value;
    }
}

And finally the relevant Xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         xmlns:d="http://xamarin.com/schemas/2014/forms/design"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         mc:Ignorable="d"
         x:Class="Picking.Views.Inv2Page"
         Title="{Binding Title}"
         xmlns:local="clr-namespace:Picking.Helpers">

<ContentPage.Resources>
    <ResourceDictionary>
        <local:inverseBoolConverter x:Key="inverseBoolConverter" />
    </ResourceDictionary>
</ContentPage.Resources>

<ContentPage.Content>
    <Grid RowSpacing="0">
        <Grid Grid.Row="0">
            <Switch Grid.Column="1" OnColor="Orange" ThumbColor="Gray" IsVisible="{Binding isMoveGoods}" IsToggled="{Binding isPrimaryBin, Mode=TwoWay, Converter={StaticResource inverseBoolConverter}}"/
        </Grid>
        <ListView x:Name="ItemsListView" Grid.Row="1" 
            ItemsSource="{Binding Items}"
            VerticalOptions="FillAndExpand"
            HasUnevenRows="true"
            RefreshCommand="{Binding LoadItemsCommand}"
            IsPullToRefreshEnabled="true"
            IsRefreshing="{Binding IsBusy, Mode=OneWay}"
            CachingStrategy="RecycleElement"
            ItemTapped="ItemsListView_ItemTapped"
            Grid.RowSpan="2"
            IsVisible="{Binding isPrimaryBin}"
              >
        </ListView>

        <ListView x:Name="ItemsListViewTransfer" Grid.Row="1" 
            ItemsSource="{Binding Items}"
            VerticalOptions="FillAndExpand"
            HasUnevenRows="true"
            RefreshCommand="{Binding LoadItemsCommand}"
            IsPullToRefreshEnabled="true"
            IsRefreshing="{Binding IsBusy, Mode=OneWay}"
            CachingStrategy="RecycleElement"
            ItemTapped="ItemsListView_ItemTapped"
            Grid.RowSpan="2"
            IsVisible="{Binding isPrimaryBin, Converter={StaticResource inverseBoolConverter}}"
              >
        </ListView>
</ContentPage.Content>

</ContentPage>

I've removed anything non-relevant to the problem (for example, the content of the listviews, extra labels, or anything that does not interact with my problem)

It is my 1st time working with converters. I've looked over multiple guide on how to make them work and it led me to this weird limbo when nothing work, but at least nothing break.

Thanks for your help.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Elgate
  • 113
  • 2
  • 11

1 Answers1

0

It looks like your two listViews load the same data when the switch state changes, so it looks like the UI doesn't change.Maybe you could show your viewmodel.That will be clearer.

Below is a simple sample with your codes,if that you want ?

ConvertModel (you could replace your own viewmodel):

 class ConvertModel :INotifyPropertyChanged
{
    ObservableCollection<string> items = new ObservableCollection<string>();
    public ObservableCollection<string> Items { get { return items; } }
    private bool _isPrimaryBin;
    public bool isPrimaryBin
    {
        get { return _isPrimaryBin; }
        set
        {

            _isPrimaryBin = value;
            if (_isPrimaryBin)
            {
                items.Clear();
                items.Add("aaa");
                items.Add("bbb");
                items.Add("ccc");
                items.Add("ddd");
                items.Add("eee");
                items.Add("fff");
                items.Add("ggg");
            }
            else
            {
                items.Clear();
                items.Add("111");
                items.Add("222");
                items.Add("333");
                items.Add("444");
                items.Add("555");
                items.Add("666");
                items.Add("777");
            }
            OnPropertyChanged();

        }
    }

    public ConvertModel(bool isPr)
    {
        _isPrimaryBin = isPr;

        if (isPr)
        {
            items.Add("aaa");
            items.Add("bbb");
            items.Add("ccc");
            items.Add("ddd");
            items.Add("eee");
            items.Add("fff");
            items.Add("ggg");
        }
        else
        {
            items.Add("111");
            items.Add("222");
            items.Add("333");
            items.Add("444");
            items.Add("555");
            items.Add("666");
            items.Add("777");
        }

    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

page.xaml:

<ContentPage.Resources>
    <ResourceDictionary>
        <local:inverseBoolConverter x:Key="inverseBoolConverter" />
    </ResourceDictionary>
</ContentPage.Resources>
<ContentPage.Content>

    <StackLayout Orientation="Vertical">
        <Switch Grid.Column="1" OnColor="Orange" ThumbColor="Gray"  IsToggled="{Binding isPrimaryBin, Mode=TwoWay, Converter={StaticResource inverseBoolConverter}}"></Switch>

        <ListView x:Name="ItemsListView" 
        ItemsSource="{Binding Items}"
        VerticalOptions="FillAndExpand"
        HasUnevenRows="true"
        IsPullToRefreshEnabled="true"
        CachingStrategy="RecycleElement"
        IsVisible="{Binding isPrimaryBin}"
         >
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Label Text="{Binding .}"></Label>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
        <ListView x:Name="ItemsListViewTransfer" 
        ItemsSource="{Binding Items}"
        VerticalOptions="FillAndExpand"
        HasUnevenRows="true"
        IsPullToRefreshEnabled="true"
        CachingStrategy="RecycleElement"
        IsVisible="{Binding isPrimaryBin, Converter={StaticResource inverseBoolConverter}}"
          >
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Label Text="{Binding .}"></Label>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>
</ContentPage.Content>

page.xaml.cs:

public ConvertPage()
  {
      InitializeComponent();
      ConvertModel convertModel = new ConvertModel(false);
      BindingContext = convertModel;
  }

the effect like:

enter image description here

Leo Zhu
  • 15,726
  • 1
  • 7
  • 23
  • That was the problem. I had been stuck learning something new, and I ended up not double checking that it was showing the right things. – Elgate Jul 02 '20 at 13:07