I have an issue with ListView Control not updating

Ronald Rex 1,666 Reputation points
2023-05-08T01:12:16.6766667+00:00

Hi Friends,

I have an issue with ListView not updating after I update my BindingList . If at all possible I would like to exploit the .Net Community Toolkit using the MVVM Software Design Pattern by only having my code in my ViewModels, XAML ContentPages, and Models (if possible). I did quite a bit of extensive research on Stack Overflow and I saw where many conversations on this particular topic recommended using an ObservableCollection<T> Class with the INotifyPropertyChanged Interface on a Model, but I was not clear on how to do this or if using this approach would violate the MVVM design pattern. I also saw where I can use the BindingList (which is what I am already using, but understanding both ways is fine because I may run into a use case where I need to use an ObservableCollection) to update the ListView, but I also wasn't clear about how this is done.

In the Code snippet below, you can see where I am binding the Userdefinedfields to the ItemSource of the syncfusion ListView in my XAML. In my ViewModel I have a BindingList and a Property called _selectedUdf (Code in .Net Community Toolkit) to hold the Object the user selected in the ListView OnSelectedUdfChanged( fires when the selected item changes in the ListView Control.) I am using a Popup page to edit the the Objects in my ListView and I can see using this line of code in the [RelayCommand] Shell.Current.DisplayAlert("show", SelectedUdf.NAME, "Info"); that the bound property is being updated; However, its not updating the Syncfusion ListView Control (The reason for posting this Question). Any help with this would be Greatly Appreciated.

XAML:

 <sf:SfListView x:Name="listView" 
                                 SelectionMode="Single"
                                 ItemSize="200"
                                 AutoFitMode="Height"
                                 Grid.Row="0"                                 
                                 ItemsSource="{Binding Userdefinedfields}"                                  
                                 ScrollBarVisibility="Always">

                
               
                <sf:SfListView.ItemTemplate>
                    <DataTemplate x:DataType="libmodel:UserDefinedFields">
                        <Frame x:Name="frame" CornerRadius="10" Margin="10" Padding="0" HasShadow="True" BackgroundColor="CadetBlue">
                            <Grid Margin="60,4,4,0">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="auto" />
                                <RowDefinition Height="auto"/>
                            </Grid.RowDefinitions>
                            <Label Text="{Binding NAME}" Grid.Row="0"  />
                                <Button  CommandParameter="{Binding ID}"   MaximumWidthRequest="70" Text= "Edit" Grid.Row="1" HorizontalOptions="Start"  Command="{Binding Path=BindingContext.EditUdfCommand, Source={x:Reference listView}}"  Margin="0,4,0,0"/>
                        </Grid>
ViewModel Code:

[ObservableProperty]
BindingList<UserDefinedFields> _userdefinedfields;
	
[ObservableProperty]
UserDefinedFields _selectedUdf;


public PayerEditViewModel(IPyrDirDataAccess pyrDirDataAccess)
	{
		_pyrData = pyrDirDataAccess;
		RefreshUserDefienedFieldsList();
	}


private void RefreshUserDefienedFieldsList()
	{
		var udfList = _pyrData.GetUserDefinedFields();
		Userdefinedfields = null;
		Userdefinedfields = new BindingList<UserDefinedFields>(udfList);
	}



[RelayCommand]
	private void EditUdf(int ID)
	{
		int idx = Userdefinedfields.IndexOf(Userdefinedfields.Where(x => x.ID == ID).FirstOrDefault());
		SelectedUdf = Userdefinedfields[idx];
		
		if (SelectedUdf != null)
		
		{
			 _popupService.ShowPopup(new EditUserDefinedFieldPopupView(this));
			Shell.Current.DisplayAlert("show", SelectedUdf.NAME, "Info");
		}
		else
		{
			
		}
	}


Model Code:

public class UserDefinedFields 
{
	public int ID { get; set; }
	public string NAME { get; set; }
}
.NET MAUI
.NET MAUI
A Microsoft open-source framework for building native device applications spanning mobile, tablet, and desktop.
2,918 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,299 questions
0 comments No comments
{count} votes

Accepted answer
  1. Yonglun Liu (Shanghai Wicresoft Co,.Ltd.) 36,061 Reputation points Microsoft Vendor
    2023-05-08T06:10:33.5566667+00:00

    Hello,

    but I was not clear on how to do this or if using this approach would violate the MVVM design pattern.

    No, actually, using INotfiyPropertyChanged is the official recommended method, please refer to Data binding and MVVM for more details.

    You could refer to the following code to modify your ViewModel so that your ListView updates SelectedUdf.NAME as expected:

    // in Model Code
    public class UserDefinedFields: ObservableObject 
    {
            private string name;
            public string NAME
            {
                get => name;
                set => SetProperty(ref name, value);
            }
            private int id;
            public int ID
            {
                get => id;
                set => SetProperty(ref id, value);
            }
    }
    // in ViewModel
    public partial class TestViewModel : INotifyPropertyChanged 
    {
        private ObservableCollection<UserDefinedFields> _userdefinedfields;
        public ObservableCollection<UserDefinedFields> Userdefinedfields
        {
            get { return _userdefinedfields; }
            set
            {
                if (_userdefinedfields != value)
                {
                    _userdefinedfields = value;
                    OnPropertyChanged(); // reports this property
                }
            }
        }
    
        private UserDefinedFields _selectedUdf;
        public UserDefinedFields SelectedUdf
        {
            get => _selectedUdf;
            set
            {
                if (_selectedUdf != value)
                {
                    _selectedUdf = value;
                    OnPropertyChanged();
                }
            }
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged([CallerMemberName] string name = "") =>
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }
    
    

    Best Regards,

    Alec Liu.


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    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