2012-04-09 67 views
0

因此我知道如何在Windows窗体应用程序中托管WCF服务。 但是,如何获得与表单上的控件进行交互的服务。 例如,我想要Web服务调用将图像加载到图片控件中。请让我知道,如果你找到了一个方法来做到这一点。你可以这样做就像是低于在Windows窗体应用程序中托管交互式Web服务

+0

您需要将代码执行返回到UI线程。一些IDesign示例演示了这一点。 – stephenl 2012-04-09 14:53:00

+0

你尝试了什么? – JotaBe 2012-04-09 14:57:27

回答

0

的一种方式......

注:我是有点担心这种做法,可能会想知道更多关于你想要做这样的事情之前,要达到什么但为了回答你的问题,这里是...

假设你想允许某人发送一张图片在窗体上的图片框中显示,所以从服务开始,它可能看起来像这个:

[ServiceContract] 
public interface IPictureService 
{ 
    [OperationContract] 
    void ShowPicture(byte[] picture); 
} 

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] 
public class PictureService : IPictureService 
{ 
    private readonly Action<Image> _showPicture; 

    public PictureService(Action<Image> showPicture) 
    { 
     _showPicture = showPicture; 
    } 

    public void ShowPicture(byte[] picture) 
    { 
     using(var ms = new MemoryStream(picture)) 
     { 
      _showPicture(Image.FromStream(ms));  
     }    
    } 
} 

现在创建一个表单,您将用来显示图片(Form1是表单的名称,pictureBox1是问题的图片框)。该代码是这样的:

public partial class Form1 : Form 
{ 
    private readonly ServiceHost _serviceHost; 

    public Form1() 
    { 
     // Construct the service host using a singleton instance of the 
     // PictureService service, passing in a delegate that points to 
     // the ShowPicture method defined below 
     _serviceHost = new ServiceHost(new PictureService(ShowPicture)); 
     InitializeComponent(); 
    } 

    // Display the given picture on the form 
    internal void ShowPicture(Image picture) 
    { 
     Invoke(((ThreadStart) (() => 
            { 
             // This code runs on the UI thread 
             // by virtue of using Invoke 
             pictureBox1.Image = picture; 
            }))); 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 
     // Open the WCF service when the form loads 
     _serviceHost.Open(); 
    } 

    private void Form1_FormClosing(object sender, FormClosingEventArgs e) 
    { 
     // Close the WCF service when the form closes 
     _serviceHost.Close(); 
    } 
} 

的完整性,添加一个app.config并把这个(显然山楂你的主机服务其实并不重要,因为WCF将它抽象掉在很大程度上,但我想给你一个完全工作的例子):

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <system.serviceModel> 
    <behaviors> 
     <serviceBehaviors> 
      <behavior name=""> 
       <serviceMetadata httpGetEnabled="true" /> 
       <serviceDebug includeExceptionDetailInFaults="false" /> 
      </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    <services> 
     <service name="WindowsFormsApplication1.PictureService"> 
      <endpoint address="" binding="wsHttpBinding" contract="WindowsFormsApplication1.IPictureService"> 
       <identity> 
        <dns value="localhost" /> 
       </identity> 
      </endpoint> 
      <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 
      <host> 
       <baseAddresses> 
        <add baseAddress="http://localhost:8732/WindowsFormsApplication1/PictureService/" /> 
       </baseAddresses> 
      </host> 
     </service> 
    </services> 
    </system.serviceModel> 
</configuration> 

,就是这样 - 如果你发送ShowPicture操作的字节数组是一个图像,它会在表中显示。

例如,假设创建一个控制台应用程序,并将服务引用添加到上面定义的winforms应用程序中托管的服务中,主要方法可以简单地将其包含在其中(并且该logo.png将显示在窗体上):

var buffer = new byte[1024]; 
var bytes = new byte[0]; 
using(var s = File.OpenRead(@"C:\logo.png")) 
{ 
    int read; 
    while((read = s.Read(buffer, 0, buffer.Length)) > 0) 
    { 
     var newBytes = new byte[bytes.Length + read]; 
     Array.Copy(bytes, newBytes, bytes.Length); 
     Array.Copy(buffer, 0, newBytes, bytes.Length, read); 
     bytes = newBytes; 
    }    
} 

var c = new PictureServiceClient(); 
c.ShowPicture(bytes); 
相关问题