【问题标题】:Xamarin Forms ListView Header ProblemsXamarin 表单 ListView 标题问题
【发布时间】:2016-11-23 20:13:34
【问题描述】:

我有一个示例项目,我正在尝试做如下两件事情。所有属性都在同一个 ViewModel 中。

我试图通过将可见性属性绑定到我的视图模型中的属性将 HeaderTemplate 中所有对象的可见性设置为 false 来隐藏标题。这是行不通的。我真正想要的是一种打开和关闭标题的方法,在代码中很好,但我更喜欢在 XAML 中。所有代码都在下面。任何建议将不胜感激。

注意:我已经尝试将所有 Header 属性放入它们自己的类中,在我的 ViewModel 中实例化该类的实例,并将 Header Binding 设置为该类,每个标题标签绑定到该类的属性。这也不起作用。

XAML 代码

<?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:SampleHeaderFooter"
         x:Class="SampleHeaderFooter.MainPage">

<ContentPage.Content>

    <!-- List of places -->
    <ListView x:Name="lvPlaces"  
                  VerticalOptions="StartAndExpand" 
                  HorizontalOptions="StartAndExpand"
                  HasUnevenRows="True"
                  ItemsSource="{Binding GBSPlaceDetails}"
                  Header="{Binding HeaderText}">
        <ListView.HeaderTemplate>
            <DataTemplate>
                <StackLayout IsVisible="False">
                    <Label x:Name="lblHeaderText" Text="{Binding .}" IsVisible="{Binding HeaderVisible}" TextColor="White" FontSize="Medium" FontAttributes="Bold" />
                    <Label x:Name="lblHeaderLink" Text="Click here to change your settings." IsVisible="{Binding HeaderVisible}" 
                           TextColor="Blue" FontSize="Medium" FontAttributes="Bold">
                        <Label.GestureRecognizers>
                            <TapGestureRecognizer Tapped="btnSettings_Clicked"/>
                        </Label.GestureRecognizers>
                    </Label>
                </StackLayout>
            </DataTemplate>
        </ListView.HeaderTemplate>
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <BoxView x:Name="bvLine" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" VerticalOptions="Center" HorizontalOptions="FillAndExpand" BackgroundColor="Black" HeightRequest="1" />
                        <Label x:Name="lblPlaceName" Grid.Row="1" Grid.Column="0"  Grid.ColumnSpan="2" BackgroundColor="Transparent" TextColor="Gray" FontAttributes="Bold" 
                                   Text="{Binding Title}" FontSize="Medium" Margin="0,4,0,4" VerticalOptions="Center" HorizontalOptions="FillAndExpand"/>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</ContentPage.Content>        

代码背后

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace SampleHeaderFooter
{
public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();
        PlacesVM lobj_PlaceVM = new PlacesVM();
        BindingContext = lobj_PlaceVM;
    }

    private void btnSettings_Clicked(object sender, EventArgs e)
    {

    }
  }
}

视图模型类

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

namespace SampleHeaderFooter
{
    public class GBSPlaceDetail
    {
        /// <summary>
        /// Name / Title of the Place
        /// </summary>
        public string Title { get; set; }
    }

    public class PlacesVM
    {
        private bool ib_HeaderVisible = false;
        private string is_HeaderText = "";

        /// <summary>
        /// Indicates if the header should be visible.  This only happens when a query was performed using the values as specified in the settings and no locations 
        /// were returned.
        /// </summary>
        public bool HeaderVisible
        {
            get
            {
                return ib_HeaderVisible;
            }

            set
            {
                ib_HeaderVisible = value;
            }
        }

        /// <summary>
        /// The Text that should appear in the header.
        /// </summary>
        public string HeaderText
        {
            get
            {
                return is_HeaderText;
            }
            set
            {
                is_HeaderText = value;
            }
        }

    /// <summary>
    /// A collection for Nearby Place objects.
    /// </summary>
    public ObservableCollection<GBSPlaceDetail> GBSPlaceDetails { get; private set; }


        /// <summary>
        /// Constructor for the Places View Model
        /// </summary>
        public PlacesVM()
        {
            this.GBSPlaceDetails = new ObservableCollection<GBSPlaceDetail>();

            this.GBSPlaceDetails.Add(new GBSPlaceDetail { Title = "Place 1" });
            this.GBSPlaceDetails.Add(new GBSPlaceDetail { Title = "Place 2" });
            this.GBSPlaceDetails.Add(new GBSPlaceDetail { Title = "Place 3" });
            this.GBSPlaceDetails.Add(new GBSPlaceDetail { Title = "Place 4" });
            this.GBSPlaceDetails.Add(new GBSPlaceDetail { Title = "Place 5" });
            this.GBSPlaceDetails.Add(new GBSPlaceDetail { Title = "Place 6" });

            HeaderVisible = false;
            HeaderText = "This is my header text.";            
        }

    }
}

【问题讨论】:

    标签: listview data-binding xamarin.forms


    【解决方案1】:

    我将标题设置为在开头可见,以便您可以单击设置文本。 几乎不需要更改。

    在 xaml 中只复制了顶部有变化的部分,其余部分相同

     <ListView x:Name="lvPlaces"
                      VerticalOptions="StartAndExpand"
                      HorizontalOptions="StartAndExpand"
                      HasUnevenRows="True"
                      ItemsSource="{Binding GBSPlaceDetails}"
                      Header="{Binding .}">
    
    
          <ListView.HeaderTemplate>
            <DataTemplate>
              <StackLayout Orientation="Vertical" IsVisible="{Binding HeaderVisible}">
                <Label x:Name="lblHeaderText" Text="{Binding HeaderText}"  TextColor="White" FontSize="Medium" FontAttributes="Bold"  />
                <Label x:Name="lblHeaderLink" Text="Click here to change your settings." 
                       TextColor="Blue" FontSize="Medium" FontAttributes="Bold">
                  <Label.GestureRecognizers>
                    <TapGestureRecognizer Tapped="btnSettings_Clicked"/>
                  </Label.GestureRecognizers>
                </Label>
              </StackLayout>
            </DataTemplate>
          </ListView.HeaderTemplate>
    

    在代码MainPage中:

    public partial class MainPage : ContentPage
    {
        PlacesVM lobj_PlaceVM;
    
        public HiddenHeaderPage()
        {
            InitializeComponent();
    
            lobj_PlaceVM = new PlacesVM();
            BindingContext = lobj_PlaceVM;
        }
    
        private void btnSettings_Clicked(object sender, EventArgs e)
        {
            lobj_PlaceVM.HeaderVisible = !lobj_PlaceVM.HeaderVisible;
        }
    }
    

    在模型代码中:

    public class PlacesVM : INotifyPropertyChanged
    {
        private bool ib_HeaderVisible = false;
        private string is_HeaderText = "";
    
        /// <summary>
        /// Indicates if the header should be visible.  This only happens when a query was performed using the values as specified in the settings and no locations 
        /// were returned.
        /// </summary>
        public bool HeaderVisible
        {
            get
            {
                return ib_HeaderVisible;
            }
    
            set
            {
                ib_HeaderVisible = value;
                OnPropertyChanged();
            }
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        /// <summary>
        /// The Text that should appear in the header.
        /// </summary>
        public string HeaderText
        {
            get
            {
                return is_HeaderText;
            }
            set
            {
                is_HeaderText = value;
            }
        }
    
        /// <summary>
        /// A collection for Nearby Place objects.
        /// </summary>
        public ObservableCollection<GBSPlaceDetail> GBSPlaceDetails { get; private set; }
    
    
        /// <summary>
        /// Constructor for the Places View Model
        /// </summary>
        public PlacesVM()
        {
            this.GBSPlaceDetails = new ObservableCollection<GBSPlaceDetail>();
    
            this.GBSPlaceDetails.Add(new GBSPlaceDetail { Title = "Place 1" });
            this.GBSPlaceDetails.Add(new GBSPlaceDetail { Title = "Place 2" });
            this.GBSPlaceDetails.Add(new GBSPlaceDetail { Title = "Place 3" });
            this.GBSPlaceDetails.Add(new GBSPlaceDetail { Title = "Place 4" });
            this.GBSPlaceDetails.Add(new GBSPlaceDetail { Title = "Place 5" });
            this.GBSPlaceDetails.Add(new GBSPlaceDetail { Title = "Place 6" });
    
            HeaderVisible = true;
            HeaderText = "This is my header text.";
        }
    
    }
    

    【讨论】:

    • 感谢您似乎已修复它。我发誓我尝试了标题 {Binding .} 但显然没有与所有其他正确的东西结合使用。再次感谢尤里。
    • 更新 - 还有一个小问题。即使在此示例中 - 当您单击链接以“隐藏”标题时 - 项目行也不会在页面上一直向上移动。似乎标题总是占用一些空间。有没有办法解决这个问题?
    • 更新解决方案:为了不让我的标题占用任何空间,我需要在标题的所有字段(StackLayout 和标签)上使用 IsVisible="{Binding HeaderVisible}"。我还需要从我的 ListView 中删除 VerticalOptions 和 Horizo​​ntalOptions。一旦我这样做了,标题就不会占用任何空间,除非它应该是可见的。希望这会有所帮助。
    猜你喜欢
    • 2021-06-12
    • 2020-02-07
    • 1970-01-01
    • 1970-01-01
    • 2015-11-05
    • 2019-02-15
    • 1970-01-01
    • 2017-08-24
    • 1970-01-01
    相关资源
    最近更新 更多