的ObservableCollection<>和ListView绑定问题

时间:2017-01-26 18:14:44

标签: c# xaml listview xamarin

我今天要来,因为我不确定了解C#中的 Binding 。我目前正在制作一个愚蠢的应用程序,以帮助我自己的课程和他们的位置。其他一些信息也会出现在应用程序中。

所以我有这个设计,这是我的4个班级的简单ListView

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>

在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");
    }
}

一切都是好的方式,我的意思是显示Debug.WriteLine();。我现在不明白的事情就是为什么我的列表视图是空的?对我来说,它没有意义,但每个人都知道,问题往往发生在计算机和主席之间,所以......我哪里错了?

我将ListView的主<ListView x:Name="CoursesListView" ...>public ObservableCollection<Course> Courses { get; set; }绑定在一起。我填写它,初始化一切,我设置绑定上下文但最后..页面是空的,为什么?

另外,我问自己另一个问题。如果我将一个集合绑定到一个列表,我可以绑定该列表视图的每个元素内的另一个列表吗?如果您感到困惑,请查看每个List<Section> Sections对象中的Course。在xaml部分,我在每个元素的中心部分都有一个列表。

我希望我的问题很明确,也许这是一个愚蠢的问题,也许这个问题很有意思,我不知道但是肯定的是,我没有,我仍然没有理解我的想法。

感谢您的帮助。

PS:如果你想要任何编辑,请告诉我。

2 个答案:

答案 0 :(得分:3)

您正在InitCoursesList函数中创建ObservableCollection。绑定(已绑定到值为null的Courses)在创建ObservableCollection时不会更新,因为您没有引发PropertyChanged事件(请参阅INotifyPropertyChanged)所以对该系列的任何添加都不会注册。解决方案是在创建包含类时创建集合:

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

然后在初始化函数中填充它:

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

当然,如果你想绑定第二个列表(ObservableCollection),你可以这样做。在Course课程中,您只需拥有ObservableCollection并将其绑定到您要用于查看该数据的任何控件。

答案 1 :(得分:1)

如果将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));

原因是,正如答案中所述,您正在重新创建ObservableCollection并破坏与旧的绑定,因为重新分配它时没有触发PropertyChanged事件。因为这是一个UIElement,所以最好只使它成为DependencyProperty而不是实现INotifyPropertyChanged,你也可以选择这样做。然后你需要在Courses属性的setter中写出一个完整的Courses属性调用PropertyChanged。

此外,您还需要更新绑定语句...它需要查看MainPage而不是DataContext。

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

或者命名您的MainPage x:Name =&#34; mainPage&#34;并使用此绑定...

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