c# - Xamarin Forms 动态 ListView

标签 c# xamarin xamarin.ios xamarin.android xamarin.forms

我正在尝试在 xamarin.forms 中创建一个有点复杂的列表。用户应该能够点击列表中的一个项目,它应该会扩展成更大的东西。较大的项目现在应该显示一些与此 View 专门关联的其他 UI 组件。

我想知道我应该如何解决这个问题。它是关于具有动态大小项目的 ListView 。单击该项目将显示与该项目相关的其他 View 。这应该在 Xamarin.ios 和 Xamarin.droid 中完成,还是建议尝试在 xamarin.forms 中实现?

我会张贴一张图片,它不是很好,可能需要一些放大,但它显示了 4 个项目。第 3 个已展开,因此您可以在其上看到微调器和按钮。

一次只能展开一个项目(我可能必须在 ViewModel 中处理它)并且在按下另一个项目时,旧的项目应该被隐藏。

The list

编辑:

感谢 Rohit,我开始在 Xamarin.Forms 中实现一个解决方案,但它并没有真正发挥作用,只是在如何扩展行方面出现了一些小问题。见下图。为了简单起见,我跳过了微调器,只使用了一个按钮。展开的行与其下方的行重叠。第一张图片是点击之前的图片,第二张图片是点击名为“Two”的项目之后的图片。

查看

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="simpletest.PlayGroundPage">
    <ContentPage.Content>
        <StackLayout>
            <ListView VerticalOptions="FillAndExpand" HasUnevenRows="True" ItemsSource="{Binding AllItems}" SelectedItem="{Binding MySelectedItem}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <StackLayout VerticalOptions="FillAndExpand">
                            <StackLayout VerticalOptions="FillAndExpand" Orientation="Horizontal">
                                <Label Text="{Binding MyText}" />
                                <Image Source="{Binding MyImage}" />
                            </StackLayout>
                            <Button Text="button1" IsVisible="{Binding IsExtraControlsVisible}" />  
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

元素

    public class Item : INotifyPropertyChanged
    {


        public Item(string text, string image, int id)
        {
            _myText = text;
            _myImage = image;
            _id = id;
            _isExtraControlsVisible = false;

        }

        private string _myText;
        private string _myImage;
        private bool _isExtraControlsVisible;
        private int _id;

        public event PropertyChangedEventHandler PropertyChanged;

        public int Id { get { return _id; } set { _id = value; } }

        public string MyText
        {
            get { return _myText; }
            set { _myText = value; OnPropertyChanged("MyText"); }
        }
        public string MyImage
        {
            get { return _myImage; }
            set { _myImage = value; OnPropertyChanged("MyImage"); }
        }
        public bool IsExtraControlsVisible
        {
            get { return _isExtraControlsVisible; }
            set { _isExtraControlsVisible = value; OnPropertyChanged("IsExtraControlsVisible"); }
        }

        private void OnPropertyChanged(string property)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(property));
            }
        }
    }

View 模型:

    class PlayGroundViewModel : INotifyPropertyChanged
    {
        private Item _mySelectedItem;



        public PlayGroundViewModel(ObservableCollection<Item> allItems)
        {
            AllItems = allItems;
            _mySelectedItem = allItems.First();
        }
        public ObservableCollection<Item> AllItems { get; set; }

        public Item MySelectedItem
        {
            get { return _mySelectedItem; } //Added a field for this one, mainly for debugging.
            set
            {

                foreach (Item x in AllItems) //Changed to non-linq since it is not a list.
                {
                    x.IsExtraControlsVisible = false;
                }

                if (value != null)
                {
                    foreach (Item x in AllItems)
                    {
                        if (x.Id.Equals(value.Id))
                        {
                            x.IsExtraControlsVisible = true;
                            _mySelectedItem = x;
                        }
                    }
                }

                SetChangedProperty("MySelectedItem");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void SetChangedProperty(string property)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(property));
            }
        }

    }

代码隐藏:

    public partial class PlayGroundPage : ContentPage
    {
        public PlayGroundPage()
        {
            InitializeComponent();
            ObservableCollection<Item> items = new ObservableCollection<Item>();
            items.Add(new Item("One", "", 0));
            items.Add(new Item("Two", "", 1));
            items.Add(new Item("Three", "", 2));
            PlayGroundViewModel weekViewModel = new PlayGroundViewModel(items);
            BindingContext = weekViewModel;
        }
    }

Before clicking on a row

After having clicked

最佳答案

您可以使用 XAML、ViewModel、ObservableCollection 通过以下方式实现它。

XAML:

<ListView VerticalOption="FillAndExpand" HasUnevenRows="True" 
 ItemsSource="{Binding AllItems}" SelectedItem="{Binding MySelectedItem}" >
 <ListView.ItemTemplate>
   <DataTemplate>
      <ViewCell>
         <StackLayout VerticalOptions="FillAndExpand">
            <StackLayout VerticalOptions="FillAndExpand" Orientation="Horizontal">
               <Label Text="{Binding MyText}" />
               <Image Source="{Binding MyImage}" />
            </StackLayout>
            <Button Text="button" IsVisible="{Binding IsExtraControlsVisible}" />
            <Spinner IsVisible="{Binding IsExtraControlsVisible}" />
         </StackLayout>
      </ViewCell> 
   </DataTemplate>
 </ListView.ItemTemplate>
</ListView>

View 模型:

public ObservableCollection<Item> AllItems
{
    get { return _allItems; }
    set
    {
        _allItems = value;
        OnPropertyChanged();
     }
}
public Item MySelectedItem
{
    get { return _mySelectedItem; }
    set
    {
        _mySelectedItem = value;
        OnPropertyChanged();

        foreach (var item in AllItems)
        {
            item.IsExtraControlsVisible = false;
        }
        var selectedItem = AllItems.FirstOrDefault(x => x.Equals(value));
        if (selectedItem != null)
        {
            selectedItem.IsExtraControlsVisible = true;
        }
    }
}

项目.cs:

public class Item : INotifyPropertyChanged
{
   private string _myText;
   private string _myImage;
   private bool _isExtraControlsVisible;
   private int _id;

   public int Id { get; set; }
   public string MyText 
   {
       get{ return _myText; } 
       set
       { _myText = value; 
          OnPropertyChanged();
       } 
   }
   public string MyImage
   {
       get{ return _myImage; } 
       set
       {
            _myImage = value; 
            OnPropertyChanged();
       } 
   }
   public bool IsExtraControlsVisible
   {
       get{ return _isExtraControlsVisible; } 
       set
       {
           _isExtraControlsVisible = value;
           OnPropertyChanged();
       } 
   }
}

请在此处找到演示 - XamarinForms_Dynamic_ListView_Item .

关于c# - Xamarin Forms 动态 ListView ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38702566/

相关文章:

c# - 从返回 403 forbidden 的网站解析

c# - 当属性具有相同的 DisplayName 时,PropertyGrid 选择错误?

java - 使用 ViewPager 在 Xamarin.Android 上以轮播样式显示图像幻灯片并使用突出的子项进行填充,Viewpager 错误地计算参数

android - 将 Card.IO 移植到 C# Xamarin Studio

Xamarin iOS WKWebView DidFinishNavigation 和 DidStartProvisionalNavigation 没有被调用

xcode - 如何在Xcode项目中使用MonoTouch库?

c# - 跨 UNC 复制文件

c# - 需要时髦的 LINQ(第 2 部分)

wcf - Visual Studio 2015 + Xamarin + native 可移植 PCL + WCF

ios - 将 iOS 静态库绑定(bind)到 Xamarin.iOS 并使用 dll