ContentView 内的 Xamarin 表单编辑器无法正确调整大小或换行文本

Xamarin forms Editor inside ContentView doesn't resize or wrap text properly

因此,我在代码中声明了一个编辑器,该编辑器绑定到 ListView 的自定义 ViewCell 中 StackLayout 中的 ContentView 的内容 属性,如果编辑器,它要么不会换行文本,要么不会调整大小以适应它。如果我启用 AutoSize,文本不会换行并且会离开屏幕。如果我禁用 AutoSize,编辑器会正确换行文本,但它一次只显示一行文本,并且每当 XAML 热重载刷新屏幕时,文本就会“展开”。我该如何解决这些问题?

我替换了 XAML 中的所有内容和我认为与“...”无关的代码。

我的XAML:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="Partylist.Views.ChecklistPage">
    ...
    
    <ContentPage.Content>
        <!--Main layout of the page-->
        <StackLayout>
            <!--ListView of the checklist items-->
            <ListView x:Name="ChecklistView"
                      ItemSelected="OnItemSelected"
                      HasUnevenRows="true">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <!--These context actions are buttons that appear
                            when you long press the item (Android) or swipe 
                            left (iOS).-->
                            <ViewCell.ContextActions>
                                <MenuItem Clicked="OnDelete"
                                          CommandParameter="{Binding .}"
                                          Text="Delete"
                                          IsDestructive="true"/>
                            </ViewCell.ContextActions>
                            <!--This is the actual content-->
                            <StackLayout Orientation="Horizontal"
                                         Padding="20,5"
                                         VerticalOptions="FillAndExpand">
                                <ContentView Content="{Binding ItemCheckbox}"/>
                                <ContentView Content="{Binding ItemEditor}"
                                             HorizontalOptions="FillAndExpand"
                                             VerticalOptions="FillAndExpand"/>
                            </StackLayout>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>

            ...
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

我的代码:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace Partylist.Views
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class ChecklistPage : ContentPage
    {
        // Struct for items on the checklist.
        struct Item
        {
            public Editor ItemEditor { get; set; }
            public CheckBox ItemCheckbox { get; set; }
        }
        // Create a list of contact structs to populate the ListView.
        ObservableCollection<Item> items;
        // Flag for when an item is added to the list.
        bool itemAdded = false;

        ...

        // Override for OnAppearing().
        protected override void OnAppearing()
        {
            ...
            // Set the binding context of the page to itself.
            BindingContext = this;
            ...

            // Make the ObservableCOllection reference something.
            items = new ObservableCollection<Item>();
            // Open a stream to the list that we want to display.
            StreamReader listReader = new StreamReader(App.selectedList
                .ListFile.FullName);
            // Loop through the file and read data into the list.
            while (!listReader.EndOfStream)
            {
                // Create a blank item.
                Item newItem = new Item()
                {
                    ItemEditor = new Editor()
                    {
                        Text = listReader.ReadLine(),
                        Placeholder = "New Item",
                        IsTabStop = true,
                        //AutoSize = EditorAutoSizeOption.TextChanges
                    },
                    ItemCheckbox = new CheckBox()
                    {
                        Color = App.selectedList.ListItemColor,
                        IsChecked = bool.Parse(listReader.ReadLine())
                    }
                };
                // Subscribe OnCompleted() to the new item's "Completed" 
                // event.
                newItem.ItemEditor.Completed += OnCompleted;
                // Subscribe OnTextChanged() to the new item's 
                // "TextChanged" event.
                newItem.ItemEditor.TextChanged += OnTextChanged;
                // Add the new item to the list.
                items.Add(newItem);
                // Make the ListView update.
                ChecklistView.ItemsSource = items;
                OnPropertyChanged("contacts");
            }
            // Once everything is loaded, close the file.
            listReader.Close();
        }

        ...

        // Function for when the "Add New Contact" button is clicked.
        private void OnAddNewItemClicked(object sender, EventArgs e)
        {
            // Create a blank item.
            Item newItem = new Item()
            {
                ItemEditor = new Editor()
                {
                    Placeholder = "New Item",
                    IsTabStop = true,
                    //AutoSize = EditorAutoSizeOption.TextChanges
                },
                ItemCheckbox = new CheckBox()
                {
                    Color = App.selectedList.ListItemColor,
                    IsChecked = false
                }
            };
            // Subscribe OnCompleted() to the new item's "Completed" 
            // event.
            newItem.ItemEditor.Completed += OnCompleted;
            // Subscribe OnTextChanged() to the new item's 
            // "TextChanged" event.
            newItem.ItemEditor.TextChanged += OnTextChanged;
            // Add the new contact to the list.
            items.Add(newItem);
            // Set the "itemAdded" flag to true.
            itemAdded = true;
            // Make the ListView update.
            ChecklistView.ItemsSource = items;
            OnPropertyChanged("contacts");
            // Select the new item.
            ChecklistView.SelectedItem = items.ElementAt(items.Count - 1);
        }

        // Function for when an item is selected, used to set the focus to
        // a newly added item in the list.
        private async void OnItemSelected(object sender, SelectedItemChangedEventArgs e)
        {
            // Only runs this if an item was added (as opposed to being 
            // read in from the file).
            if (itemAdded)
            {
                if (e.SelectedItem == null) return;
                await Task.Delay(100); // Change the delay time if Focus() doesn't work.
                ((Item)e.SelectedItem).ItemEditor.Focus();
                ChecklistView.SelectedItem = null;
                itemAdded = false;
            }
        }

        // Function for when the user presses "Return" on the keyboard in
        // an editor.
        private void OnCompleted(object sender, EventArgs e)
        {
            // We just want to unfocus the editor.
            ((Editor)sender).Unfocus();
        }

        // Function for when the user types anything in the editor, used 
        // to make sure it resizes.
        private void OnTextChanged(object sender, TextChangedEventArgs e)
        {
            // Makes the cell resize. The cell is the parent of the 
            // StackLayout which is the parent of the ContentView which is
            // the parent of the Editor that fired the event.
            ((ViewCell)((Editor)sender).Parent.Parent.Parent)
                .ForceUpdateSize();
        }

        ...
    }
}

通常当我们使用 Editor 时,我们用 StackLayout 包裹它,这将其最大宽度限制为 StackLayout。但是,在这里,您使用了不限制宽度的 ContentView。它默认为无限宽度,因此它始终是单行显示,您可以尝试将 WidthRequest 添加到 Editor.

 ItemEditor = new Editor()
      {
          Placeholder = "New Item",
          IsTabStop = true,
          WidthRequest = 200,
          AutoSize = EditorAutoSizeOption.TextChanges
      }