2012-04-09 53 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); 
相關問題