c# - 如何通过wcf服务更新宿主项目中的winform控件?
问题描述
我有一个客户端解决方案,它是带有一个表单和按钮“连接”(到 wcf 服务)的 Windows 窗体项目。
我还有另一个解决方案,它由 wcf 库项目(用于 wcf 服务)和 windows 窗体项目(用于主机)组成。WCF 服务实现了最简单的方法 Connect 增加计数器并调用通知客户端的回调。如何通过 wcf 服务(连接方法)更新宿主项目中的表单控件?
监控服务:
[ServiceContract(CallbackContract = typeof(IMonitoringServiceCallback))]
public interface IMonitoringService
{
[OperationContract(IsOneWay = true)]
void Connect(string name);
}
public interface IMonitoringServiceCallback
{
[OperationContract(IsOneWay = true)]
void Notify(string msg);
}
监控服务:
public class MonitoringService : IMonitoringService
{
private int _registeredUsers = 0;
public void Connect(string name)
{
_registeredUsers++;
// How i should update textBox in Host form here?
// Something like this: textBox1.Text = name;
var callback = OperationContext.Current.GetCallbackChannel<IMonitoringServiceCallback>();
callback.Notify(_registeredUsers.ToString());
}
}
主持人:
public partial class MonitoringListenerForm : Form
{
private ServiceHost host = null;
public MonitoringListenerForm()
{
InitializeComponent();
}
private void btnStartListen_Click(object sender, EventArgs e)
{
if (host == null)
{
host = new ServiceHost(typeof(MonitoringService));
host.Open();
textBox1.Text = "Host started @ " + DateTime.Now.ToString();
}
}
private void btnStopListen_Click(object sender, EventArgs e)
{
host.Close();
host = null;
textBox1.Text = "Host closed @ " + DateTime.Now.ToString();
}
}
客户:
public partial class MonitoringClientForm : Form, IMonitoringServiceCallback
{
private InstanceContext instanceContext = null;
private MonitoringServiceClient client = null;
public MonitoringClientForm()
{
InitializeComponent();
}
public void Notify(string msg)
{
textBox1.Text = "Callback: " + msg;
}
private void btnConnect_Click(object sender, EventArgs e)
{
instanceContext = new InstanceContext(this);
client = new MonitoringServiceClient(instanceContext);
try
{
client.Connect("client1");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
更新:例如在监控监听器文本框中应显示客户端的名称,当客户端连接时。
解决方案
Callbackcontract 可以根据你的描述使用。回调函数会调用客户端代码,将文本框中需要更新的参数放入回调函数中,并传递给客户端执行。客户端将使用从服务器端传递的参数更新文本框。
这是我的演示。使用的绑定是 wsdualhttpbinding。
public class MonitoringService : IMonitoringService
{
private static int _registeredUsers = 0;
public void Connect(string name)
{
_registeredUsers++;
Console.WriteLine("success");
var callback = OperationContext.Current.GetCallbackChannel<IMonitoringServiceCallback>();
callback.Notify(_registeredUsers.ToString());
}
}
这是服务器的代码。服务器端通过回调调用客户端代码并传递一个参数。客户端将获取参数并执行它。
private void button1_Click(object sender, EventArgs e)
{
instanceContext = new InstanceContext(this);
var client = new MonitoringServiceClient(instanceContext);
try
{
client.Connect("client1");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.Run(new Form1());
}
public void Notify(string msg)
{
textBox1.Text = "Callback: "+msg;
}
这是客户端代码。客户端实现回调。
这就是结果。
public class MonitoringService : IMonitoringService
{
private static int _registeredUsers = 0;
public void Connect(string name)
{
_registeredUsers++;
Console.WriteLine("success");
var callback = OperationContext.Current.GetCallbackChannel<IMonitoringServiceCallback>();
callback.Notify("name");
}
}
修改通知中的参数。
您可以通过修改 Notify 中的参数来更新客户端文本框的值。
更新
可以通过反射获取文本框的值,然后发送到客户端。
public void Connect(string name)
{
var callback = OperationContext.Current.GetCallbackChannel<IMonitoringServiceCallback>();
Form1 form = new Form1();
Type type = typeof(Form1);
System.Reflection.FieldInfo propertyInfo = type.GetField("textBox1");
TextBox textBox = (TextBox)propertyInfo.GetValue(form);
callback.Notify(textBox.Text);
}
推荐阅读
- ios - 在 iOS 中使用状态栏和所有内容以编程方式截取屏幕截图?
- java - Java:用流汇总数据
- lua - FiveM 服务器,表索引为 nil && 尝试索引 nil 值(本地,xPlayer)
- java - Cassandra 和 Java Spring 分页中的 OrderBy 子句中断
- c# - AspNetCore 3.1 角色策略不适用于视图控制器
- c - 使用 C 在 Linux 中获取处理器类型
- sql - 如何优化使用游标的 PL/SQL 代码
- azure-devops - 通用包工件 - 在管道中使用包视图
- java - 嘿,我正在尝试在 Eclipse 中使用 GUI 设计器插件创建一个应用程序窗口,但它向我显示以下错误
- python - 在python中的嵌套dict中获取值