【发布时间】:2019-12-04 12:34:36
【问题描述】:
我正在尝试使用ReactiveUI 来解决问题。我创建了一个包含以下主要包的新项目:
- Xamarin.Forms 4.1.0.618606
- PropertyChanged.Fody 3.0.1
- ReactiveUI 9.19.5
- ReactiveUI.XamForms 9.19.5
该项目有一个page 和关联的viewmodel。我想使用 ReactiveUI 将 View 与 ViewModel 绑定。但是绑定不起作用。该项目构建并运行,但不会触发任何property changed notification,也不会触发任何command。该应用程序需要显示list 的company names。但该列表不显示在 ViewModel 中定义的集合。该应用程序应允许用户使用CollectionChangeCommand 对列表进行排序,每次更改搜索query。
查看代码:
<rxui:ReactiveContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:rxui="clr-namespace:ReactiveUI.XamForms;assembly=ReactiveUI.XamForms"
xmlns:local="clr-namespace:Demo"
x:TypeArguments="local:MainViewModel"
x:Class="Demo.MainPage">
<Shell.TitleView>
<SearchBar x:Name="SearchHandler"
Placeholder="SelectCompany" />
</Shell.TitleView>
<StackLayout>
<ListView x:Name="CompaniesListView"
ItemsSource="{Binding Companies}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<StackLayout Orientation="Horizontal"
Margin="10">
<Label x:Name="NameLabel"
Text="{Binding Name}" />
</StackLayout>
<BoxView HorizontalOptions="FillAndExpand"
HeightRequest="1"
Color="BlueViolet" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Button Text="ClickMe"
x:Name="OnlyButton" />
</StackLayout>
</rxui:ReactiveContentPage>
背后的代码:
public partial class MainPage : ReactiveContentPage<MainViewModel>
{
MainViewModel vm;
public MainPage()
{
InitializeComponent();
this.Bind(ViewModel, vm => vm.Query, v => v.SearchHandler.Text);
this.BindCommand(ViewModel, vm => vm.ButtonClickedCommand, v => v.OnlyButton);
}
}
ViewModel 代码:
[AddINotifyPropertyChangedInterface]
public class MainViewModel : ReactiveObject
{
public ObservableCollection<Company> Companies { get; private set; }
public ReactiveCommand<Unit, Unit> ButtonClickedCommand { get; set; }
public ReactiveCommand<Unit, Unit> CollectionChange { get; set; }
public string Query { get; set; }
public MainViewModel()
{
Companies = new ObservableCollection<Company>
{
new Company{Name="EPF CORPORATION"},
new Company{Name="ABC COMPANY PVT. LTD."},
new Company{Name="UNIQUE COMPUTER SYSTEMS"},
new Company{Name="MICROSOFT PRIVATE LIMITED"},
};
this.WhenAny(x => x.Query, x => !string.IsNullOrWhiteSpace(x.Value));
CollectionChange = ReactiveCommand.CreateFromTask(async () => await SortCollection());
ButtonClickedCommand = ReactiveCommand.CreateFromTask(async () => await ButtonClicked());
async Task SortCollection()
{
ObservableCollection<Company> temp;
temp = new ObservableCollection<Company>(Companies.OrderByDescending(m => m.Name.ToLower().StartsWith(Query.ToLower(), StringComparison.CurrentCulture)));
Companies.Clear();
foreach (Company c in temp)
Companies.Add(c);
}
async Task ButtonClicked()
{
await Shell.Current.DisplayAlert("Button Clicked", "The reactive button command fired finally", "OK");
}
}
我只想使用ReactiveObject 和ReactiveCommand。我将坚持使用 Xamarin.Forms Shell,直到 ReactiveShell 不可用。
我将感谢任何可以向我展示如何正确使用 ReactiveUI 和 xamarin.forms 的人。
【问题讨论】:
-
嘿,您可能想提出一个Minimal, reproducible example,目前它只是一个相当大的存储库作为您的示例,不能满足最小化。
-
@GlennWatson 我修改了问题。最小可复制项目文件的链接是send.firefox.com/download/11666c7d71103813/…。该绑定适用于默认 Xamarin.Forms 绑定。但不适用于 ReactiveUI。谢谢
-
@GlennWatson 还有一个查询。如何按查询字符串升序对公司名称进行排序。
-
github.com/reactiveui/dynamicdata#sorting sort() 扩展方法只接受一个比较器,所以在你的情况下它可能是
Sort(SortExpressionComparer<Company>.Ascending(t => t.Name))