更新可观察集合时,Xamarin Forms Collectionview不更新

p5cysglq  于 2023-02-27  发布在  其他
关注(0)|答案(2)|浏览(171)

我已经被这个问题困扰了很长一段时间了。这对你们来说可能很简单。
我有一个集合视图,它的项目源显示一个可观察的集合。它显示来自用户的消息时,应用程序启动,然后作为一个新的消息来,我想将新消息添加为collectionview中的第一个元素,但它发生了变形,并删除了之前的项目(仅从用户界面,而不是实际可观察的收集数据),并只显示1项。当我导航到其他页面,并返回它正确显示。有人能帮我这个。
克默尔

<CollectionView Grid.Row="1"  x:Name="myMessagesCV" SelectionMode="Single" SelectionChanged="MyMessagesCV_SelectionChanged" RemainingItemsThresholdReached="MyMessagesCV_RemainingItemsThresholdReached" RemainingItemsThreshold="5">
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <StackLayout Padding="8, 8, 8, 0">
                            <Grid Padding="0" ColumnSpacing="0" RowSpacing="0" Margin="2">
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="Auto"/>
                                    <RowDefinition Height="Auto"/>
                                </Grid.RowDefinitions>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="75"/>
                                    <ColumnDefinition Width="*"/>
                                </Grid.ColumnDefinitions>

                                <ffimageloading:CachedImage x:Name="userImage" Source="{Binding userImage}" Aspect="AspectFill" HeightRequest="75" Grid.Row="0" Grid.Column="0" CacheType="All" DownsampleToViewSize="True">
                                    <ffimageloading:CachedImage.Transformations>
                                        <transformations:CircleTransformation/>
                                    </ffimageloading:CachedImage.Transformations>
                                </ffimageloading:CachedImage>
                                
                                <Grid Grid.Row="0" Grid.Column="1" Padding="5">
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="Auto"/>
                                        <RowDefinition Height="Auto"/>
                                    </Grid.RowDefinitions>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="*"/>
                                        <ColumnDefinition Width="Auto"/>
                                    </Grid.ColumnDefinitions>
                                    <Label Padding="10, 0, 0, 5" Text="{Binding userName}" LineBreakMode="TailTruncation" TextColor="Black" FontSize="Medium" Grid.Row="0" Grid.Column="0"/>
                                    <Label Padding="10, 0, 0, 5" Text="{Binding message}" FontAttributes="{Binding newMessage}" FontSize="Small" TextColor="Black"  Grid.Row="1" Grid.Column="0"  HorizontalOptions="StartAndExpand" />
                                    <Image Grid.Row="0" Grid.Column="1" Grid.RowSpan="2" Source="dot.png" Aspect="AspectFill" WidthRequest="10" IsVisible="{Binding IsNewMessage}" HorizontalOptions="Center" VerticalOptions="Center"/>
                                </Grid>

                                <BoxView BackgroundColor="LightGray" HeightRequest="1" Grid.Row="1" Grid.Column="1"/>
                        </Grid>
                    </StackLayout>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>

页面背后的代码

public ObservableCollection<Messages> MyMessagesList = new ObservableCollection<Messages>();

      public async void GetMyMessages()
    {
        
            if (IsBusy)
                return;

            IsBusy = true;
            var messages = await FirebaseDataHelper.GetMyMessages(uid);
            var allmyMessages = await Task.WhenAll(FirebaseDataHelper.GetUserMessagesDetail(messages));

            myunreadmsg = 0;
            allmyMessagesCount = messages.Count;
            IsSubscribe = false;
            
            foreach (var message in allmyMessages)
            {
                if (message.Count > 0)
                {
                    for (int i = 0; i < message.Count; i++)
                    {
                        if (message[i].status == "Delivered" && message[i].senderId != uid)
                        {
                            message[i].newMessage = FontAttributes.Bold;
                            message[i].IsNewMessage = true;
                            myunreadmsg++;
                        }

                        if (!MyMessagesList.Any(m => m.otheruserId == message[i].otheruserId) && message[i].message != null)
                            MyMessagesList.Add(message[i]);
                    }
                }
            }

            myMessagesCV.ItemsSource = MyMessagesList;

    }

    public void GetMyNewMessages(Messages messageData)
    {
        IsSubscribe = false;
        myunreadmsg = 0;

        Messages newMessageData = new Messages();
        if (messageData.status == "Delivered" && messageData.senderId != uid)
        {
            newMessageData.newMessage = FontAttributes.Bold;
            newMessageData.IsNewMessage = true;
            newMessageData.otheruserId = messageData.otheruserId;
            newMessageData.senderId = messageData.senderId;
            newMessageData.sellerId = messageData.sellerId;
            myunreadmsg++;
        }
        else
        {
            newMessageData.newMessage = FontAttributes.None;
        }

       
        for (int i = 0; i < MyMessagesList.Count; i++)
        {
            if (MyMessagesList[i].otheruserId == messageData.otheruserId)
            {
                if (i == 0)
                {

                    MyMessagesList[i].message = messageData.message;

                    if (myunreadmsg > 0)
                    {
                        MyMessagesList[i].IsNewMessage = true;
                        MyMessagesList[i].newMessage = FontAttributes.Bold;
                    }
                    break;
                }
                else
                {
                    newMessageData.userName = MyMessagesList[i].userName;
                    newMessageData.userImage = MyMessagesList[i].userImage;
                    newMessageData.message = messageData.message;
                    newMessageData.time = messageData.time;
                    
                    newMessageData.messageId = messageData.messageId;

                    MyMessagesList.Remove(MyMessagesList[i]);
                    MyMessagesList.Insert(0, newMessageData);
                    break;
                }
            }
        }

        myMessagesCV.ItemsSource = MyMessagesList;
    }

谢谢你们希望我能解决这个问题。

zte4gxcn

zte4gxcn1#

当新消息到达时,不要像在GetMyNewMessages方法中那样再次设置ItemSource:

myMessagesCV.ItemsSource = MyMessagesList;

只需将新消息插入MyMessagesList ObservableCollection即可。

MyMessagesList.Insert(0, newMessageData);

我做了一个简单的项目来演示它。
下面是xaml:

<ContentPage
    x:Class="Search.MainPage"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    BackgroundColor="White">

    <Grid Margin="15">

        <CollectionView
            x:Name="CollectionView"
            HorizontalOptions="FillAndExpand"
            VerticalOptions="FillAndExpand">
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <Label Text="{Binding}" TextColor="Red" />
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </Grid>

</ContentPage>

下面是这个页面的代码:

public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
        }
        public ObservableCollection<int> Data { get; set; } = new ObservableCollection<int>(Enumerable.Range(1, 10));

        protected override void OnAppearing()
        {
            base.OnAppearing();

            Device.StartTimer(TimeSpan.FromSeconds(3), () =>
            {
                Data.Insert(0, new Random().Next(1, 1000));
                return true;
            });

            CollectionView.ItemsSource = Data;
        }
    }
l2osamch

l2osamch2#

在我的例子中,我定义了collectionview的名称:

<CollectionView x:Name="CollectionViewName"  
        ItemsSource="{Binding MyObservableCollection}" >
        </CollectionView>

然后在***.xaml.cs文件中查看:

public MyViewModel vm;
public MyView()
{
    InitializeComponent();
    vm = new MyViewModel();
    BindingContext = vm;
}

protected override async void OnAppearing()
{
    base.OnAppearing();
    await vm.LoadData();
    CollectionViewName.ItemsSource = null;
    CollectionViewName.ItemsSource = vm.MyObservableCollection;
}

在我的视图模型中:

[ObservableProperty]
ObservableCollection<myModel> MyObservableCollection=new ObservableCollection<myModel> ();

 [RelayCommand]
    public async Task  LoadData()
    {
        config = new PartitionSyncConfiguration($"{App.RealmApp.CurrentUser.Id}", App.RealmApp.CurrentUser);
        realm = Realm.GetInstance(config);
        try
        {
            var list = realm.All<myModel>().ToList().Where(u=> u.Field== youramount).Reverse<myModel>();

            MyObservableCollection= new ObservableCollection<myModel>(list);
        }
        catch (Exception ex)
        {
            await Application.Current.MainPage.DisplayPromptAsync("Error", ex.Message);
        }
    }

相关问题