c# - 当通过网络接收的数据更改属性时,如何将控件绑定(bind)到属性更改?

标签 c# winforms sockets data-binding

我有一类具有姓名、年龄、性别和消息等属性的用户
所以我有一个表单,其中为每个用户的每个属性动态创建了一些文本框,并将每个文本框绑定(bind)到适当的属性。

当用户连接到我的程序并更改其属性时,文本框不会更改。

这是我的用户类:

using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace binding_network
{
    class user : INotifyPropertyChanged
    {
        private string _name;

        public string Name
        {
            get { return _name; }
            set
            {
                if (_name != value)
                {
                    _name = value;
                    NotifyPropertyChanged();
                }
            }
        }
        private int _age;

        public int Age
        {
            get { return _age; }
            set
            {
                if (_age != value)
                {
                    _age = value;
                    NotifyPropertyChanged();
                }
            }
        }
        private string _message;

        public string Message
        {
            get { return _message; }
            set
            {
                if (_message != value)
                {
                    _message = value;
                    NotifyPropertyChanged();
                }
            }
        }
        private string _gender;

        public string Gender
        {
            get { return _gender; }
            set
            {
                if (true)
                {
                    _gender = value;
                    NotifyPropertyChanged();
                }
            }
        }




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

这是我的表单代码:
public partial class Form1 : Form
{
    private BindingSource userBindingSource = new BindingSource();
    BindingList<user> userList = new BindingList<user>();
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        ///some code to create textboxes dynamically....

        txtName.DataBindings.Clear();
        txtName.DataBindings.Add("text", userBindingSource[userIndex], "name");
        txtAge.DataBindings.Clear();
        txtAge.DataBindings.Add("text", userBindingSource[userIndex], "age");
        txtGender.DataBindings.Clear();
        txtGender.DataBindings.Add("text", userBindingSource[userIndex], "gender");
        txtMessage.DataBindings.Clear();
        txtMessage.DataBindings.Add("text", userBindingSource[userIndex], "message");
    }
}

通过这种方法,我通过网络接收数据
private void GetMessage(object obj)
{
    user user1 = (user)obj;
    try
    {
        while (true)
        {
            byte[] buffer = new byte[1024];
            int rec = user1.SocketClient.Receive(buffer, 0, buffer.Length, 0);
            Array.Resize(ref buffer, rec);
            if (rec > 0)
            {
                user1.Name = BitConverter.ToString(buffer, 0);
                user1.Gender = BitConverter.ToString(buffer, 80);
                user1.Age = BitConverter.ToInt32(buffer, 96);
                user1.Message = BitConverter.ToString(buffer, 160);
            }
        }

    }
    catch (Exception ex)
    {

        MessageBox.Show(ex.ToString());
    }

}

但是在收到数据后,文本框不会刷新

最佳答案

很多代码似乎丢失了,但这里有一些东西......
userBindingSource尚未连接到 userList .

绑定(bind)propertyNamedataMember参数的大小写不正确。
userIndex没有定义。

即使是,绑定(bind)到 userBindingSource[userIndex]不允许导航源(也许你没问题)。

所以让我们解决这些问题:

public partial class Form1 : Form
{
    private BindingSource userBindingSource = new BindingSource();
    BindingList<user> userList = new BindingList<user>();
    int userIndex = 0;

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        userBindingSource.DataSource = userList;
        userIndex = userBindingSource.Position;

        ///some code to create textboxes dynamically....

        txtName.DataBindings.Clear();
        txtName.DataBindings.Add("Text", userBindingSource, "Name");
        txtAge.DataBindings.Clear();
        txtAge.DataBindings.Add("Text", userBindingSource, "Age");
        txtGender.DataBindings.Clear();
        txtGender.DataBindings.Add("Text", userBindingSource, "Gender");
        txtMessage.DataBindings.Clear();
        txtMessage.DataBindings.Add("Text", userBindingSource, "Message");
    }
}

假设 userList已填充,您现在可以导航 userBindingSource像这样:
// However you're tracking userIndex, or maybe...
// userIndex = userList.IndexOf(user1);
userBindingSource.Position = userIndex;

或其中任何一个:
userBindingSource.MoveFirst();
userBindingSource.MovePrevious();
userBindingSource.MoveNext();
userBindingSource.MoveLast();

最后,删除无限 while (true)循环进入 GetMessage .

此时,如果您的数据被正确接收和解析,您的TextBox控件应该更新。

编辑...

所以你是多线程的,这很棒。

现在我们必须确保导致 UI 更改的所有操作都在正确的线程上完成。

让我们这样做(假设 GetMessageForm 类中定义):
        if (rec > 0)
        {
            var name = BitConverter.ToString(buffer, 0);
            var gender = BitConverter.ToString(buffer, 80);
            var age = BitConverter.ToInt32(buffer, 96);
            var message = BitConverter.ToString(buffer, 160);

            this.Invoke(new Action(() =>
            {
                user1.Name = name;
                user1.Gender = gender;
                user1.Age = age;
                user1.Message = message;
            }));
        }

还有这个:
catch (Exception ex)
{
    this.Invoke(new Action(() => MessageBox.Show(ex.ToString())));
}

并绑定(bind)源导航(如果在不同的线程上):
this.Invoke(new Action(() => userBindingSource.Position = userIndex));

您也可以考虑使用 BeginInvoke方法。

关于c# - 当通过网络接收的数据更改属性时,如何将控件绑定(bind)到属性更改?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60907101/

相关文章:

.net - WinForm 用户控件 - 拖放

Python - 如何打印有多少网站支持每个密码套件请求

c# - 奇怪的控制流程

c# - 让网络浏览器导航到手机网站

wpf - Windows 窗体是旧技术吗?

java - 带有 https 的 tomcat 在直接 TCP 连接时获得 CLOSE_WAIT

c++ - 为什么UDP服务器上的UDP客户端端口会发生变化

c# - 如果在嵌套集合上使用 SelectMany,则保留父实例

c# - ASP.NET Web API 不返回 XML

c# - 控制台图表绘制