Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
反应列表更新不';在UITableView中,似乎无法第一次正确编组_Uitableview_Xamarin_Xamarin.ios_Reactiveui - Fatal编程技术网

反应列表更新不';在UITableView中,似乎无法第一次正确编组

反应列表更新不';在UITableView中,似乎无法第一次正确编组,uitableview,xamarin,xamarin.ios,reactiveui,Uitableview,Xamarin,Xamarin.ios,Reactiveui,我在正确刷新UITableView时遇到问题,至少第一次出现视图时,有时(很少)甚至可能会挂起应用程序。当我通过更改选项卡项离开UIViewController并向后导航时,在整个生命周期中,一切都开始完美工作 具有如下所示的ReactiveTableViewSource public class ATableViewSource : ReactiveTableViewSourceBase<IAViewModel> { WeakReference<AListViewCo

我在正确刷新UITableView时遇到问题,至少第一次出现视图时,有时(很少)甚至可能会挂起应用程序。当我通过更改选项卡项离开UIViewController并向后导航时,在整个生命周期中,一切都开始完美工作

具有如下所示的ReactiveTableViewSource

public class ATableViewSource : ReactiveTableViewSourceBase<IAViewModel>
{
    WeakReference<AListViewController> _weakContainer;
    Lazy<AListViewController> _lazyContainerViewController;

    AListViewController Container => _lazyContainerViewController.Value;

    public ATableViewSource(AListViewController container,
                            UITableView tableView,
                            IReactiveNotifyCollectionChanged<IAViewModel> collection)
        : base(tableView, collection,
                ATableViewCell.Key,
                ATableViewCell.Height,
                ATableViewCell.Height)
    {
        _weakContainer = new WeakReference<AListViewController>(container);
        tableView.RegisterNibForCellReuse(ATableViewCell.Nib, ATableViewCell.Key);

        _lazyContainerViewController = new Lazy<AListViewController>(() =>
        {
            AListViewController _container;
            _weakContainer.TryGetTarget(out _container);
            return _container;
        });
    }

    public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
    {
        base.RowSelected(tableView, indexPath);

        tableView.DeselectRow(indexPath, false);
        var item = ItemAt(indexPath) as IAViewModel;
        if (item.IsNotNull())
        {
            AViewController viewController = new AViewController(item);
          Container.NavigationController.PushViewController(viewController, true);
        }
    }
}
在视图中,我总是刷新数据(ViewModel.TheReactiveList)

AViewModel设置

public class TheListViewModel : SchedulersViewModelBase, ITheListViewModel
{
    public ReactiveList<IAViewModel> TheReactiveList { get; } = new ReactiveList<IAViewModel> { ChangeTrackingEnabled = true };

    protected readonly IDataService DataService;

    public TheListViewModel(IScheduler mainScheduler,
                            IScheduler taskPoolScheduler,
                            IDataService dataService)
            : base(mainScheduler, taskPoolScheduler)
    {
        DataService = dataService;
    }

    public void RefreshTheReactiveList()
    {
        DataService.RefreshData()
                    .SubscribeOn(MainScheduler)
                    .ObserveOn(MainScheduler)
                    .Subscribe(ClearDataAndAddRange,
                                ex => AppObservables.Errors.OnNext(ex))
                    .DisposeWith(Disposables);
    }

    void ClearDataAndAddRange(IEnumerable<IAViewModel> data)
    {
        using (TheReactiveList.SuppressChangeNotifications())
        {
            TheReactiveList.Clear();
            TheReactiveList.AddRange(data);
        }
    }
}
公共类ListViewModel:SchedulerViewModelBase,ITheListViewModel
{
public ReactiveList TheReactiveList{get;}=new ReactiveList{ChangeTrackingEnabled=true};
受保护的只读IDataService数据服务;
公共视图模型(ISScheduler Main Scheduler,
IsScheduler taskPoolScheduler,
IDataService(数据服务)
:基本(mainScheduler、taskPoolScheduler)
{
数据服务=数据服务;
}
public void refreshtereactivelist()
{
DataService.RefreshData()
.SubscribeOn(主计划程序)
.ObserveOn(主调度器)
.订阅(ClearDataandAddress,
ex=>AppObservables.Errors.OnNext(ex))
.一次性使用(一次性使用);
}
无效ClearDataAndAddressRange(IEnumerable数据)
{
使用(TheReactiveList.SuppressChangeNotifications())
{
TheReactiveList.Clear();
TheReactiveList.AddRange(数据);
}
}
}
我必须提到,在这个用例中,我有一个父UIViewController和两个子控制器,每个子控制器都具有相同的设置(UITableView、ReactiveTableViewSource、ViewModel.ReactiveList),并且它们的UIView容器的隐藏状态是受控的,但我注意到UIViewController也有类似的效果,一个UITableView最多需要3秒钟才能在UITableView中显示结果

我在下面发布了
ReactiveTableViewSourceBase
供您参考,我很久以前在互联网上就发现了这个问题,所以它可能很可疑。不过,将基类更改为
ReactiveTableViewSource
并没有什么区别

public abstract class ReactiveTableViewSourceBase<TViewModel> : ReactiveTableViewSource<TViewModel>, IInformsEnd
{
    private readonly Subject<Unit> _requestMoreSubject = new Subject<Unit>();
    private readonly Subject<CGPoint> _scrollSubject = new Subject<CGPoint>();

    public IObservable<CGPoint> DidScroll
    {
        get { return _scrollSubject.AsObservable(); }
    }

    public IObservable<Unit> RequestMore
    {
        get { return _requestMoreSubject; }
    }

    public override void Scrolled(UIScrollView scrollView)
    {
        _scrollSubject.OnNext(scrollView.ContentOffset);
    }

    ~ReactiveTableViewSourceBase()
    {
        Console.WriteLine("Destorying " + GetType().Name);
    }

    protected ReactiveTableViewSourceBase(UITableView tableView, nfloat height, nfloat? heightHint = null)
            : base(tableView)
    {
        tableView.RowHeight = height;
        tableView.EstimatedRowHeight = heightHint ?? tableView.EstimatedRowHeight;
    }

    protected ReactiveTableViewSourceBase(UITableView tableView, IReactiveNotifyCollectionChanged<TViewModel> collection,
            Foundation.NSString cellKey, nfloat height, nfloat? heightHint = null, Action<UITableViewCell> initializeCellAction = null)
            : base(tableView, collection, cellKey, (float)height, initializeCellAction)
    {
        tableView.RowHeight = height;
        tableView.EstimatedRowHeight = heightHint ?? tableView.EstimatedRowHeight;
    }

    public override void WillDisplay(UITableView tableView, UITableViewCell cell, Foundation.NSIndexPath indexPath)
    {
        if (indexPath.Section == (NumberOfSections(tableView) - 1) &&
            indexPath.Row == (RowsInSection(tableView, indexPath.Section) - 1))
        {
            // We need to skip an event loop to stay out of trouble
            BeginInvokeOnMainThread(() => _requestMoreSubject.OnNext(Unit.Default));
        }
    }

    public override void RowSelected(UITableView tableView, Foundation.NSIndexPath indexPath)
    {
        var item = ItemAt(indexPath) as ICanGoToViewModel;
        if (item != null)
        {
            item.GoToCommand.Execute();
        }

        base.RowSelected(tableView, indexPath);
    }

    protected override void Dispose(bool disposing)
    {
        _requestMoreSubject.Dispose();
        _scrollSubject.Dispose();
        base.Dispose(disposing);
    }
}

public interface IInformsEnd
{
    IObservable<Unit> RequestMore { get; }
}
公共抽象类ReactiveTableViewSourceBase:ReactiveTableViewSource,IInformsEnd
{
私有只读主题_requestmorepubject=新主题();
私有只读主题_scrollSubject=新主题();
公共IObservable卷
{
获取{return\u scrollSubject.AsObservable();}
}
公共IObservable请求更多
{
获取{return\u requestmorepubject;}
}
公共覆盖无效滚动(UIScrollView滚动视图)
{
_scrollSubject.OnNext(scrollView.ContentOffset);
}
~ReactiveTableViewSourceBase()
{
WriteLine(“Destorying”+GetType().Name);
}
受保护的ReactiveTableViewSourceBase(UITableView tableView,nfloat高度,nfloat?heightHint=null)
:基础(表格视图)
{
tableView.RowHeight=高度;
tableView.EstimatedRowHeight=高度提示??tableView.EstimatedRowHeight;
}
受保护的ReactiveTableViewSourceBase(UITableView tableView、IReactiveNotifyCollectionChanged collection、,
NSCONCELL CELKEY,NFLULT高度,NFLULT?HEEGHUNTITT = NULL,Actudio RealAlgEcEccult=空值)
:基础(tableView、集合、cellKey、(浮动)高度、initializeCellAction)
{
tableView.RowHeight=高度;
tableView.EstimatedRowHeight=高度提示??tableView.EstimatedRowHeight;
}
公共覆盖空WillDisplay(UITababVIEW TabLVIEW,UITabelVIEW cell cell,基础.NSIXDEXPATH索引路径)
{
if(indexPath.Section==(NumberOfSections(tableView)-1)&&
indexPath.Row==(RowsInSection(tableView,indexPath.Section)-1)
{
//我们需要跳过事件循环以避免麻烦
BeginInvokeOnMainThread(()=>_requestMoreSubject.OnNext(Unit.Default));
}
}
公共覆盖空行选择(UITababVIEW TabLVIEW,基础.NSIXDEXPATH索引路径)
{
var item=ItemAt(indexPath)作为ICanGoToViewModel;
如果(项!=null)
{
item.GoToCommand.Execute();
}
base.RowSelected(tableView,indexPath);
}
受保护的覆盖无效处置(布尔处置)
{
_requestMoreSubject.Dispose();
_scrollSubject.Dispose();
基地。处置(处置);
}
}
公共接口IInformsEnd
{
IObservable RequestMore{get;}
}
public class TheListViewModel : SchedulersViewModelBase, ITheListViewModel
{
    public ReactiveList<IAViewModel> TheReactiveList { get; } = new ReactiveList<IAViewModel> { ChangeTrackingEnabled = true };

    protected readonly IDataService DataService;

    public TheListViewModel(IScheduler mainScheduler,
                            IScheduler taskPoolScheduler,
                            IDataService dataService)
            : base(mainScheduler, taskPoolScheduler)
    {
        DataService = dataService;
    }

    public void RefreshTheReactiveList()
    {
        DataService.RefreshData()
                    .SubscribeOn(MainScheduler)
                    .ObserveOn(MainScheduler)
                    .Subscribe(ClearDataAndAddRange,
                                ex => AppObservables.Errors.OnNext(ex))
                    .DisposeWith(Disposables);
    }

    void ClearDataAndAddRange(IEnumerable<IAViewModel> data)
    {
        using (TheReactiveList.SuppressChangeNotifications())
        {
            TheReactiveList.Clear();
            TheReactiveList.AddRange(data);
        }
    }
}
public abstract class ReactiveTableViewSourceBase<TViewModel> : ReactiveTableViewSource<TViewModel>, IInformsEnd
{
    private readonly Subject<Unit> _requestMoreSubject = new Subject<Unit>();
    private readonly Subject<CGPoint> _scrollSubject = new Subject<CGPoint>();

    public IObservable<CGPoint> DidScroll
    {
        get { return _scrollSubject.AsObservable(); }
    }

    public IObservable<Unit> RequestMore
    {
        get { return _requestMoreSubject; }
    }

    public override void Scrolled(UIScrollView scrollView)
    {
        _scrollSubject.OnNext(scrollView.ContentOffset);
    }

    ~ReactiveTableViewSourceBase()
    {
        Console.WriteLine("Destorying " + GetType().Name);
    }

    protected ReactiveTableViewSourceBase(UITableView tableView, nfloat height, nfloat? heightHint = null)
            : base(tableView)
    {
        tableView.RowHeight = height;
        tableView.EstimatedRowHeight = heightHint ?? tableView.EstimatedRowHeight;
    }

    protected ReactiveTableViewSourceBase(UITableView tableView, IReactiveNotifyCollectionChanged<TViewModel> collection,
            Foundation.NSString cellKey, nfloat height, nfloat? heightHint = null, Action<UITableViewCell> initializeCellAction = null)
            : base(tableView, collection, cellKey, (float)height, initializeCellAction)
    {
        tableView.RowHeight = height;
        tableView.EstimatedRowHeight = heightHint ?? tableView.EstimatedRowHeight;
    }

    public override void WillDisplay(UITableView tableView, UITableViewCell cell, Foundation.NSIndexPath indexPath)
    {
        if (indexPath.Section == (NumberOfSections(tableView) - 1) &&
            indexPath.Row == (RowsInSection(tableView, indexPath.Section) - 1))
        {
            // We need to skip an event loop to stay out of trouble
            BeginInvokeOnMainThread(() => _requestMoreSubject.OnNext(Unit.Default));
        }
    }

    public override void RowSelected(UITableView tableView, Foundation.NSIndexPath indexPath)
    {
        var item = ItemAt(indexPath) as ICanGoToViewModel;
        if (item != null)
        {
            item.GoToCommand.Execute();
        }

        base.RowSelected(tableView, indexPath);
    }

    protected override void Dispose(bool disposing)
    {
        _requestMoreSubject.Dispose();
        _scrollSubject.Dispose();
        base.Dispose(disposing);
    }
}

public interface IInformsEnd
{
    IObservable<Unit> RequestMore { get; }
}