Use a boolean to switch between two ObservableCollections in a ListView

CGLNCGLN ✭✭Member ✭✭
edited March 2018 in Xamarin.Forms

Hello everyone :)

I have a boolean ("ShowChildrenDocumentsSetting") in a "SettingsViewModel" that I want to use to change the items source of a Listview.
The binding context of this Listview is a ViewModel with two ObservableCollections ("Documents" and "AllDocuments").
How can I change dynamically the ItemsSourceProperty of my Listview using this boolean to switch between those collections?

I tried using Datatrigger in my view's constructor but I didn't manage to make it work:

            DataTrigger dataTriggerTrue = new DataTrigger(typeof(ListView))
            {
                Value = "True",
                Binding = new Binding("ShowChildrenDocumentsSetting") { Source = Helper.SettingsViewModel }
            };

            Setter sourceSetterTrue = new Setter()
            {
                Property = ListView.ItemsSourceProperty,
                Value = new Binding("AllDocuments") { Source = this.BindingContext}
            };
            dataTriggerTrue.Setters.Add(sourceSetterTrue);
            listView.Triggers.Add(dataTriggerTrue);


            DataTrigger dataTriggerFalse = new DataTrigger(typeof(ListView))
            {
                Value = "False",
                Binding = new Binding("ShowChildrenDocumentsSetting") { Source = Helper.SettingsViewModel }
            };

            Setter sourceSetterFalse = new Setter()
            {
                Property = ListView.ItemsSourceProperty,
                Value = new Binding("Documents") { Source = this.BindingContext }
            };

            dataTriggerFalse.Setters.Add(sourceSetterFalse);
            listView.Triggers.Add(dataTriggerFalse);

Right now I'm doing it like this (see code below) in my view's constructor but it's not dynamic.
I need to recreate the page to see the change in the Listview's collection if I change the ShowChildrenDocuments value :

    if (Helper.SettingsViewModel.ShowChildrenDocuments) {
        listView.SetBinding(ListView.ItemsSourceProperty, "AllDocuments");
    } else {
        listView.SetBinding(ListView.ItemsSourceProperty, "Documents");
    }

Any idea on how this should be done ?
Thank you in advance !

Best Answers

Answers

  • JoeMankeJoeManke ✭✭✭✭✭ USMember ✭✭✭✭✭

    What happens if you remove the second block and always let the triggers handle setting the ItemsSource binding?

  • CGLNCGLN ✭✭ Member ✭✭

    When I tried with the trigger method I prior removed the second block. However it doesn't show any item from my observable collection using this method.

  • CGLNCGLN ✭✭ Member ✭✭

    Thank you for your answer @JoeManke ! :)

    I really like this solution, however I have troubles to join my ShowChildrenDocumentsSetting in my ViewModel with the one in my SettingsViewModel.
    I'm changing this boolean with a switch on a settings page (using the settings plugin from @jamesmontemagno).

    How can I link these booleans?

  • JoeMankeJoeManke ✭✭✭✭✭ USMember ✭✭✭✭✭

    Depending on how your ViewModels are set up, possibly just listen to the PropertyChanged event of the SettingsViewModel on this page's ViewModel, or use something like MessagingCenter.

  • CGLNCGLN ✭✭ Member ✭✭

    Actually I have this setup:

    I have a NodeViewModel which has a list of DocumentViewModels.
    This NodeViewModel is also a list of NodeViewModels itself.

    I have a NodeView which display the content of a NodeViewModel (Nodes + Documents).

    And I have a switch on a settings page which is binded to a boolean in my SettingsViewModel.
    When this Switch is

    • activated:
      I want to display the node's documents + all the children nodes' documents

    • desactivated:
      I want to only display the node's documents

    I'd like the NodeViews to refresh when the switch on the settings page is toggled.

    possibly just listen to the PropertyChanged event of the SettingsViewModel on this page's ViewModel

    Have you any simple example on how to do that?

  • CGLNCGLN ✭✭ Member ✭✭

    This works like a charm ! Thank you @JoeManke ! Problem solved :)

Sign In or Register to comment.