简体   繁体   中英

How to hide the empty rows of a list view in xamarin.forms

I have a StackLayout with a ListView and I have an add-button that I want to display right under the ListView . But the ListView displays many rows which are not used. Just empty rows, this is forcing my button to display at the bottom of the page. I've been messing with the VerticalOptions all day but cannot get the rows to disappear.

This is my XAML code :

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:LiquitMobileApp"
             x:Class="LiquitMobileApp.MainPage"
             Title="Settings"
             >

    <StackLayout BackgroundColor="LightGray">
        <Label Text="Liquit Zones" TextColor="Gray" FontSize="Small" Margin="10"/>
        <StackLayout AbsoluteLayout.LayoutBounds="10,10,10,10">
            <ListView x:Name="UsingZone" SeparatorColor="LightGray" ItemTapped="ZonesList_ItemTapped" RowHeight="60" BackgroundColor="Green"  >
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <ViewCell.ContextActions>
                                <MenuItem Clicked="OnEdit" Text="Edit" />
                                <MenuItem Clicked="OnDelete" CommandParameter="{Binding .}" Text="Trash" IsDestructive="True" />
                            </ViewCell.ContextActions>
                            <StackLayout Padding="15, 5, 0, 0" Orientation="Horizontal" BackgroundColor="White">
                                <Image Source="{Binding Image}" HorizontalOptions="Start" AbsoluteLayout.LayoutBounds="250.25, 0.25, 50, 50 "/>
                                <StackLayout Orientation="Vertical">
                                <Label Text = "{Binding Name}" FontSize="20" TextColor="Black" AbsoluteLayout.LayoutBounds="0.25, 0.25, 400, 40"/>
                                <Label Text = "{Binding Address}" TextColor="LightGray" AbsoluteLayout.LayoutBounds="50, 35, 200, 25"/>
                                </StackLayout>
                            </StackLayout>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
                <ListView.Footer>
                    <Label />
                </ListView.Footer>
            </ListView>
            <Button Text="Add Zone" TextColor="Black" HorizontalOptions="FillAndExpand" FontSize="Medium" Clicked="Button_Clicked" BackgroundColor="White"/>
        </StackLayout>
    </StackLayout>
</ContentPage>

Picture of the list and button:

列表图片和添加按钮

So, the solution I found is to force listview layout every time you add/remove an item. You also need to wrap the list in stacklayout.

<StackLayout BackgroundColor="LightGray">
    <Label Text="Liquit Zones" TextColor="Gray" FontSize="Small" Margin="10"/>

    <StackLayout>
    <ListView x:Name="ItemsListView" SeparatorColor="LightGray" BackgroundColor="Green" RowHeight="60" >
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <ViewCell.ContextActions>
                        <MenuItem Clicked="AddItemClicked" Text="Add" />
                        <MenuItem Clicked="RemoveItemClicked" CommandParameter="{Binding .}" Text="Trash" IsDestructive="True" />
                    </ViewCell.ContextActions>
                    <StackLayout Padding="15, 5, 0, 0" Orientation="Horizontal" BackgroundColor="White">
                        <Image Source="{Binding Image}" HorizontalOptions="Start"/>
                        <StackLayout Orientation="Vertical">
                            <Label Text = "{Binding ItemText}" FontSize="20" TextColor="Black" />
                            <Label Text = "{Binding ItemDetail}" TextColor="LightGray" />
                        </StackLayout>
                    </StackLayout>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
        <ListView.Footer>
            <Label />
        </ListView.Footer>
    </ListView>
    </StackLayout>

    <Button Text="Add Item" TextColor="Black" HorizontalOptions="FillAndExpand" FontSize="Medium" Clicked="AddItemClicked" BackgroundColor="White"/>
</StackLayout>

Because you know your cell height you can do this:

       void AddItemClicked(object sender, EventArgs e)
        {
            SampleData data = new SampleData();
            data.ItemText = "An Item";
            data.ItemDetail = "Item - " + (itemsListCollection.Count + 1).ToString();
            itemsListCollection.Add(data);

            ItemsListView.HeightRequest = itemsListCollection.Count * 60;
            //ForceLayout();
        }

    void RemoveItemClicked(object sender, EventArgs e)
    {

        SampleData item =(SampleData)((MenuItem)sender).CommandParameter;
        if (item != null)
        {
            itemsListCollection.Remove(item);
        }
        ItemsListView.HeightRequest = itemsListCollection.Count * 60;

    }


class SampleData:INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private string itemText;
    public string ItemText
    {
        get
        {
            return itemText;
        }
        set
        {
            itemText = value;
            NotifyPropertyChanged("ItemText");
        }
    }
    private string itemDetail;
    public string ItemDetail
    {
        get
        {
            return itemDetail;
        }
        set
        {
            itemDetail = value;
            NotifyPropertyChanged("ItemDetail");
        }
    }
    private void NotifyPropertyChanged(string propName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propName));
        }
    }
}

在此输入图像描述

An easy way to remove the empty rows of a ListView is to set an empty footer for the ListView.

ListView HeaderList = new ListView()
    {
       Footer = ""
    };

or in XAML

<ListView  x:Name="HeaderList" Footer=""></ListView>

Hi everyone,

 public class Test
 {
    string Name{get;set;}
 }

Declare globally

  ObservableCollection<Test> objWithEmpty;

In Constructor:

 objWithEmpty=new ObservableCollection<Test>();
 objWithEmpty.Add(new Test(){"Venky"});
 objWithEmpty.Add(new Test(){""});
 objWithEmpty.Add(new Test(){"Raju"});

Now take one more ObservableCollection and check the condition as per your requirement without empty then add that item to objWithOutEmpty Collection then finally add objWithOutEmpty ItemsSource to the ListView.

  ObservableCollection<Test> objWithOutEmpty;

 foreach(var item in objWithEmpty)
   {
        if(item.Name !=null)
           {
                  objWithOutEmpty.Add(new Test(){item.Name});
           }
   };

Now set ItemsSource to the ListView

 listView.ItemsSource=objWithOutEmpty;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM