2011-07-06 65 views
-1

我有class Client,它從Stream接收數據。通知MainWindow關於其他類中的更改

另外我有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 
    } 

這裏是我的主窗口

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(); 
    } 
} 
+0

爲什麼downvote沒有至少下降一個評論這個問題? –

+0

也許是因爲我的英語不好? :) –

回答

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

+0

這將產生線程問題,改變另一個線程中的項目,而不是我的帖子中提到的ui線程。另一方面使用調度程序將是一個可行的解決方案。我唯一擔心的就是它不是真正的wpf'ish。但另一方面,這不是問題:) – dowhilefor

+0

@dowhilefor實際上你是對的。我根本沒有考慮線程,老實說,沒有注意到:( –

1

您可以創建客戶端類型

ObservableCollection<string> ChatMessages{get;private set;} 

這個系列的一員,財產綁定到你的ListBox屬性ItemsSource。

myListBox.ItemsSource = client 

你可能需要給列表框的名稱在XAML,使用

<ListBox x:Name="myListBox ... 

現在每次你添加一個項目到列表中,如果您刪除的東西的看法就會自動更新,是相同的。

會出現的一個問題是關於線程的使用。必須在UI線程中調用UI上的每個操作。在UI線程之外的其他線程中(顯然是這種情況,考慮到您的線程正在偵聽消息),您不得更改綁定到視圖的此集合,但爲此您可以使用Dispatcher。如果您想從另一個線程修改集合,則只需使用Invoke method。這樣,調用將被推遲到分派器在關聯的線程中調用它,這種情況下,UI線程。

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

我希望有所幫助。 它很難適應WPF概念,當來自Windows窗體或類似的背景,但我保證你的價值:)

+0

我相信問題是WinForms應用程序。 –

+0

它被標記爲WPF。 – SergioL