我今天要来,因为我不确定了解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部分,我在每个元素的中心部分都有一个列表。
我希望我的问题很明确,也许这是一个愚蠢的问题,也许这个问题很有意思,我不知道但是肯定的是,我没有,我仍然没有理解我的想法。
感谢您的帮助。
答案 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}"