Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 表单、XAML、绑定和isVisible_C#_Xamarin_Xamarin.forms - Fatal编程技术网

C# 表单、XAML、绑定和isVisible

C# 表单、XAML、绑定和isVisible,c#,xamarin,xamarin.forms,C#,Xamarin,Xamarin.forms,我(显然,关于这个问题)对这个问题还不熟悉,所以提前感谢您的帮助!由于我已经为此努力了好几个小时,我希望有人能加快我的学习速度:) 增编:我也在Xamarin论坛上发表了文章,但就问题的答案数量而言,这似乎是死胡同。因此,我希望没有人生气 因此,我有我的XAML主页: <?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="cant post links" xmlns:x="cant po

我(显然,关于这个问题)对这个问题还不熟悉,所以提前感谢您的帮助!由于我已经为此努力了好几个小时,我希望有人能加快我的学习速度:)

增编:我也在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>
我看不到列表项

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

正如我在调试器中看到的,实际上生成了一个用户实例,并将其分配给BindingContext,但ChangesList.ItemsSource仍然为null

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

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;
}
数据方法如下所示:

 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"));
        }
    }
}
因此,第二个问题是:为什么按钮不更改其可见性状态并变为可见?

提前非常感谢

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

编辑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"));
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Collections.ObjectModel;
使用系统文本;
使用系统组件模型;
使用Xamarin.Forms;
使用系统诊断;
名称空间App.ViewModels
{
公共类用户:INotifyPropertyChanged
{
公共字符串用户名{get;set;}
公共ObservableCollection变更=null;
公共事件属性更改事件处理程序属性更改;
公共用户()
{
更改=新的ObservableCollection();
添加变更(“测试1”);
添加变更(“测试2”);
}
公共void addChange(字符串文本)
{
变更c=新变更
{
名称=文本,
IsVisible=false
};
增加(c);
刷新();
}
公共无效刷新()
{
PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(“更改”);
}
}
}

对于第二个问题,请尝试:

PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("IsVisible"));
对于第一个问题-您能否共享您的用户源代码?请尝试以下操作:

public MainPage()
{
    InitializeComponent();
}
将用户类中的getter/setter更改为:

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;
一些解释: 绑定上下文必须包含您的数据模型类(以用户为例)

你在干什么

var bc = BindingContext;
ChangesList.ItemsSource = (bc as User).Changes;
正在尝试将主页的未设置BindingContext强制转换为用户,该内容将为空


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

您的模型是否实现了INotifyPropertyChanged?谢谢您的提问。我认为是这样。在第一篇文章中,我用完整的类代码替换了“IsVisible”方法代码。在这里,您可以看到ChangeViewModel实现了INotifyPropertyChanged方法。非常感谢您回答了第二个问题!很明显。。。对于第一个问题,我在我的第一篇文章中添加了用户代码。嗨,马库斯,非常感谢你的详细回答。一个问题:我必须以编程方式设置BindingContext吗?我想,如果我在Mainpage.XAML文件中定义它就足够了。我通常从codebehind中定义它,但是如果用户类的构造函数确保您有可用的数据,而不仅仅是一个初始化为零值的简单类对象,那么从Mainpage XAML中定义也应该做到这一点。基本上,这在很大程度上取决于您的业务逻辑和处理数据的方式。非常感谢你!
var bc = BindingContext;
ChangesList.ItemsSource = (bc as User).Changes;