Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/314.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
C# Xamarin.iOS CollectionView-添加新元素会刷新整个列表_C#_Xamarin_Xamarin.forms_Xamarin.ios_Nscollectionview - Fatal编程技术网

C# Xamarin.iOS CollectionView-添加新元素会刷新整个列表

C# Xamarin.iOS CollectionView-添加新元素会刷新整个列表,c#,xamarin,xamarin.forms,xamarin.ios,nscollectionview,C#,Xamarin,Xamarin.forms,Xamarin.ios,Nscollectionview,我正在构建一个xamarin.forms聊天应用程序,只需要添加交付的新元素,在Android上我有预期的行为,但iOS刷新了所有的CollectionView是什么导致了糟糕的用户体验。请看一看我的代码(仅相关部分),让我知道我做错了什么,或者我错过了什么,以便在iOS上也有这种行为 My.xaml: <CollectionView x:Name="ChatCollectionView" SelectionMode="None" Hori

我正在构建一个xamarin.forms聊天应用程序,只需要添加交付的新元素,在Android上我有预期的行为,但iOS刷新了所有的CollectionView是什么导致了糟糕的用户体验。请看一看我的代码(仅相关部分),让我知道我做错了什么,或者我错过了什么,以便在iOS上也有这种行为

My.xaml:

<CollectionView x:Name="ChatCollectionView" 
    SelectionMode="None" HorizontalScrollBarVisibility="Never" 
    VerticalScrollBarVisibility="Always" ItemsUpdatingScrollMode="KeepLastItemInView"
    ItemTemplate="{StaticResource MsgTemplateSelector}" Margin="5,0,5,10">
</CollectionView>

.cs文件:


public static ReaderWriterLockSlim valuesLock = new ReaderWriterLockSlim();
void ObservableCollectionCallback(IEnumerable collection, object context, Action accessMethod, bool writeAccess)
{
    var collectionLock = (ReaderWriterLockSlim)context;
    Action enterLock = writeAccess ? new Action(collectionLock.EnterWriteLock) : new Action(collectionLock.EnterReadLock);
    Action exitLock = writeAccess ? new Action(collectionLock.ExitWriteLock) : new Action(collectionLock.ExitReadLock);

    enterLock();
    try { accessMethod(); } finally { exitLock(); }
}

ObservableCollection<Msg> ListMsg;

public Page(string userid, string chatkey, string titulo, string foto)
{
    // some code ...
    this.BindingContext = this;
    BindingBase.EnableCollectionSynchronization(ListMsg as IEnumerable, valuesLock,ObservableCollectionCallback);

    List<Msg> recipient = await Task.Run(()=> client.PostData<List<Msg>>("url/msg.php")); 
    //previous line returns a json and deserialize it to a list of "Msg"

    if (recipient != null)
    {
        ListMsg = new ObservableCollection<Msg>(recipient);
        
        ChatCollectionView.ItemsSource = ListMsg;
            
        if (ListMsg.Count > 0)
        {
            if(Device.RuntimePlatform==Device.iOS)
                await Task.Delay(2000);

            ChatCollectionView.ScrollTo(ListMsg.Count - 1, position: ScrollToPosition.End, animate: false);
        }
    }
    else
        ChatCollectionView.ItemsSource = new ObservableCollection<Msg>(); 

    MessagingCenter.Subscribe<MainPage, Msg>("Page", "scroll", async (sender, arg) =>
    {
        Task.WaitAll(tasks.ToArray());

        tasks.Add(Task.Run(async () =>
        {
            arg = await MsgPrepare(arg); //this only changes the element arg not the list
            _ = Device.InvokeOnMainThreadAsync(() =>
            {
                valuesLock.EnterWriteLock();
                try { ListMsg.Add(arg); }
                finally { valuesLock.ExitWriteLock(); }
            });
        }));
    }

}






公共静态ReaderWriterLockSlim值lock=new ReaderWriterLockSlim();
void observeCollectionCallback(IEnumerable集合、对象上下文、操作访问方法、bool writeAccess)
{
var collectionLock=(ReaderWriterLockSlim)上下文;
Action enterLock=writeAccess?新操作(collectionLock.EnterWriteLock):新操作(collectionLock.EnterReadLock);
Action exitLock=writeAccess?新操作(collectionLock.ExitWriteLock):新操作(collectionLock.ExitRecordLock);
enterLock();
尝试{accessMethod();}最后{exitLock();}
}
可观察收集列表msg;
公共页面(字符串userid、字符串chatkey、字符串titulo、字符串foto)
{
//一些代码。。。
this.BindingContext=this;
BindingBase.EnableCollectionSynchronization(ListMsg作为IEnumerable、valuesLock、ObservableCollectionCallback);
List recipient=wait Task.Run(()=>client.PostData(“url/msg.php”);
//前一行返回json并将其反序列化为“Msg”列表
如果(收件人!=null)
{
ListMsg=新的可观察收集(接收人);
ChatCollectionView.ItemsSource=ListMsg;
如果(ListMsg.Count>0)
{
if(Device.RuntimePlatform==Device.iOS)
等待任务。延迟(2000);
ChatCollectionView.ScrollTo(ListMsg.Count-1,位置:ScrollToPosition.End,动画:false);
}
}
其他的
ChatCollectionView.ItemsSource=新的ObservableCollection();
MessagingCenter.Subscribe(“页面”,“滚动”,异步(发送方,参数)=>
{
Task.WaitAll(tasks.ToArray());
tasks.Add(Task.Run)(异步()=>
{
arg=await MsgPrepare(arg);//这只会更改元素arg,而不会更改列表
_=Device.InvokeOnMainThreadAsync(()=>
{
valuesLock.EnterWriteLock();
请尝试{ListMsg.Add(arg);}
最后{valuesLock.ExitWriteLock();}
});
}));
}
}

通过“错误”修复了它。我添加了涉及整个页面的内容,以修复iOS软键盘的问题(涵盖了重点输入元素)答对了,它已经解决了这两个问题。如果我去掉ScrollView,问题又回来了。我还注意到,如果ScrollView只包含CollectionView,它就可以工作,而不需要像我的情况那样覆盖整个页面。另一点是,如果你不想要ScrollView的滚动功能,你可以设置Orientation=两者都不能避免它。希望这能帮助你们。

我不明白
ListMsg
ListMsg
是如何关联的。我也不知道
收件人来自哪里。什么是
observeCollectionCallback
?请更详细地解释代码应该如何执行。可能需要提供更多的代码。这是一个键入错误它们是同一个对象,只存在ListMsg。当然,我会提供更多详细信息。@ToolMakerSte为了更好地理解,刚刚添加了更多代码。感谢您的关注。我没有发现您的代码中有任何缺陷。作为测试,如果您不使用
ObservableCollectionCallback
,问题是否仍然会出现?我想知道您的代码是否有一些限制Xamarin支持该特性的iOS代码(我意识到代码的存在有一个很好的理由;只是想看看XForms在内部管理时的行为,而不需要回调)