Xamarin.Forms ListView size to content?

前端 未结 4 1872
星月不相逢
星月不相逢 2020-12-31 09:10

I have a pretty large form (adapted mainly for tablets), that has a TabbedPage nesting a ScrollView and a vertical StackPanel containi

4条回答
  •  没有蜡笔的小新
    2020-12-31 09:58

    I could make a event handler that takes into account the on the changing size of the ListView cells. Here's it:

        
                   
                        
                            
                               
    

    Frame can be changed by Grid, StackLayout, etc. xaml.cs:

            static readonly Dictionary> _listViewHeightDictionary = new Dictionary>();
    
        private void VisualElement_OnSizeChanged(object sender, EventArgs e)
        {
            var frame = (VisualElement) sender;
            var listView = (ListView)frame.Parent.Parent;
            var height = (int) frame.Measure(1000, 1000, MeasureFlags.IncludeMargins).Minimum.Height;
            if (!_listViewHeightDictionary.ContainsKey(listView))
            {
                _listViewHeightDictionary[listView] = new Dictionary();
            }
            if (!_listViewHeightDictionary[listView].TryGetValue(frame, out var oldHeight) || oldHeight != height)
            {
                _listViewHeightDictionary[listView][frame] = height;
                var fullHeight = _listViewHeightDictionary[listView].Values.Sum();
                if ((int) listView.HeightRequest != fullHeight 
                    && listView.ItemsSource.Cast().Count() == _listViewHeightDictionary[listView].Count
                    )
                {
                    listView.HeightRequest = fullHeight;
                    listView.Layout(new Rectangle(listView.X, listView.Y, listView.Width, fullHeight));
                }
            }
        }
    
        private void ListView_OnSizeChanged(object sender, EventArgs e)
        {
            var listView = (ListView)sender;
            if (listView.ItemsSource == null || listView.ItemsSource.Cast().Count() == 0)
            {
                listView.HeightRequest = 0;
            }
        }
    
    
    

    When Frame is displaying (ListView.ItemTemplate is applying), size of frame changing. We take it's actual height via Measure() method and put it into Dictionary, which knows about current ListView and holds Frame's height. When last Frame is shown, we sum all heights. If there's no items, ListView_OnSizeChanged() sets listView.HeightRequest to 0.

    提交回复
    热议问题