通知MainWindow关于其他课程的变化

时间:2011-07-06 13:46:29

标签: c# wpf class

我有类Client,它从Stream接收数据。

我也有MainWindow,它有ListBox。

基本上我需要在收到新数据时在ListBox中添加项目。请参阅代码(注意TODO线)

class Client
{
    private TcpClient client;
    private NetworkStream stream;
    private ASCIIEncoding encoder;
    private Thread clientThread;

    public Client(string ip, int port)
    {
        this.client = new TcpClient(ip, port);
        this.stream = client.GetStream();
        this.encoder = new ASCIIEncoding();

        clientThread = new Thread(Receive);
        clientThread.Start();
    }

    public void Receive()
    {
        byte[] data = new byte[4096];
        int bytesRead;

        bytesRead = stream.Read(data, 0, 4096);
        string[] message = DecodeMessage(data, bytesRead);
        // TODO: Notify about new message
    }

这是我的MainWindow

 public partial class MainWindow : Window
{
    Client client;

    public MainWindow()
    {
        InitializeComponent();
        client = new Client("127.0.0.1", 2020);
    }

    public void updateChat(string[] message)
    {
        // TODO: Should add new messages into ListBox
    }

    private void send_Click(object sender, RoutedEventArgs e)
    {
        client.Send(0, this.messageBox.Text);
        this.messageBox.Clear();
    }
}

2 个答案:

答案 0 :(得分:1)

您可以在类型为

的Client类中创建成员和属性
ObservableCollection<string> ChatMessages{get;private set;}

此集合绑定到ListBox属性ItemsSource。

myListBox.ItemsSource = client

您可能需要在XAML中为ListBox指定名称,使用

<ListBox x:Name="myListBox ...

现在,每次在列表中添加一个项目时,视图都会自动更新,如果删除了某些内容,则相同。

将出现的一个问题是关于线程的使用。必须在UI线程中调用UI上的每个操作。您不能在除UI线程之外的另一个线程中更改此绑定到视图的集合(显然是这种情况,考虑到您的线程正在侦听消息),但为此您可以使用Dispatcher。如果要从另一个线程修改集合,只需使用Invoke method即可。这样,调用将被推迟,直到调度程序在关联的线程中调用它,即ui线程。

mUIDispatcher.Invoke(DispatcherPriority.Normal, 
      (Action)(() => { ChatMessages.Add(myMessage); }));

我希望有所帮助。 当来自Windows窗体或类似的背景时,很难习惯WPF概念,但我向你保证它值得:)

答案 1 :(得分:0)

请注意以下代码,注意星星包围的部分。

//*****
public class MessageEventArgs : EventArgs
{
    public string[] Message { get; set; }
    public MessageEventArgs(string[] message)
    {
        Message = message;
    }
}
//*****

public class Client
{
    private TcpClient client;
    private NetworkStream stream;
    private ASCIIEncoding encoder;
    private Thread clientThread;
    //*****
    public event EventHandler<MessageEventArgs> MessageReceived
    //*****

    public Client(string ip, int port)
    {
        this.client = new TcpClient(ip, port);
        this.stream = client.GetStream();
        this.encoder = new ASCIIEncoding();

        clientThread = new Thread(Receive);
        clientThread.Start();
    }

    public void Receive()
    {
        byte[] data = new byte[4096];
        int bytesRead;

        bytesRead = stream.Read(data, 0, 4096);
        string[] message = DecodeMessage(data, bytesRead);
        //*****
        InvokeMessageReceived(new MessageEventArgs(message));
        //*****
    }

   //*****
    protected void InvokeMessageReceived(MessageEventArgs e)
    {
        EventHandler<MessageEventArgs> handler = MessageReceived;
        if (handler != null) handler(this, e);
    }
   //*****
}

public class MainWindow : Window
{
    Client client;

    public MainWindow()
    {
        InitializeComponent();
        client = new Client("127.0.0.1", 2020);
        //*****
        client.MessageReceived +=new EventHandler<MessageEventArgs>(client_MessageReceived);
        //*****        
    }

    //*****
    void  client_MessageReceived(object sender, MessageEventArgs e)
    {
        var message = e.Message;
        foreach (var s in message)
        {
            listBox1.Items.Add(s);
        }
    }
    //*****

    public void updateChat(string[] message)
    {
        // TODO: Should add new messages into ListBox
    }

    private void send_Click(object sender, RoutedEventArgs e)
    {
        client.Send(0, this.messageBox.Text);
        this.messageBox.Clear();
    }
}

请阅读此内容:活动(C#编程指南) http://msdn.microsoft.com/en-us/library/awbftdfh.aspx

相关问题