如何解决C# WPF 中的 ReactiveUI:绑定列表列表
我刚开始使用 C# 中的 ReactiveUI 和 MVVM - WPF。
我创建了一个测试项目,其目标是表示对象的链表。 一个大学列表,每个大学都有一个课程列表。在课程中,考试由学生匿名提交。 我首先只显示大学列表。这有效。
但是我无法显示课程列表。我看到一个 ListBox,但条目为空。 (为了清楚起见,我暂时省略了考试的介绍。)
- 大学0
- 课程 0
- 考试 0:待定
- 考试 1:已完成
- 课程 1
- 考试 2:正在进行中
- 考试 3:完成
- 课程 0
- 大学1
- 课程 3
- 考试 4:完成
- Exam5:完成
- 课程 3
我假设在 Universityviewmodel.cs 中我必须以某种方式绑定课程列表,但是如何绑定?
对于初学者,我使用 ReactiveUI 页面上的示例作为指南:A Compelling Example
Appviewmodel.cs
using DynamicData;
using DynamicData.Binding;
using ReactiveUI;
using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive.Linq;
namespace UniversityViewer
{
public class Appviewmodel : ReactiveObject
{
private readonly IDataProviderService _dataProviderService;
public ReadOnlyObservableCollection<Universityviewmodel> Universityviewmodels { get; }
private string _searchTerm;
public string SearchTerm
{
get => _searchTerm;
set => this.RaiseAndSetIfChanged(ref _searchTerm,value);
}
public Appviewmodel()
{
_dataProviderService = new DataProviderService();
Func<University,bool> universityFilter(string text) => university =>
{
return
string.IsNullOrEmpty(text) ||
university.Name.ToLower().Contains(text.ToLower());
};
var filterPredicate = this.WhenAnyValue(x => x.SearchTerm)
.Throttle(TimeSpan.FromMilliseconds(250),RxApp.TaskpoolScheduler)
.distinctUntilChanged()
.Select(universityFilter);
var DataLoader = _dataProviderService.Universities
.Connect()
.Filter(filterPredicate)
.Transform(university => new Universityviewmodel(university))
.sort(SortExpressionComparer<Universityviewmodel>.Ascending(u => u.Name))
.ObserveOn(RxApp.MainThreadScheduler)
.Bind(out var bindingData)
.Subscribe();
Universityviewmodels = bindingData;
}
}
}
University.cs
using System.Collections.Generic;
namespace UniversityViewer
{
public class University
{
public University(string name)
{
Name = name;
Courses = new List<Course>()
{
new Course("1234"),new Course("2345"),new Course("3456")
};
}
public string Name { get; set; }
public List<Course> Courses { get; set; }
}
}
UniversityView.xaml
<reactiveui:ReactiveUserControl
x:Class="UniversityViewer.UniversityView"
xmlns:universityViewer="clr-namespace:UniversityViewer"
x:TypeArguments="universityViewer:Universityviewmodel"
xmlns:reactiveui="http://reactiveui.net"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<Grid.RowDeFinitions>
<RowDeFinition Height="Auto" />
<RowDeFinition Height="Auto" />
</Grid.RowDeFinitions>
<TextBlock textwrapping="WrapWithOverflow"
Margin="6" VerticalAlignment="Center">
<Run FontWeight="SemiBold" x:Name="nameRun"/>
</TextBlock>
<ListBox x:Name="ListBoxCourses"
Grid.Row="1" Margin="5" HorizontalContentAlignment="Stretch"
ScrollViewer.HorizontalScrollBarVisibility="disabled" />
</Grid>
</reactiveui:ReactiveUserControl>
UniversityView.xaml.cs
using ReactiveUI;
using System.Reactive.disposables;
namespace UniversityViewer
{
public partial class UniversityView : ReactiveUserControl<Universityviewmodel>
{
public UniversityView()
{
InitializeComponent();
this.WhenActivated(disposableRegistration =>
{
this.OneWayBind(viewmodel,viewmodel => viewmodel.Name,view => view.nameRun.Text)
.disposeWith(disposableRegistration);
this.OneWayBind(viewmodel,viewmodel => viewmodel.Courses,view => view.ListBoxCourses.ItemsSource)
.disposeWith(disposableRegistration);
});
}
}
}
Universityviewmodel.cs
using ReactiveUI;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace UniversityViewer
{
public class Universityviewmodel : ReactiveObject
{
private University _university;
public ReadOnlyObservableCollection<Courseviewmodel> Courseviewmodels { get; }
public Universityviewmodel(University university)
{
_university = university;
//var DataLoader = _university.Courses
// .Connect()
// ....
//Courseviewmodels = bindingData;
}
public string Name => _university.Name;
public List<Course> Courses => _university.Courses;
}
}
Course.cs
namespace UniversityViewer
{
public class Course
{
public Course(string name)
{
Name = name;
//Exams = new List<Exam>();
}
public string Name { get; set; }
//public List<Exam> Exams { get; set; }
}
}
CourseView.xaml
<reactiveui:ReactiveUserControl
x:Class="UniversityViewer.CourseView"
xmlns:universityViewer="clr-namespace:UniversityViewer"
x:TypeArguments="universityViewer:Courseviewmodel"
xmlns:reactiveui="http://reactiveui.net"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<Grid.RowDeFinitions>
<RowDeFinition Height="Auto" />
<RowDeFinition Height="Auto" />
</Grid.RowDeFinitions>
<TextBlock textwrapping="WrapWithOverflow"
Margin="6" VerticalAlignment="Center">
<Run FontWeight="SemiBold" x:Name="nameRun"/>
</TextBlock>
<!--<ListBox x:Name="ListBoxExams"
Grid.Row="1" Margin="5" HorizontalContentAlignment="Stretch"
ScrollViewer.HorizontalScrollBarVisibility="disabled" />-->
</Grid>
</reactiveui:ReactiveUserControl>
CourseView.xaml.cs
using ReactiveUI;
using System.Reactive.disposables;
namespace UniversityViewer
{
public partial class CourseView : ReactiveUserControl<Courseviewmodel>
{
public CourseView()
{
InitializeComponent();
this.WhenActivated(disposableRegistration =>
{
this.OneWayBind(viewmodel,view => view.nameRun.Text)
.disposeWith(disposableRegistration);
});
}
}
}
Courseviewmodel.cs
using ReactiveUI;
namespace UniversityViewer
{
public class Courseviewmodel : ReactiveObject
{
private Course _course;
public Courseviewmodel(Course course)
{
_course = course;
}
public string Name => _course.Name;
}
}
解决方法
为了解析 UniversityView
,CourseViewModels
应该绑定到 Courses
而不是 CourseView
:
this.OneWayBind(ViewModel,viewModel => viewModel.CourseViewModels,view => view.ListBoxCourses.ItemsSource)
.DisposeWith(disposableRegistration);
然后您需要填充 CourseViewModels
集合。
应该从 Courses
中删除 UniversityViewModel
属性。 ReactiveUserControl
没有要解析的 Course
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。