.netlistviewmaui

.NET Maui Editor in ListView Won't Accept Input


I am upgrading an app from Xamarin to Maui. A form with a ListView that used to work perfectly, now will not accept input in Entry nor Editor controls, and Buttons do not work, UNLESS the item is the 1st or 2nd item in the list!!! (you can't make this stuff up, folks!).

The form has a button to add another element to the collection. That collection that is bound to the list view. Each element has some data entry fields (2 Entry controls, 1 Editor control) and also a Button.

If the list is empty, I can add 1 item, then add another. Everything works fine. If I add a 3rd (or more), the controls in those list items do not accept input. (!)

My XAML looks like this (I've simplified it a bit for clarity):

<ContentPage.Content>

   <StackLayout Orientation="Vertical" VerticalOptions="StartAndExpand">

       <Button WidthRequest="200" HeightRequest="50" Text="Add New" HorizontalOptions="Center" Clicked="NewCommentClicked"/>
       
       <BoxView HeightRequest="10" />

       <StackLayout Orientation="Vertical" VerticalOptions="StartAndExpand" HeightRequest="1200">

       <ListView x:Name="CommentsList" 
                 ItemsSource="{Binding .Comments}"   
                 SelectionMode="None" 
                 SeparatorVisibility="None" 
                 RowHeight="220" 
                 VerticalOptions="StartAndExpand">

           <ListView.ItemTemplate>
               <DataTemplate>
                   <ViewCell>
                       <ViewCell.View>
                           <Grid>
                               <Grid.RowDefinitions>
                                   <RowDefinition Height="40"/>
                                   <RowDefinition Height="40"/>
                                   <RowDefinition Height="40"/>
                                   <RowDefinition Height="40"/>
                                   <RowDefinition Height="5"/>
                               </Grid.RowDefinitions>
                               <Grid.ColumnDefinitions>
                                   <ColumnDefinition Width="10"/>
                                   <ColumnDefinition Width="90"/>
                                   <ColumnDefinition Width="80"/>
                                   <ColumnDefinition Width="400"/>
                                   <ColumnDefinition Width="80"/>
                               </Grid.ColumnDefinitions>
                               <Label Grid.Row="0" Grid.Column="1" WidthRequest="80"  Text="Rel (in):" VerticalOptions="Start" />
                               <Entry Grid.Row="0" Grid.Column="2" WidthRequest="80"  Text="{Binding RelDepth}" VerticalOptions="Start" />
                               
                               <Label Grid.Row="1" Grid.Column="1" WidthRequest="80"  Text="Abs (ft):" />
                               <Label Grid.Row="1" Grid.Column="2" WidthRequest="80"  Text="{Binding AbsDepth}" />

                               <Editor Grid.Row="0" Grid.Column="3" Grid.RowSpan="4"
                                      WidthRequest="400" 
                                      HeightRequest="120"
                                      Text="{Binding Text}" 
                                      Placeholder="Comment(s)..."
                                      BackgroundColor="#EFEFEF"
                                      Style="{StaticResource BigBlackTextEntry}"
                                      HorizontalOptions="StartAndExpand"
                                      VerticalOptions="Start"/>

                               <Button Grid.Row="3" Grid.Column="1" WidthRequest="90" HeightRequest="50" Text="Remove" />

                               <BoxView Grid.Row="4" Grid.Column="1" Grid.ColumnSpan="4" HeightRequest="1" BackgroundColor="Cyan" />
                           </Grid>
                       </ViewCell.View>
                   </ViewCell>
               </DataTemplate>
           </ListView.ItemTemplate>
       </ListView>

       </StackLayout>
       
   </StackLayout>

</ContentPage.Content>

In the code behind, I set the Binding context like this:


 /// in the class instance data...
 private CommentBinding ViewModel { get; set; } 

 /// elsewhere - in the constructor
 ViewModel = new CommentBinding() { Comments = theModels };

 BindingContext = ViewModel;

 /// when an item is added 

 private void NewCommentClicked(object sender, EventArgs e)
 {
   try
   {
     DepthModel newComment = new DepthModel() { RelDepth=0 };

     newComment.RecalcAbsDepth(_startingAbsDepthInches);

     ViewModel.Comments.Add(newComment);

     ViewModel.NotifyChange();
   }
   catch (Exception exception)
   {
     // log error... etc
   }
 }


The attached screen shot shows the 3 items in the list. The first two are editable and everyting works. The 3rd item does not allow any data entry (as if the controls were disabled - but we don't do that) and the button "Remove" does not respond.

enter image description here

Please note that the StackView that wraps the ListView had to be added to get the ListView to position properly (that is yet another mystery) - and the 1200 HeightRequest is an experiment to see if this is influencing the odd behavior - I'm not concerned about these right now.

All ideas welcome, of course.


Solution

  • Based on your code, I created a new demo and tried it on my side. But I found that the ListView cannot scroll. And I found there is a known issue on ListView and CollectionView do not scroll in a VerticalStackLayout, so we can use a Grid instead of StackLayout on the outside of the ListView.

    You can refer to the following code:

    <ContentPage.Content>
        <Grid  VerticalOptions="StartAndExpand"  >
            <Grid.RowDefinitions>
                <RowDefinition Height="60" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
    
            <VerticalStackLayout>
    
                <Button WidthRequest="200" HeightRequest="50" Text="Add New" HorizontalOptions="Center" Command="{Binding AddNewCommand}"/>
    
                <BoxView HeightRequest="10" />
    
            </VerticalStackLayout>
    
            <!--<StackLayout Orientation="Vertical" VerticalOptions="StartAndExpand" HeightRequest="1200">-->
    
                <ListView x:Name="CommentsList"  Grid.Row="1"
                 ItemsSource="{Binding Comments}"  
                 SelectionMode="None"
                 SeparatorVisibility="None"
                 RowHeight="220"
                 VerticalOptions="StartAndExpand">
    
                    <ListView.ItemTemplate>
                        <DataTemplate>
                            <ViewCell>
                                <ViewCell.View>
                                    <Grid>
                                        <Grid.RowDefinitions>
                                            <RowDefinition Height="40"/>
                                            <RowDefinition Height="40"/>
                                            <RowDefinition Height="40"/>
                                            <RowDefinition Height="40"/>
                                            <RowDefinition Height="5"/>
                                        </Grid.RowDefinitions>
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="10"/>
                                            <ColumnDefinition Width="90"/>
                                            <ColumnDefinition Width="80"/>
                                            <ColumnDefinition Width="400"/>
                                            <ColumnDefinition Width="80"/>
                                        </Grid.ColumnDefinitions>
                                        <Label Grid.Row="0" Grid.Column="1" WidthRequest="80"  Text="Rel (in):" VerticalOptions="Start" />
                                        <Entry Grid.Row="0" Grid.Column="2" WidthRequest="80"  Text="{Binding RelDepth}" VerticalOptions="Start" />
    
                                        <Label Grid.Row="1" Grid.Column="1" WidthRequest="80"  Text="Abs (ft):" />
                                        <Label Grid.Row="1" Grid.Column="2" WidthRequest="80"  Text="{Binding AbsDepth}" />
    
                                        <Editor Grid.Row="0" Grid.Column="3" Grid.RowSpan="4"
                                      WidthRequest="400"
                                      HeightRequest="120"
                                      Text="{Binding Text}"
                                      Placeholder="Comment(s)..."
                                      BackgroundColor="#EFEFEF"
                                      HorizontalOptions="StartAndExpand"
                                      VerticalOptions="Start"/>
    
                                         <Button Grid.Row="3" Grid.Column="1" WidthRequest="90" HeightRequest="50" Text="Remove" Command="{Binding BindingContext.RemoveCommand,Source={x:Reference CommentsList}}" CommandParameter="{Binding .}" />
    
                                        <BoxView Grid.Row="4" Grid.Column="1" Grid.ColumnSpan="4" HeightRequest="1" BackgroundColor="Cyan" />
                                    </Grid>
                                </ViewCell.View>
                            </ViewCell>
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>
    
            <!--</StackLayout>-->
    
        </Grid>
    </ContentPage.Content>
    

    Besides, since you use MVVM, we generally no longer recommend changing the data in the View model in C#, but using Command in the ViewModel. So, you can add Command AddNewCommand for Button Add New and Command RemoveCommand for Button Remove on your view model.

        public ICommand AddNewCommand { get; set; }
        public ICommand RemoveCommand { get; set; }
    

    You can refer to the following code:

    public class CommentViewModel
    {
        public ObservableCollection<DepthModel> Comments { get; set; }
    
    
        public ICommand AddNewCommand { get; set; }
        public ICommand RemoveCommand { get; set; }
    
        public CommentViewModel() {
    
            Comments = new ObservableCollection<DepthModel>();
    
            Comments.Add(new DepthModel { AbsDepth="01",  RelDepth = 01, Text="Hi 1"});
            Comments.Add(new DepthModel { AbsDepth="02",  RelDepth = 022, Text="Hi 2"});
            Comments.Add(new DepthModel { AbsDepth="03",  RelDepth = 033, Text="Hi 3"});
            Comments.Add(new DepthModel { AbsDepth="04",  RelDepth = 044, Text="Hi 4"});
            Comments.Add(new DepthModel { AbsDepth="05",  RelDepth = 055, Text="Hi 5"});
    
    
            RemoveCommand = new Command((s)=> RemoveItem(s as DepthModel));
            AddNewCommand = new Command(AddItem);
    
        }
    
        private void AddItem()
        {
            DepthModel newComment = new DepthModel() { RelDepth = 6 };
    
            //newComment.RecalcAbsDepth(_startingAbsDepthInches);
    
            Comments.Add(newComment);
        }
    
        private void RemoveItem(DepthModel depthModel)
        {
            if (depthModel == null) return;
    
            System.Diagnostics.Debug.WriteLine("remove current item.");
    
            Comments.Remove(depthModel);
    
        }
    }
    

    And the code MainPage.xaml.cs is:

    public partial class MainPage : ContentPage
    {
    
        public  CommentViewModel viewModel { get; set; }
    
        public MainPage()
        {
            InitializeComponent();
    
            viewModel = new CommentViewModel();
    
             this.BindingContext = viewModel;
        }
    }
    
    public class DepthModel
    {
    
        public int RelDepth { get; set; }
    
        public string AbsDepth { get; set; }
    
        public string Text { get; set; }
    }
    

    Note:

    Based on the code I posted above, I could not reproduce the problem you mentioned on Android and Windows platform.