简体   繁体   English

ObservableCollection <>和ListView绑定问题

[英]ObservableCollection<> and ListView binding issue

I'm coming today because I'm not sure to understand something about the Binding in C#. 我今天来是因为我不确定要了解有关C#中的绑定的一些知识。 I'm currently making a stupid app to help myself with my classes and their locations. 我目前正在制作一个愚蠢的应用程序,以帮助自己了解自己的课程及其位置。 Some others information also comes in the app. 该应用程序中还包含其他一些信息。

So I have this design, which is a simple ListView of my 4 classes. 所以我有这个设计,这是我的4个类的简单ListView

MainPage.xaml : MainPage.xaml:

<ContentPage.Content>
    <AbsoluteLayout>
        <Label
            AbsoluteLayout.LayoutBounds="0.5, 0, 1, 0.1"
            AbsoluteLayout.LayoutFlags="All"
            Text="My CSULB Schedule" />
        <ListView x:Name="CoursesListView" ItemsSource="{Binding Courses}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="2*" />
                            <RowDefinition Height="6*" />
                            <RowDefinition Height="2*" />
                        </Grid.RowDefinitions>
                        <!--  TOP  -->
                        <Grid Grid.Row="0">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="2*" />
                                <ColumnDefinition Width="6*" />
                                <ColumnDefinition Width="2*" />
                            </Grid.ColumnDefinitions>
                            <Label
                                Grid.Column="0"
                                HorizontalTextAlignment="Center"
                                Text="{Binding DaysToString}"
                                VerticalTextAlignment="Center" />
                            <Label
                                Grid.Column="1"
                                HorizontalTextAlignment="Center"
                                Text="{Binding Title}"
                                VerticalTextAlignment="Center" />
                            <Label
                                Grid.Column="2"
                                HorizontalTextAlignment="Center"
                                Text="{Binding TypeAndNumber}"
                                VerticalTextAlignment="Center" />
                        </Grid>
                        <!--  Top  -->
                        <!--  Center  -->
                        <ListView Grid.Row="1" ItemsSource="{Binding Sections}">
                            <ListView.ItemTemplate>
                                <DataTemplate>
                                    <Grid>
                                        <Grid.RowDefinitions>
                                            <ColumnDefinition Width="25*" />
                                            <ColumnDefinition Width="5*" />
                                            <ColumnDefinition Width="25*" />
                                        </Grid.RowDefinitions>
                                    </Grid>
                                    <Label
                                        Grid.Column="0"
                                        HorizontalTextAlignment="Center"
                                        Text="{Binding Location}"
                                        VerticalTextAlignment="Center" />
                                    <Label
                                        Grid.Column="1"
                                        HorizontalTextAlignment="Center"
                                        Text="{Binding TeacherName}"
                                        VerticalTextAlignment="Center" />
                                    <Label
                                        Grid.Column="2"
                                        HorizontalTextAlignment="Center"
                                        Text="{Binding Time}"
                                        VerticalTextAlignment="Center" />
                                </DataTemplate>
                            </ListView.ItemTemplate>
                        </ListView>
                        <!--  Center  -->
                        <!--  Bottom  -->
                        <Grid Grid.Row="2">
                            <Grid.RowDefinitions>
                                <ColumnDefinition Width="1*" />
                                <ColumnDefinition Width="8*" />
                                <ColumnDefinition Width="1*" />
                            </Grid.RowDefinitions>
                            <!-- Useless stuff at the moment -->
                        </Grid>
                        <!--  Bottom  -->
                    </Grid>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </AbsoluteLayout>
</ContentPage.Content>

In the CS part, I have this: 在CS部分,我有以下内容:

MainPage.xaml.cs : MainPage.xaml.cs:

public partial class MainPage : ContentPage
{
    public ObservableCollection<Course> Courses { get; set; }

    public MainPage()
    {
        base.BindingContext = this;
        Debug.WriteLine("1.");
        InitCoursesList();
        Debug.WriteLine("2.");
        InitializeComponent();
        Debug.WriteLine("3.");
        //CoursesListView.ItemsSource = Courses;
    }

    private void InitCoursesList()
    {
        Debug.WriteLine("1.1");
        this.Courses = new ObservableCollection<Course>()
        {
            new Course()
            {
                Days = new List<Course.Day>() { Course.Day.M, Course.Day.W },
                Title = "Object Oriented Programming",
                Type = "CECS",
                Number = "274",
                Sections = new List<Section>()
                {
                    new Section()
                    {
                        Location = "VEC-419",
                        TeacherName = "Foss S",
                        Time = "1-1:50pm"
                    },
                    new Section()
                    {
                        Location = "ECS-414",
                        TeacherName = "Foss S",
                        Time = "2-3:15pm"
                    }
                }
            },
            new Course()
            {
                Days = new List<Course.Day>() { Course.Day.M, Course.Day.W },
                Title = "Adv Artificial Intelligence",
                Type = "CECS",
                Number = "551",
                Sections = new List<Section>()
                {
                    new Section()
                    {
                        Location = "VEC-331",
                        TeacherName = "Todd Ebert",
                        Time = "3:30-4:45pm"
                    }
                }
            },
            new Course()
            {
                Days = new List<Course.Day>() { Course.Day.Tu, Course.Day.Th },
                Title = "Operating Syetems",
                Type = "CECS",
                Number = "326",
                Sections = new List<Section>()
                {
                    new Section()
                    {
                        Location = "VEC-330",
                        TeacherName = "Lam S",
                        Time = "9:30-10:20am"
                    },
                    new Section()
                    {
                        Location = "ECS-416",
                        TeacherName = "Lam S",
                        Time = "10:30-11:45am"
                    }
                }
            },
            new Course()
            {
                Days = new List<Course.Day>() { Course.Day.Tu, Course.Day.Th },
                Title = "C++ for Java Developers",
                Type = "CECS",
                Number = "282",
                Sections = new List<Section>()
                {
                    new Section()
                    {
                        Location = "VEC-518",
                        TeacherName = "Nachawati S",
                        Time = "11-11:50am"
                    },
                    new Section()
                    {
                        Location = "ECS-403",
                        TeacherName = "Nachawati S",
                        Time = "12-1:15pm"
                    }
                }
            },
        };
        Debug.WriteLine("1.2");
    }
}

Everything is coming in the good way, I mean the display of the Debug.WriteLine(); 一切都很好,我的意思是显示Debug.WriteLine(); . The thing I don't understand now it's why my listview is empty? 我现在不了解的事情是为什么列表视图为空? For me, it doesn't make sense but everyone knows that, often, the problem comes between the computer and the chair so.. Where am I wrong? 对我来说,这没有道理,但每个人都知道,问题通常出在电脑和椅子之间,所以..我在哪里错了?

I bind my main ListView which is <ListView x:Name="CoursesListView" ...> with my public ObservableCollection<Course> Courses { get; set; } 我将我的主ListView绑定为<ListView x:Name="CoursesListView" ...>与我的public ObservableCollection<Course> Courses { get; set; } public ObservableCollection<Course> Courses { get; set; } public ObservableCollection<Course> Courses { get; set; } . public ObservableCollection<Course> Courses { get; set; } I fill it, initalize everything, I set the binding context but at the end.. The page is empty, why? 我填充它,初始化所有内容,但设置了绑定上下文,但最后。.页面为空,为什么?

Also I was asking to myself another question. 我也在问自己另一个问题。 If I bind a collection to a list, can I bind another list inside of every element of this list view? 如果我将集合绑定到列表,是否可以在此列表视图的每个元素内绑定另一个列表? If you are confuse, take a look at the List<Section> Sections in every Course object. 如果您感到困惑,请查看每个Course对象中的List<Section> Sections In the xaml part, I have a list in the center part of each element. 在xaml部分,每个元素的中心部分都有一个列表。

I hope my question is clear, maybe it's a stupid question, maybe this question is interesting, I don't know but for sure, I didn't and I still don't understand something I think. 我希望我的问题很清楚,也许这是一个愚蠢的问题,也许这个问题很有趣,我不知道,但是可以肯定的是,我没有,我仍然不明白我的想法。

Thank for your help. 谢谢您帮忙。

PS: Tell me if you want any edit. PS:告诉我是否要进行编辑。

You're creating the ObservableCollection in your InitCoursesList function. 您正在InitCoursesList函数中创建ObservableCollection The binding, which will have already bound to Courses with a value of null, won't update when you create the ObservableCollection because you're not raising the PropertyChanged event (see INotifyPropertyChanged ) so any additions to the collection won't register. 当您创建ObservableCollection时,该绑定将已经与Courses绑定,其值将为null,因为您没有引发PropertyChanged事件(请参阅INotifyPropertyChanged ),所以不会更新该绑定,因此对该集合的任何添加都不会注册。 The solution is to create the collection when the containing class is created: 解决方案是在创建包含类时创建集合:

public ObservableCollection<Course> Courses { get; set; } = new ObservableCollection<Course>();

And then just populate it in the initialise function: 然后在初始化函数中填充它:

private void InitCoursesList()
{
    Courses.Add(new Course { etc });
}

And of course, if you wanted to bind a second list ( ObservableCollection ) you can do that. 当然,如果您想绑定第二个列表( ObservableCollection ),则可以这样做。 In your Course class you'd simply have an ObservableCollection and bind that to whatever control you want to use to view that data. 在您的Course类中,您仅具有一个ObservableCollection并将其绑定到您想要用来查看该数据的任何控件。

Your code will work if you change the Courses property to a dependency property. 如果将Courses属性更改为依赖项属性,则代码将起作用。

public ObservableCollection<Course> Courses
    {
        get { return (ObservableCollection<Course>)GetValue(CoursesProperty); }
        set { SetValue(CoursesProperty, value); }
    }

public static readonly DependencyProperty CoursesProperty =
        DependencyProperty.Register(nameof(Courses), typeof(ObservableCollection<Course>), typeof(MainPage));

The reason is, as stated in an answer already, is that you're re-creating the ObservableCollection and breaking the binding to the old one because there is no PropertyChanged event fired when you re-assigned it. 正如已经在一个答案中所述,其原因是您正在重新创建ObservableCollection并中断与旧对象的绑定,因为在重新分配它时不会触发PropertyChanged事件。 Since this is a UIElement it is best to just make this a DependencyProperty rather than implementing INotifyPropertyChanged, which you also have the choice of doing. 由于这是一个UIElement,因此最好将其设置为DependencyProperty而不是实现INotifyPropertyChanged,您也可以选择这样做。 Then you would need to write out a full Courses property call PropertyChanged in the setter of the Courses property. 然后,您需要在Courses属性的设置器中写出完整的Courses属性调用PropertyChanged。

Furthermore you need to update your binding statement as well... It needs to look at the MainPage rather than the DataContext. 此外,您还需要更新绑定语句...它需要查看MainPage而不是DataContext。

ItemsSource="{Binding Courses, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MainPage}}}

Or name your MainPage x:Name="mainPage" and use this binding... 或命名您的MainPage x:Name =“ mainPage”并使用此绑定...

ItemsSource="{Binding Courses, ElementName=mainPage}"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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