I am adding a user interface to some code that I wrote for the messenger some time ago. Everything seems to be in order, except when I try to display new messages from another thread.
The program flows:
An instance is created and created MainWindow. Constructor for MainWindow:
public MainWindow()
{
InitializeComponent();
_messageContainer = (StackPanel)FindName("Messages");
_messageStatus = (StatusBarItem)FindName("MessageStatus");
_messageCountElement = (StatusBarItem)FindName("MessageCount");
_messageBox = (TextBox)FindName("MessageToSend");
_sendButton = (Button)FindName("SendMessage");
_ipAddress = GetIPAddress();
try
{
Client.Initialize(_ipAddress, this);
_sendButton.IsEnabled = true;
_messageBox.IsEnabled = true;
}
catch (Exception e)
{
DisplayMessage("Could not connect to " + _ipAddress.ToString() + ". The error given was '" + e.Message + "'.", "Server", Colors.Red);
}
}
The sending client ( Clientclass) is initialized using Client.Initializethe constructor MainWindow. Client.Initialize:
public static void Initialize(IPEndPoint endPoint, MainWindow window)
{
windowInstance = window;
client = new TcpClient();
client.ReceiveTimeout = 500;
listenerThread = new Thread(new ParameterizedThreadStart(Receiver.Start));
listenerThread.Start((object)new StartupData(endPoint, windowInstance));
client.Connect(endPoint);
}
The listener thread starts with Client.Initialize. The downstream method is Startlong and complex, but works fine. It comes down to calling another method ProcessMessageto process what it receives. ProcessMessage:
public static void ProcessMessage(string response)
{
response = response.Trim();
MessageBox.Show(response);
if (response.StartsWith("[Message]"))
{
MessageBox.Show("Message");
response = response.Substring(9);
int openIndex = response.IndexOf("<");
int closeIndex = response.IndexOf(">");
if (openIndex < 0 || closeIndex < 0 || closeIndex < openIndex)
{
throw new FormatException("Could not find ID tag in message");
}
int diff = closeIndex - openIndex;
int id = Int32.Parse(response.Substring(openIndex + 1, diff - 1));
if (id != Client.GetClientId())
{
MessageBox.Show("Them");
string message = response.Substring(closeIndex + 1);
window.DisplayMessage(message, "Them", Colors.Yellow);
}
else
{
MessageBox.Show("You");
string message = response.Substring(closeIndex + 1);
window.DisplayMessage(message, "You", Colors.Blue);
}
}
else if (response.Length == 5 && response.StartsWith("[") && response.EndsWith("]"))
{
MessageBox.Show("Response code");
Client.HandleResponse(ResponseCodes.GetResponse(response));
}
else
{
try
{
Int32.Parse(response);
MessageBox.Show("ID");
Client.SetClientId(Int32.Parse(response));
return;
}
catch (Exception)
{
window.DisplayMessage(response, "Server", Colors.Red);
}
}
}
The method is called DisplayMessage. DisplayMessage:
public void DisplayMessage(string message, string name, Color nameColor)
{
MessageBox.Show("Called");
UpdateMessageStatus(ProcessingStatus.Processing);
Grid fullMessage = new Grid();
fullMessage.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(50.00) });
fullMessage.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(600.00) });
Label nameLabel = new Label
{
Content = string.Format("[{0}]", name),
Foreground = new SolidColorBrush(nameColor)
};
Grid.SetColumn(nameLabel, 0);
TextBlock textLabel = new TextBlock
{
Text = message,
TextWrapping = TextWrapping.Wrap,
Margin = new Thickness(0, 5, 0, 5)
};
Grid.SetColumn(textLabel, 1);
fullMessage.Children.Add(nameLabel);
fullMessage.Children.Add(textLabel);
UpdateMessageStatus(ProcessingStatus.Displaying);
Dispatcher.BeginInvoke(new Action(delegate()
{
_messageContainer.Children.Add(fullMessage);
}));
_messageCount += 1;
UpdateMessageCount();
UpdateMessageStatus(ProcessingStatus.Ready);
}
. window.DisplayMessage , . , , Grid .
? Dispatcher.BeginInvoke SO, , , .
( : MessageBox es . , MessageBox DisplayMessage , .)