我在WPF项目中的UI有问题。
概念:
C#中的两个客户端通过聊天与Linux上的Java服务器进行通信。
与其中一位客户,我可以使用'/ kick [user] [reason]'踢另一位聊天者。为了接收从发件人到被踢用户的套接字,我处于异步回调中,因此我很少在UI线程中工作。为解决no-ui方法问题,我使用了Dispatcher。因此,要关闭当前用户界面,我可以这样做
this.Dispatcher.BeginInvoke((System.Threading.ThreadStart)delegate { this.Close(); });
它运行良好,但现在我需要调用另一个UI(用户的连接菜单),但是当我使用“ Show()”方法时,我得到
'System.InvalidOperationException' in PresentationCore.dll
at System.Windows.Input.InputManager..ctor()
at System.Windows.Input.InputManager.GetCurrentInputManagerImpl()
at System.Windows.Input.KeyboardNavigation..ctor()
at System.Windows.FrameworkElement.FrameworkServices..ctor()
at System.Windows.FrameworkElement.EnsureFrameworkServices()
at System.Windows.FrameworkElement..ctor()
at System.Windows.Controls.Control..ctor()
at System.Windows.Window..ctor()
所以我也尝试将其放入Dispatcher
MainWindow mw = new MainWindow();
mw.Dispatcher.BeginInvoke((System.Threading.ThreadStart)delegate { mw.Show(); });
但是我遇到相同的错误((System.InvalidOperationException)。
该怎么做???
方法:]
数据包接收:(不是很有用,但是也许我可以用其他方式做到这一点...?
private void callBack(IAsyncResult aResult)
{
String message = "";
try
{
int size = sck.EndReceiveFrom(aResult, ref ip);
if (size > 0)
{
byte[] receive = new byte[1024];
receive = (byte[])aResult.AsyncState;
message = Encoding.Default.GetString(receive, 0, 1024);
//class for execute sockets informations that the server sends
new Event(message, this);
}
byte[] buffer = new byte[1024];
//restart async task
sck.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref ip, new AsyncCallback(callBack), buffer);
}
catch (Exception) { }
}
kickUser:
public void kickUser(String sender, String reason)
{
if (!CheckAccess())
{
//working well
this.Dispatcher.BeginInvoke((System.Threading.ThreadStart)delegate { this.Close(); });
//And here the System.InvalidOperationException
MainWindow mw = new MainWindow();
mw.Show();
//this.Dispatcher.BeginInvoke((System.Threading.ThreadStart)delegate { mw.Show(); });
//mw.Dispatcher.BeginInvoke((System.Threading.ThreadStart)delegate { mw.Show(); });
//All do the same OperationException error.
}
MessageBox.Show("You get kicked by \"" + sender + "\" for: " + reason, "Server: /kick");
}
是,我找到了问题!
我只需要创建一个在新的主UI线程中显示窗口的方法。然后,我只需要在关闭the old UI。
的委托中调用此方法。 this.Dispatcher.BeginInvoke((System.Threading.ThreadStart)delegate
{
this.Close();
MainWindow mw = new MainWindow();
mw.call();
});
这里是MainWindow类的调用方法((新UI主线程);
public void call()
{
this.Show();
MessageBox.Show("You get kicked by \"" + "sender" + "\" for: " + "reason", "Server: /kick");
}