0

WindowsフォームアプリケーションでWCFサービスをホストする方法を知っています。しかし、フォーム上のコントロールと対話するサービスを取得するにはどうすればよいですか。たとえば、画像コントロールに画像をロードする Web サービス呼び出しが必要です。これを行う方法を見つけた場合はお知らせください。

4

1 に答える 1

0

これを行う1つの方法は以下のようなものです...

注:私はこのアプローチについて少し心配しており、おそらくこのようなことをする前に達成したいことについてもっと知りたいと思うでしょうが、ここであなたの質問に答えるために...

誰かがあなたに画像を送信してフォームの画像ボックスに表示できるようにしたいとします。そのため、サービスから開始すると、次のようになります。

[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);
于 2012-04-10T09:22:09.727 に答える