Skip to content

Instantly share code, notes, and snippets.

@arosh
Created July 31, 2012 02:54
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save arosh/3213108 to your computer and use it in GitHub Desktop.
Save arosh/3213108 to your computer and use it in GitHub Desktop.
System.Windows.Forms.PictureBox with WPF

概要

<WindowsFormHost>を使ってSystem.Windows.FormsのPictureBoxをWPFで利用した

前書き

『C#による計測制御プログラミング入門』 を読んでいる。

若干情報が古い感じなので(2008年発行)、フォームアプリケーションでGUIを制作しているのだが、いろいろ思うところもあってWPFで作ることに。

ただ、大きな変更が加えられたコントロールも少なからずある(特にグラフィック関係)ため、そのあたりの情報を自分で調べるのは面倒。よって、フォームアプリケーション用のコントロールをWPFから使う方法を調べた。

Visual C# 2010 Express で行った操作の覚書。

参照の追加

  • 参照設定を右クリ
  • 参照の追加
  1. 「参照」タブで %programfiles%\Reference Assemblies\Microsoft\Framework\v3.0\WindowsFormsIntegration.dll を追加する

  2. 「.Net」タブで

    • System.Windows.Forms
    • System.Drawing を追加する

XAMLの編集

<Window>の属性定義で

xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"

を追加すると、 wf:コントロール名 でアクセスできるようになる。

その際、 <WindowsFormsHost> でくくる必要があるが、これは「Control」を「1つだけ」しか持てないことに注意せよ。

また、追加するコントロールに名前をつける際には x:Name="" と付けないと、C#のコード側から見えない。

C#コード編集

using System.Windows.Formsとしてもよいが、意外と var で乗り切れたりする。

using System.Drawing; とするときには、 using System.Windows.Media; を消すと、名前が干渉しなくて良いカンジになる。

参考URL

<Window x:Class="Measure_and_Control.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
Title="初めてのアプリケーション" Height="350" Width="525">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<WindowsFormsHost Grid.Column="0">
<wf:PictureBox x:Name="pictureBox1" />
</WindowsFormsHost>
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Button Grid.Row="0" Content="表示" Name="button1" Click="button1_Click" />
</Grid>
</Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Drawing;
namespace Measure_and_Control
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
// 処理が重いとき → Bitmap
// そうでもないとき → Paintイベント
private void button1_Click(object sender, RoutedEventArgs e)
{
int ph = pictureBox1.ClientSize.Height;
int pw = pictureBox1.ClientSize.Width;
Bitmap bmp = new Bitmap(pw, ph);
pictureBox1.Image = bmp;
Graphics gr = Graphics.FromImage(bmp);
for (int i = 0; i <= ph; i++)
{
double value = 1 - (double)i / ph;
var color = HsvColor(value);
var p = new Pen(color);
// (0, i) -> (pw, i)
gr.DrawLine(p, 0, i, pw, i);
}
gr.Dispose();
pictureBox1.Refresh();
}
private static Color HsvColor(double value)
{
// 角度
double h = (1 - value) * 360 / 60;
// 彩度
double s = value;
// 強度
double v = value;
// 作業領域
double p1 = v * (1 - s);
double p2 = v * (1 - s * (h - Math.Floor(h)));
double p3 = v * (1 - s * (1 - (h - Math.Floor(h))));
// 赤・緑・青
int r = 0;
int g = 0;
int b = 0;
switch ((int)Math.Floor(h))
{
case 0:
r = (int)(v * 255);
g = (int)(p3 * 255);
b = (int)(p1 * 255);
break;
case 1:
r = (int)(p2 * 255);
g = (int)(v * 255);
b = (int)(p1 * 255);
break;
case 2:
r = (int)(p1 * 255);
g = (int)(v * 255);
b = (int)(p3 * 255);
break;
case 3:
r = (int)(p1 * 255);
g = (int)(p2 * 255);
b = (int)(v * 255);
break;
case 4:
r = (int)(p3 * 255);
g = (int)(p1 * 255);
b = (int)(v * 255);
break;
case 5:
r = (int)(v * 255);
g = (int)(p1 * 255);
b = (int)(p2 * 255);
break;
}
var color = Color.FromArgb(r, g, b);
return color;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment