Редактор .NET Maui в ListView не принимает ввод

Я обновляю приложение с Xamarin до Мауи. Форма с ListView, которая раньше работала идеально, теперь не принимает ввод в элементах управления «Ввод» или «Редактор», а кнопки не работают, ЕСЛИ элемент не является 1-м или 2-м элементом в списке !!! (ребята, вы не можете это выдумать!).

В форме есть кнопка для добавления еще одного элемента в коллекцию. Эта коллекция, привязанная к представлению списка. Каждый элемент имеет несколько полей для ввода данных (2 элемента управления вводом, 1 элемент управления редактором), а также кнопку.

Если список пуст, я могу добавить 1 элемент, затем добавить еще один. Все работает нормально. Если я добавлю третий (или более), элементы управления в этих элементах списка не примут входные данные. (!)

Мой XAML выглядит так (я немного упростил его для ясности):

<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 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
   }
 }


На прилагаемом снимке экрана показаны 3 элемента списка. Первые два доступны для редактирования, и все работает. 3-й пункт не позволяет вводить какие-либо данные (как если бы элементы управления были отключены - но мы этого не делаем) и кнопка "Удалить" не реагирует.

Обратите внимание, что StackView, который обертывает ListView, должен был быть добавлен, чтобы ListView правильно позиционировался (это еще одна загадка) - и 1200 HeightRequest - это эксперимент, чтобы увидеть, влияет ли это на странное поведение - меня это не беспокоит. об этом прямо сейчас.

Все идеи, конечно, приветствуются.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

На основе вашего кода я создал новую демо-версию и опробовал ее на своей стороне. Но я обнаружил, что ListView не может прокручиваться. И я обнаружил известную проблему в ListView и CollectionView, которые не прокручиваются в вертикальном StackLayout, поэтому мы можем использовать Grid вместо StackLayout снаружи ListView.

Вы можете обратиться к следующему коду:

<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>

Кроме того, поскольку вы используете MVVM, мы обычно больше не рекомендуем изменять данные в модели представления в C#, а использовать команду в ViewModel. Итак, вы можете добавить команду AddNewCommand для кнопки Add New и команду RemoveCommand для кнопки Remove в свою модель представления.

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

Вы можете обратиться к следующему коду:

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);

    }
}

И код MainPage.xaml.cs:

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; }
}

Примечание:

Основываясь на приведенном выше коде, я не смог воспроизвести упомянутую вами проблему на платформах Android и Windows.

Джесси: Кажется, это очень полезно. Я попробую и отчитаюсь. Команды RE в модели представления: Да. Это устаревший код, поэтому мне еще предстоит перейти на этот подход. Это следующее в списке....

DA Consulting 25.07.2024 15:50

@Джесси: Это помогло. Но мне интересно, почему это НЕ работало в предыдущей реализации? Кажется немного странным, что элементы в представлении списка работают ДО тех пор, пока в списке не будет более двух элементов. Это похоже на ошибку, но не связанную с прокруткой (проблема была не в этом).

DA Consulting 25.07.2024 17:08

Я пытался начать без элементов в списке и добавлять их один за другим, но проблем, о которых вы говорили, не возникло. :)

Jessie Zhang -MSFT 26.07.2024 03:37
But I'm curious as to why it did NOT work in the previous implementation? Я также попробовал реализацию, которую вы опубликовали в этой задаче, но все еще не могу воспроизвести проблему. Конечно, если пользовательский интерфейс длиннее одного экрана, ListView невозможно прокручивать.
Jessie Zhang -MSFT 26.07.2024 03:46

Другие вопросы по теме