Update collection view item when Preference is changed

mrizoiwe98 66 Reputation points
2021-03-31T00:15:52.28+00:00

I have a predefined list of items in CollectionView and each item includes a checkbox. The checkbox is binded to a Preference. What I want to do is automatically update the checkbox in CollectionView when the preference is updated. How can I do this?

 public class AchievementsViewModule : BaseViewModel
    {
        public ObservableCollection<Achievement> Achievements { get; set; }

        public AchievementsViewModule()
        {
            Achievements = new ObservableCollection<Achievement>();
            Achievements.Add(new Achievement
            {
                Title = "first title",
                Subtitle = "first subtitle",
                ImageUrl = "image.png",
                Completed = Preferences.get("item1",False),
                CompletedDate = DateTime.Now
            }); 
   Achievements.Add(new Achievement
            {
                Title = "second title",
                Subtitle = "second subtitle",
                ImageUrl = "image.png",
                Completed = Preferences.get("item2",False),
                CompletedDate = DateTime.Now
            }); 
   Achievements.Add(new Achievement
            {
                Title = "third title",
                Subtitle = "third subtitle",
                ImageUrl = "image.png",
                Completed = Preferences.get("item3",False),
                CompletedDate = DateTime.Now
            }); 


    }

In a separate page, a button changes the Preference value:

private void Button_Clicked(object sender, EventArgs e)
      {
          Preferences.Set("item2", True);
      }

And here's the Achievement module

  public class Achievement
   {
        public string Title { get; set; }
        public string Subtitle { get; set; }

       public DateTime CompletedDate { get; set; }
       public Boolean Completed { get; set; }
       public string ImageUrl { get; set; }
   }

The XAML for Achievements page:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="App1.Views.AchievementsPage"
             xmlns:viewmodels="clr-namespace:App1.ViewModels"
             xmlns:model="clr-namespace:App1.Models"
             x:DataType="model:Achievement">
    <ContentPage.BindingContext>
        <viewmodels:AchievementsViewModule></viewmodels:AchievementsViewModule>
    </ContentPage.BindingContext>


    <StackLayout>
        <CollectionView x:DataType="viewmodels:AchievementsViewModule"
                        SelectionMode="Single"
            ItemsSource= "{Binding Achievements}"
            SelectionChanged="CollectionView_SelectionChanged">

            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <Grid Padding="10"
                      x:DataType="model:Achievement"
                     RowDefinitions="Auto, *"
                      ColumnDefinitions="Auto, *">
                        <Image Grid.RowSpan="2" BackgroundColor="Red"
                       Source="{Binding ImageUrl}"
                       Aspect="AspectFill"
                       HeightRequest="50"
                       WidthRequest="50" />
                        <Label Grid.Column="1" HorizontalOptions="StartAndExpand" BackgroundColor="Green"
                       Text="{Binding Title}"
                       FontAttributes="Bold" />
                        <Label Grid.Row="1" HorizontalOptions="Start" BackgroundColor="Yellow"
                       Grid.Column="1"
                       Text="{Binding Subtitle}"
                       VerticalOptions="End" />
                        <CheckBox Grid.RowSpan="2" 
                    "Grid.Column="3" 
                     IsChecked="{Binding Completed}"  </CheckBox>

                    </Grid>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>

    </StackLayout>
</ContentPage>
Xamarin
Xamarin
A Microsoft open-source app platform for building Android and iOS apps with .NET and C#.
5,294 questions
0 comments No comments
{count} votes

Accepted answer
  1. Leon Lu (Shanghai Wicresoft Co,.Ltd.) 68,571 Reputation points Microsoft Vendor
    2021-03-31T02:07:06.747+00:00

    Hello,​

    Welcome to our Microsoft Q&A platform!

    No. I cannot find any Api to monitor Preference value changed event. You just could monitor the property of Achievement changed event, then you can update value in the sharePreference.

    But you change the value of Preference in other pages, this page will disappear, when this page appears, all the value will be added again, Completed = Preferences.Get("item2", false), will be executed again, So the value will be changed. No need to mintor it.

    You can delete ContentPage.BindingContext in the XAML. Here is my xaml layout

       <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"  
                    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:viewmodels="clr-namespace:App76"  
                    x:Class="App76.Page1">  
           <!--<ContentPage.BindingContext>  
               <viewmodels:AchievementsViewModule></viewmodels:AchievementsViewModule>  
           </ContentPage.BindingContext>-->  
         
           <StackLayout>  
               <Button Text="navi" Clicked="Button_Clicked"></Button>  
               <CollectionView x:DataType="viewmodels:AchievementsViewModule"  
                                SelectionMode="Single"  
                    ItemsSource= "{Binding Achievements}"  
                    SelectionChanged="CollectionView_SelectionChanged">  
         
                   <CollectionView.ItemTemplate>  
                       <DataTemplate>  
                           <Grid Padding="10"  
                              x:DataType="viewmodels:Achievement"  
                             RowDefinitions="Auto, *"  
                              ColumnDefinitions="Auto, *">  
                               <Image Grid.RowSpan="2" BackgroundColor="Red"  
                               Source="{Binding ImageUrl}"  
                               Aspect="AspectFill"  
                               HeightRequest="50"  
                               WidthRequest="50" />  
                               <Label Grid.Column="1" HorizontalOptions="StartAndExpand" BackgroundColor="Green"  
                               Text="{Binding Title}"  
                               FontAttributes="Bold" />  
                               <Label Grid.Row="1" HorizontalOptions="Start" BackgroundColor="Yellow"  
                               Grid.Column="1"  
                               Text="{Binding Subtitle}"  
                               VerticalOptions="End" />  
                               <CheckBox   
                                   Grid.RowSpan="2"   
                                   Grid.Column="3"  
                                   IsChecked="{Binding Completed}">  
                               </CheckBox>  
         
                           </Grid>  
                       </DataTemplate>  
                   </CollectionView.ItemTemplate>  
               </CollectionView>  
         
           </StackLayout>  
       </ContentPage>  
    

    Here is layout's background code. add bindingContext in the OnAppearing method, remove it in the OnDisappearing method.

       public partial class Page1 : ContentPage  
           {  
               public Page1()  
               {  
                   InitializeComponent();  
                 
               }  
         
               private void CollectionView_SelectionChanged(object sender, SelectionChangedEventArgs e)  
               {  
         
               }  
               protected override void OnAppearing()  
               {  
                   base.OnAppearing();  
         
                   this.BindingContext = new AchievementsViewModule();  
               }  
         
               protected override void OnDisappearing()  
               {  
                   base.OnDisappearing();  
         
                   this.BindingContext = null;  
               }  
               private void Button_Clicked(object sender, EventArgs e)  
               {  
                   Navigation.PushModalAsync(new Page2());  
               }  
           }  
       }  
    

    ===================
    Update=========================

    If you want to use MessageCenter, that is Ok, that is the same achievment.

    When you click the Button set the new value for Preference in other pages. Send a message.

       private void Button_Clicked(object sender, EventArgs e)  
               {  
                   var res=Preferences.Get("item2", false);  
         
                   Preferences.Set("item2", !res);  
         
                   MessagingCenter.Send<App, string>((App)App.Current, "OneMessage", "");  
               }  
    

    In the AchievementsViewModule.cs code, you can remove all data from ObservableCollection, then re-add it in the MessagingCenter.Subscribe.

       public class AchievementsViewModule : BaseViewModel  
           {  
               public ObservableCollection<Achievement> Achievements { get; set; }  
         
               public AchievementsViewModule()  
               {  
                   Achievements = new ObservableCollection<Achievement>();  
         
         
         
                   Achievements.Add(new Achievement  
                   {  
                       Title = "first title",  
                       Subtitle = "first subtitle",  
                       ImageUrl = "image.png",  
                       Completed = Preferences.Get("item1", false),  
                       CompletedDate = DateTime.Now  
                   });  
                   Achievements.Add(new Achievement  
                   {  
                       Title = "second title",  
                       Subtitle = "second subtitle",  
                       ImageUrl = "image.png",  
                       Completed = Preferences.Get("item2", false),  
                       CompletedDate = DateTime.Now  
                   });  
                   Achievements.Add(new Achievement  
                   {  
                       Title = "third title",  
                       Subtitle = "third subtitle",  
                       ImageUrl = "image.png",  
                       Completed = Preferences.Get("item3", false),  
                       CompletedDate = DateTime.Now  
                   });  
         
                   MessagingCenter.Subscribe<App, string>(App.Current, "OneMessage", (snd, arg) =>  
                   {  
                       Device.BeginInvokeOnMainThread(() => {  
                           Achievements.Clear();  
         
                           Achievements.Add(new Achievement  
                           {  
                               Title = "first title",  
                               Subtitle = "first subtitle",  
                               ImageUrl = "image.png",  
                               Completed = Preferences.Get("item1", false),  
                               CompletedDate = DateTime.Now  
                           });  
                           Achievements.Add(new Achievement  
                           {  
                               Title = "second title",  
                               Subtitle = "second subtitle",  
                               ImageUrl = "image.png",  
                               Completed = Preferences.Get("item2", false),  
                               CompletedDate = DateTime.Now  
                           });  
                           Achievements.Add(new Achievement  
                           {  
                               Title = "third title",  
                               Subtitle = "third subtitle",  
                               ImageUrl = "image.png",  
                               Completed = Preferences.Get("item3", false),  
                               CompletedDate = DateTime.Now  
                           });  
                       });  
                   });  
               }  
           }  
         
           public class Achievement  
           {  
               public string Title { get; set; }  
               public string Subtitle { get; set; }  
         
               public DateTime CompletedDate { get; set; }  
               public Boolean Completed { get; set; }  
               public string ImageUrl { get; set; }  
           }  
       }  
    

    Best Regards,

    Leon Lu


    If the response is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


0 additional answers

Sort by: Most helpful