Xamarin.Forms,XAML,绑定和isVisible

时间:2018-08-31 21:26:49

标签: c# xamarin xamarin.forms

我(显然是关于这个问题)对此并不熟悉,所以在此先感谢您的帮助!希望在数小时内努力做到这一点时,我希望有人可以加快我的学习速度:)

附录:我也发布了Xamarin论坛,但是就问题的解答数量而言,这似乎已经死了。因此,我希望没人冒犯。

所以,我有XAML主页:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="cant post links"
             xmlns:x="cant post links"
             xmlns:local="clr-namespace:App.ViewModels"
             x:Class="App.ViewModels.MainPage">

    <ContentPage.BindingContext>
        <local:User/>
    </ContentPage.BindingContext>

    <StackLayout>
        <Label Text="Test"/>
        <ListView ItemsSource="{Binding Changes}"
                  x:Name="ChangesList"
                  HasUnevenRows="True"
                  Margin="40,80"
                  ItemTapped="ListView_ItemTapped">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <StackLayout>
                            <Label Text="{Binding Name}"/>
                            <Button Text="Details"
                                    IsVisible="{Binding IsVisible}"/>
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
        <Button Text="Press to add" x:Name="addItem" Clicked="addItem_Clicked"/>
    </StackLayout>

</ContentPage>

我有一个带有相应属性的数据模型。当我离开MainPage类构造函数时,如下所示:

public MainPage()
{
    InitializeComponent();
}

我没有看到列表项。

因此,第一个问题:我认为,基于绑定,该应用程序会自动生成一个User实例并将其分配给列表?

正如我在调试器中看到的那样,实际上生成了一个User实例,并将其分配给BindingContext,但是ChangesList.ItemsSource保持为空。

因此,我更改了构造函数的代码:

public MainPage()
{
    InitializeComponent();
    var bc = BindingContext;
    var list = ChangesList.ItemsSource;
    ChangesList.ItemsSource = (bc as User).Changes;
}

这使我在编译和运行应用程序时看到包含项目的列表。另外,我可以通过“ addItem”按钮后面的代码将新项目添加到列表中。但是:当我点击一个项目时,什么也没有发生。代码如下:

private void ListView_ItemTapped(object sender, ItemTappedEventArgs e)
{
    var change = e.Item as Change;
    change.IsVisible = !change.IsVisible;
}

和Data方法如下:

 public class Change : INotifyPropertyChanged
{
    public string Name { get; set; }
    bool isVisible = false;

    public event PropertyChangedEventHandler PropertyChanged;

    public bool IsVisible
    {
        get
        {
            return isVisible;
        }
        set
        {
            isVisible = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Change-IsVisible"));
        }
    }
}

因此,第二个问题是:为什么Button不更改其可见性状态而变得可见?

非常感谢您!

编辑:添加了完整的“更改”类代码。

编辑2:用户代码。

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.ComponentModel;
using Xamarin.Forms;
using System.Diagnostics;

namespace App.ViewModels
{
    public class User : INotifyPropertyChanged
    {
        public string Username { get; set; }
        public ObservableCollection<Change> Changes = null;   
        public event PropertyChangedEventHandler PropertyChanged;

        public User()
        {
            Changes = new ObservableCollection<Change>();
            addChange("Test 1");
            addChange("Test 2");

        }

        public void addChange(string text)
        {
            Change c = new Change
            {
                Name = text,
                IsVisible = false
            };
            Changes.Add(c);
            refresh();
        }

        public void refresh()
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Changes"));
        }
    }
}

2 个答案:

答案 0 :(得分:0)

对于第二个问题-尝试:

PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("IsVisible"));

第一个问题-您能否分享您的用户源代码

答案 1 :(得分:0)

尝试以下操作:

将您的User类中的获取器/设置器更改为:

public string Username
{
    get { return username;}
    set { username = value; OnPropertyChanged("Username");
}
private string username = string.Empty;

public ObservableCollection<Change> Changes
{
    get { return changes; }
    set { changes = value; OnPropertyChanged("Changes");
}
private ObservableCollection<Change> changes = null;

向类添加新方法:     公共无效OnPropertyChanged(字符串propertyName)     {         PropertyChanged?.Invoke(this,new PropertyChangedEventArgs(propertyName));     }

然后确保您在Changes类中相应地实现了上面修改的代码。

最后在MainPage类构造函数中设置页面的绑定上下文:

public MainPage(User user)
{
    InitializeComponent();
    BindingContext = user;
}

一些解释: 绑定上下文必须包含您的数据模型类,在您的情况下为User。

您在做什么

var bc = BindingContext;
ChangesList.ItemsSource = (bc as User).Changes;

正在尝试将未设置的MainPage BindingContext强制转换为User。

因此,为了在Xaml中使用BindingContext,必须将其设置为用户类的实例,否则屏幕上将不会显示任何数据。