Add row to UITableView Programmatically 向UITableView程序atically添加行

huangapple go评论74阅读模式
英文:

Add row to UITableView Programmatically

问题

你正在尝试在聊天室代码中以编程方式向UITableView添加行,但似乎无法正确实现。以下是你的代码:

public override async void ViewDidLoad()
{
    // ...(略去了部分代码)...

    client.OnMessageReceived += (sender2, message) =>
    {
        AddMessage(message);
        InvokeOnMainThread(() =>
        {
            tblMessages.ReloadData();
        });
    };

    // ...(略去了部分代码)...
}

public void AddMessage(string message)
{
    MyMessages.Prepend(message);
    source.Data = MyMessages;
    InvokeOnMainThread(() =>
    {
        tblMessages.ReloadData();
    });
}

AddMessage方法中,你已经将新消息添加到MyMessages列表中,并更新了source.Data。然后,使用InvokeOnMainThread来确保在主线程上刷新tblMessages,以便新消息能够正确显示在表格视图中。

这个修改应该能够让接收到的消息在UITableView中正确显示。

英文:

I'm trying to add rows to my UITableView programmatically in my chat room code and I can't seem to get it right. My Code:

public override async void ViewDidLoad()
{
    base.ViewDidLoad();
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
    var height = UIScreen.MainScreen.Bounds.Height;
    var width = UIScreen.MainScreen.Bounds.Width; 
    UIImageView banner = new UIImageView();
    banner.Image = UIImage.FromResource(null, "MY_TESTAPP.Resources.drawable.Banner2.jpg");
    banner.Frame = new RectangleF(0, 0, (float)width, 73);
    banner.ContentMode = UIViewContentMode.ScaleAspectFit;
    UILabel lblTitle = new UILabel();
    lblTitle.Text = theSelectedCompany + " Chat Room";
    MyMessages = GetMessages();
    tblMessages.LayoutIfNeeded();
    source.Data = MyMessages;
    tblMessages.Source = source;

    UITextField txtSendingTextMessage = new UITextField(new CGRect(0, width, width, 100));
    txtSendingTextMessage.Placeholder = "Enter Message To Send Here";

    UIButton btnSendText = new UIButton();
    CGRect ScreenBounds = UIScreen.MainScreen.Bounds;
    float buttonWidth = (float)ScreenBounds.Width / 4;
    btnSendText.Frame = new RectangleF(0f, 0f, buttonWidth, 50f);
    btnSendText.SetTitleColor(UIColor.Black, UIControlState.Normal);
    btnSendText.SetTitle("Send Text", UIControlState.Normal);
    btnSendText.BackgroundColor = UIKit.UIColor.FromRGB(255, 215, 0);

    View.Add(banner);
    View.Add(lblTitle);
    View.Add(tblMessages);
    View.Add(txtSendingTextMessage);
    View.Add(btnSendText);

    View.SubviewsDoNotTranslateAutoresizingMaskIntoConstraints();

    View.AddConstraints(
        banner.AtTopOf(View, 50),
        banner.AtRightOf(View, 0),
        banner.AtLeftOf(View, 0),
        lblTitle.Below(banner, 5),
        lblTitle.WithSameCenterX(banner),
        tblMessages.Below(lblTitle, 10),
        tblMessages.AtLeftOf(View),
        tblMessages.WithSameWidth(View),
        tblMessages.Height().EqualTo(height/2),
        txtSendingTextMessage.Below(tblMessages, 10),
        txtSendingTextMessage.WithSameCenterX(tblMessages),
        btnSendText.Below(txtSendingTextMessage, 10),
        btnSendText.WithSameCenterX(txtSendingTextMessage)
    );
        client = new Client(MyUser.Firstname + " " + MyUser.Lastname, MyUser.Username, MyUser.Firstname, MyUser.Lastname, theSelectedCompany, theSelectedDept, theSelectedSection, "CHATROOM");
        client.OnMessageReceived += (sender2, message) => AddMessage(message);
        await client.Connect();

        btnSendText.TouchUpInside += (object sender, EventArgs e) =>
        {
            try
            {
                client.SendChatMessage(theSelectedCompany, theSelectedDept, theSelectedSection, MyUser.Username, txtSendingTextMessage.Text);
                txtSendingTextMessage.Text = "";
            }
            catch (Exception ex)
            {
                Utils.LogError("App:MY_TESTAPP (Messenger.cs) - An error occured in the btnSendText.TouchUpInside event, the error is: " + ex.Message + Environment.NewLine + "Trace: " + Utils.GetExceptionInfo(ex));
            }
        };
}

The AddMessage code:

    public void AddMessage(string message)
    {
        MyMessages.Prepend(message);
        source = new MessageSource();
        source.Data = MyMessages;
        tblMessages.Source = source;
        tblMessages.ReloadData();
        //InvokeOnMainThread(() =>
        //{
        tblMessages.ReloadData();
        //});
    }

The UITableViewSource Code:

public class MessageSource : UITableViewSource
{
    public List<string> Data { get; set; } = new List<string>(); 
    string CellIdentifier = "TableCell";

    public override nint RowsInSection(UITableView tableview, nint section)
    {
        return Data.Count;
    }

    public void Add(string Message)
    {
        Data.Prepend(Message);
    }

    public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
    {
        UITableViewCell cell = tableView.DequeueReusableCell(CellIdentifier);
        string item = Data[indexPath.Row];

        //if there are no cells to reuse, create a new one
        if (cell == null)
        {
            cell = new UITableViewCell(UITableViewCellStyle.Default, CellIdentifier);
        }

        cell.TextLabel.Text = item;

        return cell;
    }
}

Absolutely everything works as expected, I connect the client to the hub, I retrieve messages from the database, populate the tableview and it all displays fine. When I send a message, all other users get it, I just can't seem to add any received messages to the tableview. When messages are received the AddMessage code is executed, it's just that the tableview never displays the changes.

答案1

得分: 0

以下是您要翻译的内容:

"又一次在我的iOS编程经历中经历了一段痛苦的篇章。

我遇到的问题是,一旦我创建了MyMessages列表并将其分配给MessageSource实例,我就不能再向其中添加MessageSource将看到的任何内容了。对于像我一样的VB程序员,可以将其理解为ByRef。我需要在MessageSource中创建一个与Messages视图控制器中的MyMessages列表共享引用的列表。众所周知,ByRef在C#类层次结构中不存在,但存在Interface,在这种情况下是IListIList是一个字符串列表的接口,现在我的代码看起来像这样:

Messages ViewController:

IList<string> MyMessages;
public override async void ViewDidLoad()
{
    // 其他代码...
    MyMessages = GetMessages();
    // 其他代码...
}

MessageSource代码:

public class MessageSource : UITableViewSource
{
    public IList<string> Data;
    // 其他代码...
    public void Add(string Message)
    {
        Data.Prepend(Message);
    }
    // 其他代码...
}

AddMessage代码:

public void AddMessage(string message)
{
    MyMessages.Prepend(message);
    InvokeOnMainThread(() =>
    {
        tblMessages.InsertRows(new NSIndexPath[] { NSIndexPath.FromRowSection(0, 0) }, UITableViewRowAnimation.None);
    });
}

GetMessages现在返回IList<string>,除此之外,没有其他更改。我可以发送和接收消息并将它们添加到MyMessages列表中,就像处理任何List一样(MyMessages.Add(message))。不同之处在于,MessageSource中的Data现在是对内存中的字符串列表的接口,其他所有对MyMessages的引用也是如此,因此现在每个人都在向同一个数据列表中添加内容。聊天窗口看起来很丑,我需要对其进行美化,我会的,但我首先想让功能正常运行。"

英文:

Well, another painful chapter in my iOS coding experience comes to a close.

The issue I was having is that once I created the MyMessages list and assigned it to the MessageSource instance, I could no longer add anything to it that MessageSource would see. For you VB programmers out there (like me), think ByRef. I needed to create a list in MessageSource that was by reference to the MyMessages list in the Messages view controller. Well as we all know, ByRef doesn't exist in the c# class hierarchy but what does is Interface, and in this case IList, IList is an interface to a list of strings, now my code looks like this:

Messages ViewController:

IList&lt;string&gt; MyMessages;
public override async void ViewDidLoad()
{
    base.ViewDidLoad();
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
    var height = UIScreen.MainScreen.Bounds.Height;
    var width = UIScreen.MainScreen.Bounds.Width; 
    UIImageView banner = new UIImageView();
    banner.Image = UIImage.FromResource(null, &quot;MY_TESTAPP.Resources.drawable.Banner2.jpg&quot;);
    banner.Frame = new RectangleF(0, 0, (float)width, 73);
    banner.ContentMode = UIViewContentMode.ScaleAspectFit;
    UILabel lblTitle = new UILabel();
    lblTitle.Text = theSelectedCompany + &quot; Chat Room&quot;;
    MyMessages = GetMessages();
    tblMessages.LayoutIfNeeded();
    source.Data = MyMessages;
    tblMessages.Source = source;

    UITextField txtSendingTextMessage = new UITextField(new CGRect(0, width, width, 100));
    txtSendingTextMessage.Placeholder = &quot;Enter Message To Send Here&quot;;

    UIButton btnSendText = new UIButton();
    CGRect ScreenBounds = UIScreen.MainScreen.Bounds;
    float buttonWidth = (float)ScreenBounds.Width / 4;
    btnSendText.Frame = new RectangleF(0f, 0f, buttonWidth, 50f);
    btnSendText.SetTitleColor(UIColor.Black, UIControlState.Normal);
    btnSendText.SetTitle(&quot;Send Text&quot;, UIControlState.Normal);
    btnSendText.BackgroundColor = UIKit.UIColor.FromRGB(255, 215, 0);

    View.Add(banner);
    View.Add(lblTitle);
    View.Add(tblMessages);
    View.Add(txtSendingTextMessage);
    View.Add(btnSendText);

    View.SubviewsDoNotTranslateAutoresizingMaskIntoConstraints();

    View.AddConstraints(
        banner.AtTopOf(View, 50),
        banner.AtRightOf(View, 0),
        banner.AtLeftOf(View, 0),
        lblTitle.Below(banner, 5),
        lblTitle.WithSameCenterX(banner),
        tblMessages.Below(lblTitle, 10),
        tblMessages.AtLeftOf(View),
        tblMessages.WithSameWidth(View),
        tblMessages.Height().EqualTo(height/2),
        txtSendingTextMessage.Below(tblMessages, 10),
        txtSendingTextMessage.WithSameCenterX(tblMessages),
        btnSendText.Below(txtSendingTextMessage, 10),
        btnSendText.WithSameCenterX(txtSendingTextMessage)
    );
        tblMessages.RegisterClassForCellReuse(CellIdentifier);

    client = new Client(MyUser.Firstname + &quot; &quot; + MyUser.Lastname, MyUser.Username, MyUser.Firstname, MyUser.Lastname, theSelectedCompany, theSelectedDept, theSelectedSection, &quot;CHATROOM&quot;);
    client.OnMessageReceived += (sender2, message) =&gt; AddMessage(message);
    await client.Connect();

    btnSendText.TouchUpInside += (object sender, EventArgs e) =&gt;
    {
        try
        {
            client.SendChatMessage(theSelectedCompany, theSelectedDept, theSelectedSection, MyUser.Username, txtSendingTextMessage.Text);
            txtSendingTextMessage.Text = &quot;&quot;;
        }
        catch (Exception ex)
        {
            Utils.LogError(&quot;App:MY_TESTAPP (Messenger.cs) - An error occured in the btnSendText.TouchUpInside event, the error is: &quot; + ex.Message + Environment.NewLine + &quot;Trace: &quot; + Utils.GetExceptionInfo(ex));
        }
    };
}

The MessageSource code:

public class MessageSource : UITableViewSource
{
    public IList&lt;string&gt; Data; 
    string CellIdentifier = &quot;TableCell&quot;;

    public override nint RowsInSection(UITableView tableview, nint section)
    {
        return Data.Count;
    }

    public void Add(string Message)
    {
        Data.Prepend(Message);
    }

    public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
    {
        UITableViewCell cell = tableView.DequeueReusableCell(CellIdentifier);
        string item = Data[indexPath.Row];

        //if there are no cells to reuse, create a new one
        if (cell == null)
        {
            cell = new UITableViewCell(UITableViewCellStyle.Default, CellIdentifier);
        }

        cell.TextLabel.Text = item;

        return cell;
    }
}

The AddMessage code:

public void AddMessage(string message)
{
    MyMessages.Prepend(message);
    InvokeOnMainThread(() =&gt;
    {
        tblMessages.InsertRows(new NSIndexPath[] { NSIndexPath.FromRowSection(0, 0) }, UITableViewRowAnimation.None);
    });
}

GetMessages now returns an IList&lt;string&gt; other than that, nothing else changes. I can send and receive messages and add them to MyMessages list like I would any List (MyMessages.Add(message)). The difference her is that Data in MessageSource is now an Interface to a list of strings somewhere in memory as is every other reference to MyMessages, so now everyone is adding to the same data list. The chat is ugly as sin and I need to pretty it up and I will, but I wanted to get the functionality to work first.

huangapple
  • 本文由 发表于 2023年5月18日 10:41:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/76277388.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定