user-interface - Xamarin表单框架未随内容扩展

标签 user-interface mvvm data-binding xamarin.forms

我是Xamarin Forms的新手,我遇到了第一个挑战。我想在Listview中的Stacklayout周围放置一个Frame。当用户在Listview中选择一个项目时,我希望一些控件出现。在没有框架的情况下,此方法可以正常工作,但是当控件出现时,框架不会展开。如何更改或解决此问题?
下面的代码。

XAML:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         xmlns:local="clr-namespace:MVVMTest"
         x:Class="MVVMTest.MainPage">
<StackLayout>
    <ListView HasUnevenRows="True" SelectedItem="{Binding SelectedViewItem, Mode=TwoWay}" ItemsSource="{Binding Items}" >
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <Frame BackgroundColor="White" BorderColor="Black">
                        <StackLayout>
                            <Label Text="{Binding Name}"></Label>
                            <Entry Text="{Binding Details}" IsVisible="{Binding ShowDetails}"></Entry>
                        </StackLayout>
                    </Frame>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</StackLayout>

XAML.cs
namespace MVVMTest
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            BindingContext = new ViewModel()
            {
                Items = new List<ViewModelItem>()
                {
                    new ViewModelItem()
                    {
                        Name = "Test",
                        Details = "details"
                    },
                    new ViewModelItem()
                    {
                        Name = "Test2",
                        Details = "details2"
                    }
                }
            };
            InitializeComponent();
        }
    }
}

模型:
namespace MVVMTest
{
    public class ViewModel : INotifyPropertyChanged
    {
        private ViewModelItem _selectedViewItem;
        private List<ViewModelItem> _items;

        public event PropertyChangedEventHandler PropertyChanged;
        void OnPropertyChanged([CallerMemberName] string propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public ViewModelItem SelectedViewItem
        {
            get
            {
                return _selectedViewItem;
            }
            set
            {
                _selectedViewItem = value;
                OnPropertyChanged();
                if (value != null)
                {
                    value.ShowDetails = !value.ShowDetails;
                    SelectedViewItem = null;
                }
            }
        }

        public List<ViewModelItem> Items
        {
            get
            {
                return _items;
            }
            set
            {
                _items = value;
                OnPropertyChanged();
            }
        }

        public ViewModel()
        {

        }
    }

    public class ViewModelItem : INotifyPropertyChanged
    {
        private bool _showDetails;
        private string _details;
        private string _name;

        public event PropertyChangedEventHandler PropertyChanged;
        void OnPropertyChanged([CallerMemberName] string propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public string Name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
                OnPropertyChanged();
            }
        }

        public bool ShowDetails
        {
            get
            {
                return _showDetails;
            }
            set
            {
                _showDetails = value;
                OnPropertyChanged();
            }
        }

        public string Details
        {
            get
            {
                return _details;
            }
            set
            {
                _details = value;
                OnPropertyChanged();
            }
        }
    }
}

最佳答案

我最终使用PropertyChanged事件对ListView的显示或隐藏使用react。在事件处理程序中,我设置了Frame的HeightRequest,这迫使它自行调整大小。

替代解决方案/帮助可以在这里找到:

https://forums.xamarin.com/discussion/comment/366577

XAML:

<StackLayout>
    <ListView HasUnevenRows="True" SelectedItem="{Binding SelectedViewItem, Mode=TwoWay}" ItemsSource="{Binding Items}" >
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <Frame BackgroundColor="White" BorderColor="Black" Margin="2" Padding="2" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
                        <StackLayout>
                            <Label Text="{Binding Name}"></Label>
                            <ListView HasUnevenRows="True" Margin="2" ItemsSource="{Binding DetailObjects}" IsVisible="{Binding ShowDetails}" PropertyChanged="ListView_PropertyChanged">
                                <ListView.ItemTemplate>
                                    <DataTemplate>
                                        <ViewCell>
                                            <Entry Text="{Binding Details}"></Entry>
                                        </ViewCell>
                                    </DataTemplate>
                                </ListView.ItemTemplate>
                            </ListView>
                        </StackLayout>
                    </Frame>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</StackLayout>

后面的代码:
public partial class MainPage : ContentPage
{
    public MainPage()
    {
        BindingContext = new ViewModel()
        {
            Items = new List<ViewModelItem>()
            {
                new ViewModelItem()
                {
                    Name = "Test",
                    DetailObjects = new List<ViewModelItemDetails>
                    {
                        new ViewModelItemDetails
                        {
                            Details = "details1"
                        },
                        new ViewModelItemDetails
                        {
                            Details = "details2"
                        }
                    }
                },
                new ViewModelItem()
                {
                    Name = "Test2",
                    DetailObjects = new List<ViewModelItemDetails>
                    {
                        new ViewModelItemDetails
                        {
                            Details = "details1"
                        },
                        new ViewModelItemDetails
                        {
                            Details = "details2"
                        }
                    }
                }
            }
        };
        InitializeComponent();
    }

    private void ListView_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        if (!(sender is ListView list)) return;
        if (e.PropertyName == ListView.IsVisibleProperty.PropertyName)
        {
            Element parent = list;
            Frame frame = null;
            while (frame == null && parent != null)
            {
                if (parent is Frame) frame = parent as Frame;
                parent = parent.Parent;
            }

            if (list.IsVisible)
            {
                list.HeightRequest = list.ItemsSource.Cast<ViewModelItemDetails>().Count() * 50;

                if (frame != null) frame.HeightRequest = list.HeightRequest + 50;
            }
            else
            {
                if (frame != null) frame.HeightRequest = 50;
            }
        }
    }
}

关于user-interface - Xamarin表单框架未随内容扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54977809/

相关文章:

c# - 在事件上使用 GUI 功能 (MVVM)

WPF - 如何在 ListView 中使用当前选定项更新文本框?使用 MVVM!

c# - 如何使用CommandParameter发送列表

android - 执行数据绑定(bind)后更改包名称

.net - 将文本添加到绑定(bind)的 TextBlock

c# - 将 WPF 绑定(bind)源设置为 DataGrid 列

c++ - 如何在 C++ 中循环创建形状并将其附加到窗口?

user-interface - 功能性 GUI 用户在哪里?

qt - 通过单击 qt gui 应用程序中的按钮启动新表单?

c# - 如何在 c#/.net 中实现编辑 -> 复制菜单