在扩展上更新列表视图 [英] Update list view on expand

查看:64
本文介绍了在扩展上更新列表视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编码一个Xamarin.Forms项目,并且有一个列表视图,但是每当显示隐藏的内容时,例如,使一个条目可见,ViewCell就会与它下面的条目重叠.

有没有办法我可以.Update()列表视图或一些刷新它并使它们都适合的方法.

我不希望刷新使它回到顶部.

当我显示某些东西时,Android似乎能够自动更新高度.

我尝试使用HasUnevenRows="True",但这仍然不能解决问题.

代码:

Message.xaml

<StackLayout>
        <local:PostListView x:Name="MessageView" HasUnevenRows="True" IsPullToRefreshEnabled="True" Refreshing="MessageView_Refreshing" SeparatorVisibility="None" BackgroundColor="#54a0ff">
            <local:PostListView.ItemTemplate>
                <DataTemplate>
                    <local:PostViewCell>
                        <StackLayout>
                            <Frame CornerRadius="10" Padding="0" Margin="10, 10, 10, 5" BackgroundColor="White">
                                <StackLayout>
                                    <StackLayout x:Name="MessageLayout" BackgroundColor="Transparent" Padding="10, 10, 15, 10">
                                        ...
                                        <Label Text="{Binding PostReply}" FontSize="15" TextColor="Black" Margin="10, 0, 0, 10" IsVisible="{Binding ShowReply}"/>
                                        <StackLayout Orientation="Vertical" IsVisible="{Binding ShowReplyField}" Spacing="0">
                                            <Entry Text="{Binding ReplyText}" Placeholder="Reply..." HorizontalOptions="FillAndExpand" Margin="0, 0, 0, 5"/>
                                            ...
                                        </StackLayout>
                                        <StackLayout x:Name="MessageFooter" Orientation="Horizontal" IsVisible="{Binding ShowBanners}">
                                            <StackLayout Orientation="Horizontal">
                                                ...
                                                <Image x:Name="ReplyIcon" Source="reply_icon.png" HeightRequest="20" HorizontalOptions="StartAndExpand" IsVisible="{Binding ShowReplyButton}">
                                                    <Image.GestureRecognizers>
                                                        <TapGestureRecognizer Command="{Binding ReplyClick}" CommandParameter="{Binding .}"/>
                                                    </Image.GestureRecognizers>
                                                </Image>
                                                ... 
                                            </StackLayout>
                                            ...
                                        </StackLayout>
                                    </StackLayout>
                                </StackLayout>
                            </Frame>
                        </StackLayout>
                    </local:PostViewCell>
                </DataTemplate>
            </local:PostListView.ItemTemplate>
        </local:PostListView>
    </StackLayout>

Message.cs

    using Newtonsoft.Json;
 using SocialNetwork.Classes;
 using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Net.Http;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace SocialNetwork
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MessagePage : ContentPage
{
    public MessagePage()
    {
        InitializeComponent();
        LoadPage();
    }

    private async void LoadPage()
    {
        await LoadMessages();
    }

    private async void RefreshPage()
    {
        await LoadMessages();
        MessageView.EndRefresh();
    }

    private async Task LoadMessages()
    {
        //*Web Request*
        MessageView.ItemsSource = FormatPosts(this, Navigation, page_result);
        ...
    }

    public IList<MessageObject> FormatPosts(Page page, INavigation navigation, string json)
    {
        IList<MessageObject> Posts = new List<MessageObject>() { };
        var messages = JsonConvert.DeserializeObject<List<Message>>(json);

        foreach (var message in messages)
        {
            MessageObject mo = MessageObject.CreateMessage(...);
            Posts.Add(mo);
        }

        return Posts;
    }
    public async void ShowOptionActions(string id, string poster_id, object message)
    {
        ...
    }

    public async void ShowReportOptions(string id, string poster_id)
    {
        ...
    }

    public void SubmitReplyClick(string id, object msg)
    {
        ...
    }

    public async void SendReplyAsync(string id, object msg, string reply)
    {
        await SendReply(id, msg, reply);
    }

    public void ReplyCommandClick(string id, object msg)
    {
        MessageObject message = (MessageObject) msg;
        message.ShowReplyField = message.ShowReplyField ? false : true;
        //Update Cell Bounds
    }

    private async Task SendReply(string id, object msg, string reply)
    {
        MessageObject message = (MessageObject)msg;
        ...
        message.PostReply = reply;

        //Update Cell Bounds
    }

    public async void LikeMessageClick(string id, object message)
    {
        await LikeMessage(id, message);
    }

    private async Task LikeMessage(string id, object msg)
    {
       ...
    }

    public async void DeleteMessage(string id, object msg)
    {
        MessageObject message = (MessageObject)msg;

        message.ShowBanners = false;
        message.ShowReply = false;

        ...

        //Update Cell Bounds
    }

    public async Task ReportMessage(...)
    {
        ...
    }

    private void MessageView_Refreshing(object sender, EventArgs e)
    {
        RefreshPage();
    }
}

public class MessageObject : INotifyPropertyChanged
{
    private Boolean showBannersValue = true;
    private string replyValue = String.Empty;
    private bool showReplyValue;
    private bool showReplyButtonValue;
    private bool showReplyFieldValue;
    private Command replyCommandValue;
    private Command replySubmitValue;
    private string replyTextValue;
     ...

    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    private MessageObject(...)
    {
        ...
    }

    public static MessageObject CreateMessage(...)
    {
        return new MessageObject(...);
    }

    public Boolean ShowBanners
    {
        get
        {
            return this.showBannersValue;
        }

        set
        {
            if (value != this.showBannersValue)
            {
                this.showBannersValue = value;
                NotifyPropertyChanged();
            }
        }
    }

    public Boolean ShowReplyField
    {
        get
        {
            return this.showReplyFieldValue;
        }

        set
        {
            if(value != this.showReplyFieldValue)
            {
                this.showReplyFieldValue = value;
                NotifyPropertyChanged();
            }
        }
    }

    public string PostReply
    {
        get
        {
            return this.replyValue;
        }

        set
        {
            if (value != this.replyValue)
            {
                this.replyValue = value;
                NotifyPropertyChanged();
            }
        }
    }

    public Boolean ShowReply
    {
        get
        {
            return this.showReplyValue;
        }

        set
        {
            if(value != this.showReplyValue)
            {
                this.showReplyValue = value;
                NotifyPropertyChanged();
            }
        }
    }

    public Boolean ShowReplyButton
    {
        get
        {
            return this.showReplyButtonValue;
        }

        set
        {
            if (value != this.showReplyButtonValue)
            {
                this.showReplyButtonValue = value;
                NotifyPropertyChanged();
            }
        }
    }

      public string ReplyText
    {
        get
        {
            return this.replyTextValue;
        }

        set
        {
            if(value != this.replyTextValue)
            {
                this.replyTextValue = value;
                NotifyPropertyChanged();
            }
        }
    }

    public Command ReplyClick
    {
        get
        {
            return this.replyCommandValue;
        }

        set
        {
            if (value != this.replyCommandValue)
            {
                this.replyCommandValue = value;
                NotifyPropertyChanged();
            }
        }
    }

    ...

}
}

解决方案

将通过FormatPosts方法返回的IList<MessageObject>保存在字段IList<MessageObject> _messages = new List<MessageObject>()

并在需要时使用以下代码片段更新ListView,其中包括检查设备是否在iOS上运行:

if(Device.RuntimePlatform == Device.iOS) 
{ 
    MessageView.ItemsSource = null; 
    MessageView.ItemsSource = _messages; 
}

I am coding a Xamarin.Forms project and I have a list view but whenever I show hidden content, for example, make an entry visible it the ViewCell overlaps the one beneath it.

Is there a way I could .Update() the listview or something to refresh it and make them all fit.

I don't want the refresh to cause it to go back to the top though.

Android seems to be able to automatically update the height when I show something.

I tried using HasUnevenRows="True" but that still didn't fix it.

Code:

Message.xaml

<StackLayout>
        <local:PostListView x:Name="MessageView" HasUnevenRows="True" IsPullToRefreshEnabled="True" Refreshing="MessageView_Refreshing" SeparatorVisibility="None" BackgroundColor="#54a0ff">
            <local:PostListView.ItemTemplate>
                <DataTemplate>
                    <local:PostViewCell>
                        <StackLayout>
                            <Frame CornerRadius="10" Padding="0" Margin="10, 10, 10, 5" BackgroundColor="White">
                                <StackLayout>
                                    <StackLayout x:Name="MessageLayout" BackgroundColor="Transparent" Padding="10, 10, 15, 10">
                                        ...
                                        <Label Text="{Binding PostReply}" FontSize="15" TextColor="Black" Margin="10, 0, 0, 10" IsVisible="{Binding ShowReply}"/>
                                        <StackLayout Orientation="Vertical" IsVisible="{Binding ShowReplyField}" Spacing="0">
                                            <Entry Text="{Binding ReplyText}" Placeholder="Reply..." HorizontalOptions="FillAndExpand" Margin="0, 0, 0, 5"/>
                                            ...
                                        </StackLayout>
                                        <StackLayout x:Name="MessageFooter" Orientation="Horizontal" IsVisible="{Binding ShowBanners}">
                                            <StackLayout Orientation="Horizontal">
                                                ...
                                                <Image x:Name="ReplyIcon" Source="reply_icon.png" HeightRequest="20" HorizontalOptions="StartAndExpand" IsVisible="{Binding ShowReplyButton}">
                                                    <Image.GestureRecognizers>
                                                        <TapGestureRecognizer Command="{Binding ReplyClick}" CommandParameter="{Binding .}"/>
                                                    </Image.GestureRecognizers>
                                                </Image>
                                                ... 
                                            </StackLayout>
                                            ...
                                        </StackLayout>
                                    </StackLayout>
                                </StackLayout>
                            </Frame>
                        </StackLayout>
                    </local:PostViewCell>
                </DataTemplate>
            </local:PostListView.ItemTemplate>
        </local:PostListView>
    </StackLayout>

Message.cs

    using Newtonsoft.Json;
 using SocialNetwork.Classes;
 using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Net.Http;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace SocialNetwork
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MessagePage : ContentPage
{
    public MessagePage()
    {
        InitializeComponent();
        LoadPage();
    }

    private async void LoadPage()
    {
        await LoadMessages();
    }

    private async void RefreshPage()
    {
        await LoadMessages();
        MessageView.EndRefresh();
    }

    private async Task LoadMessages()
    {
        //*Web Request*
        MessageView.ItemsSource = FormatPosts(this, Navigation, page_result);
        ...
    }

    public IList<MessageObject> FormatPosts(Page page, INavigation navigation, string json)
    {
        IList<MessageObject> Posts = new List<MessageObject>() { };
        var messages = JsonConvert.DeserializeObject<List<Message>>(json);

        foreach (var message in messages)
        {
            MessageObject mo = MessageObject.CreateMessage(...);
            Posts.Add(mo);
        }

        return Posts;
    }
    public async void ShowOptionActions(string id, string poster_id, object message)
    {
        ...
    }

    public async void ShowReportOptions(string id, string poster_id)
    {
        ...
    }

    public void SubmitReplyClick(string id, object msg)
    {
        ...
    }

    public async void SendReplyAsync(string id, object msg, string reply)
    {
        await SendReply(id, msg, reply);
    }

    public void ReplyCommandClick(string id, object msg)
    {
        MessageObject message = (MessageObject) msg;
        message.ShowReplyField = message.ShowReplyField ? false : true;
        //Update Cell Bounds
    }

    private async Task SendReply(string id, object msg, string reply)
    {
        MessageObject message = (MessageObject)msg;
        ...
        message.PostReply = reply;

        //Update Cell Bounds
    }

    public async void LikeMessageClick(string id, object message)
    {
        await LikeMessage(id, message);
    }

    private async Task LikeMessage(string id, object msg)
    {
       ...
    }

    public async void DeleteMessage(string id, object msg)
    {
        MessageObject message = (MessageObject)msg;

        message.ShowBanners = false;
        message.ShowReply = false;

        ...

        //Update Cell Bounds
    }

    public async Task ReportMessage(...)
    {
        ...
    }

    private void MessageView_Refreshing(object sender, EventArgs e)
    {
        RefreshPage();
    }
}

public class MessageObject : INotifyPropertyChanged
{
    private Boolean showBannersValue = true;
    private string replyValue = String.Empty;
    private bool showReplyValue;
    private bool showReplyButtonValue;
    private bool showReplyFieldValue;
    private Command replyCommandValue;
    private Command replySubmitValue;
    private string replyTextValue;
     ...

    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    private MessageObject(...)
    {
        ...
    }

    public static MessageObject CreateMessage(...)
    {
        return new MessageObject(...);
    }

    public Boolean ShowBanners
    {
        get
        {
            return this.showBannersValue;
        }

        set
        {
            if (value != this.showBannersValue)
            {
                this.showBannersValue = value;
                NotifyPropertyChanged();
            }
        }
    }

    public Boolean ShowReplyField
    {
        get
        {
            return this.showReplyFieldValue;
        }

        set
        {
            if(value != this.showReplyFieldValue)
            {
                this.showReplyFieldValue = value;
                NotifyPropertyChanged();
            }
        }
    }

    public string PostReply
    {
        get
        {
            return this.replyValue;
        }

        set
        {
            if (value != this.replyValue)
            {
                this.replyValue = value;
                NotifyPropertyChanged();
            }
        }
    }

    public Boolean ShowReply
    {
        get
        {
            return this.showReplyValue;
        }

        set
        {
            if(value != this.showReplyValue)
            {
                this.showReplyValue = value;
                NotifyPropertyChanged();
            }
        }
    }

    public Boolean ShowReplyButton
    {
        get
        {
            return this.showReplyButtonValue;
        }

        set
        {
            if (value != this.showReplyButtonValue)
            {
                this.showReplyButtonValue = value;
                NotifyPropertyChanged();
            }
        }
    }

      public string ReplyText
    {
        get
        {
            return this.replyTextValue;
        }

        set
        {
            if(value != this.replyTextValue)
            {
                this.replyTextValue = value;
                NotifyPropertyChanged();
            }
        }
    }

    public Command ReplyClick
    {
        get
        {
            return this.replyCommandValue;
        }

        set
        {
            if (value != this.replyCommandValue)
            {
                this.replyCommandValue = value;
                NotifyPropertyChanged();
            }
        }
    }

    ...

}
}

解决方案

Save your IList<MessageObject> which gets returned from your FormatPosts method in a field IList<MessageObject> _messages = new List<MessageObject>()

And use the following snippet to update the ListView whenever you need, includes a check to see if the device runs on iOS:

if(Device.RuntimePlatform == Device.iOS) 
{ 
    MessageView.ItemsSource = null; 
    MessageView.ItemsSource = _messages; 
}

这篇关于在扩展上更新列表视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆