20200319のC#に関する記事は8件です。

windowsには、snipping toolという、画面キャプチャがあって、画面の一部分をクリッピングできるが、連続で切り抜いて、文書にぺたぺた貼っていくような場面には向かないので、csharpで、画面に常駐するクリッピングツールをつくった

windowsには、snipping toolという、画面キャプチャがあって、画面の一部分をクリッピングできるが、連続で切り抜いて、文書にぺたぺた貼っていくような場面には向かないので、csharpで、画面に常駐するクリッピングツールをつくった

scr_cap.cs
//コンパイルは、コマンドラインから以下
//c:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /target:winexe scr_cap.cs

using System;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Imaging;


namespace scr_cap
{
  public class Form1 : Form
  {
    public Button button1;
    public Form1()
    {
      this.Text = "scr_cap";
      this.TransparencyKey = this.BackColor;
      this.TopMost = true;
      //this.SizeGripStyle = 1;
      this.FormBorderStyle = FormBorderStyle.Sizable;

      button1 = new Button();
      button1.Size = new Size(30, 1000);
      button1.Location = new Point(0, 0);
      button1.Text = "-";
      this.Controls.Add(button1);
      button1.Click += new EventHandler(button1_Click);
    }

    private void button1_Click(object sender, EventArgs e)
    {

  try
  {
    var r = this.ClientRectangle;
    var bmp = new Bitmap(r.Width-30, r.Height, PixelFormat.Format32bppArgb);
    var g = Graphics.FromImage(bmp);
    var iSource = this.PointToScreen(new Point(30, 0));
    var iDestination = new Point(0, 0);

    g.CopyFromScreen(
      iSource, iDestination,
      this.ClientSize, CopyPixelOperation.SourceCopy);
    //bmp.Save(".\\capture.png", ImageFormat.Png);
    Pen redPen = new Pen(Color.Red, 1);
    Rectangle rect = new Rectangle(0, 0, bmp.Width-1,bmp.Height-1);
    g.DrawRectangle(redPen, rect);


    Clipboard.SetDataObject(bmp, true, 20, 500);
  }
  catch(Exception ex)
  {
    MessageBox.Show("エラー:\n\n" + ex);//
  }

    }
    [STAThread]
    static void Main()
    {
      Application.EnableVisualStyles();
      Application.Run(new Form1());
    }
  }
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

画面キャプチャ画像を連続して文書に貼れるように、画面に常駐するキャプチャーツールを作った

windowsには、snipping toolという、画面キャプチャがあって、画面の一部分をクリッピングできるが、連続で切り抜いて、文書にぺたぺた貼っていくような場面には向かないので、csharpで、画面に常駐するクリッピングツールをつくった

scr_cap.cs
//コンパイルは、コマンドラインから以下
//c:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /target:winexe scr_cap.cs

using System;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Imaging;


namespace scr_cap
{
  public class Form1 : Form
  {
    public Button button1;
    public Form1()
    {
      this.Text = "scr_cap";
      this.TransparencyKey = this.BackColor;
      this.TopMost = true;
      //this.SizeGripStyle = 1;
      this.FormBorderStyle = FormBorderStyle.Sizable;

      button1 = new Button();
      button1.Size = new Size(30, 1000);
      button1.Location = new Point(0, 0);
      button1.Text = "-";
      this.Controls.Add(button1);
      button1.Click += new EventHandler(button1_Click);
    }

    private void button1_Click(object sender, EventArgs e)
    {

  try
  {
    var r = this.ClientRectangle;
    var bmp = new Bitmap(r.Width-30, r.Height, PixelFormat.Format32bppArgb);
    var g = Graphics.FromImage(bmp);
    var iSource = this.PointToScreen(new Point(30, 0));
    var iDestination = new Point(0, 0);

    g.CopyFromScreen(
      iSource, iDestination,
      this.ClientSize, CopyPixelOperation.SourceCopy);
    //bmp.Save(".\\capture.png", ImageFormat.Png);
    Pen redPen = new Pen(Color.Red, 1);
    Rectangle rect = new Rectangle(0, 0, bmp.Width-1,bmp.Height-1);
    g.DrawRectangle(redPen, rect);


    Clipboard.SetDataObject(bmp, true, 20, 500);
  }
  catch(Exception ex)
  {
    MessageBox.Show("エラー:\n\n" + ex);//
  }

    }
    [STAThread]
    static void Main()
    {
      Application.EnableVisualStyles();
      Application.Run(new Form1());
    }
  }
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

1人でアプリを作る

はじめに

こんにちは。
今回から、『Unity』を使ってスクロールゲームを作っていきます。
企画から完成までの過程を日記感覚で記録していきます!

制作環境

macOS Mojave バージョン 10.14.6
Unity 2019.2.19f1

企画

「近未来の世界で、主人公は機械で...」という、妄想を膨らませながら、
イメージを紙にサラサラと書いていきます。
ステージ構成や、プレイしてもらう時間、ターゲットなどをじっくり考えました。

実際に書いたものが下記画像になります。(きたない...)
gameRough.jpgflow.jpg
まあ、見づらくても、自分が分かっていればいいと思います。
ただ、他の人に見せるなら綺麗にまとめた方がいいかもしれません...。
今回は、一人で作るので、このまま進めます。

イメージイラスト

世界観や、設定が決まったので、イメージイラストを書きます。
手が動くままに書きました。
イメージイラストを書いてから、世界観や設定を決めていってもいいかもしれません。
characterRough.jpg

まとめ

今回は、企画をかんがえました。
内容を、事細かに説明していないので短くなっちゃいました...。

次回は、ゲームの流れがわかる、簡易的なモックアップを作ります。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

1人でアプリを作る【その1】

はじめに

こんにちは。
今回から、『Unity』を使ってスクロールゲームを作っていきます。
企画から完成までの過程を日記感覚で記録していきます!

制作環境

macOS Mojave バージョン 10.14.6
Unity 2019.2.19f1

企画

「近未来の世界で、主人公は機械で...」という、妄想を膨らませながら、
イメージを紙にサラサラと書いていきます。
ステージ構成や、プレイしてもらう時間、ターゲットなどをじっくり考えました。

実際に書いたものが下記画像になります。(きたない...)
gameRough.jpgflow.jpg
まあ、見づらくても、自分が分かっていればいいと思います。
ただ、他の人に見せるなら綺麗にまとめた方がいいかもしれません...。
今回は、一人で作るので、このまま進めます。

イメージイラスト

世界観や、設定が決まったので、イメージイラストを書きます。
手が動くままに書きました。
イメージイラストを書いてから、世界観や設定を決めていってもいいかもしれません。
characterRough.jpg

まとめ

今回は、企画をかんがえました。
内容を、事細かに説明していないので短くなっちゃいました...。

次回は、ゲームの流れがわかる、簡易的なモックアップを作ります。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Locationプロパティー、PointToScreen、PointToClient メソッドの使い方

 ControlのLocationメソッド、PointToScreenメソッド、そしてPointToClientメソッドの使い方をまとめる。本記事では、特に下の写真-1のように複数のControl(ここではPanel)が入れ子上になっている際に、あるコントロールの座標を他のコントロールの座標系で表す方法に重点を当てる。

スクリーンショット2.png
                       写真-1 

0.前提条件
 上の写真-1では、フォームの上にpanel1から4までのパネルが計4枚配置されている。それぞれの関係は次のとおり、フォームの上にpanel1(黄色)とpanel4(ライトグリーン)の二枚のパネルが配置され、さらにpanel1の上にpanel2(水色)が一枚配置され、そのpanel2のパネルの上にpanel3(ピング)が一枚配置されている。

            this.Controls.Add(panel1);    // フォーム(this)上にパネルpanel1(黄色)を追加
            this.Controls.Add(panel4);    // フォーム(this)上にパネルpanel4(ライトグリーン)を追加

            panel1.Controls.Add(panel2);  // panel1(黄色)の上にパネルpanel2(水色)を追加

            panel2.Controls.Add(panel3);  // panel2(水色)の上にパネルpanel3(ピンク)を追加

1.座標系
 この写真-1のスクリーン(モニタ)画面の中には、下の写真-2のように6つの座標系が含まれている。
     a.スクリーン(モニタ)の座標系
     b.フォーム(this)の座標系
     c.panel1の座標系
     d.panle2の座標系
     e.panel3の座標系
     f.panel4の座標系
  
 それぞれの座標系は、それぞれの領域の左上が原点になり、またそれぞれの座標軸の方向に従って座標を持つ。

スクリーンショット3.png
                       写真-2

2.Locationプロパティで得られる値
 写真-2において、それぞれのコントロール(panel1~4)のLocationプロパティで得られる値は、その親の座標系で表される値である。すなわち、
   panel1.Locationであれば、フォーム(this)の座標系であり、
   panel2.Locationであれば、panel1の座標系、
   panel3.locationであれば、panel2の座標系になる。
また、
   panel4.Locationであれば、前提条件からこれもpanel1同様フォーム(this)の座標系になる。
  
 実際にその使い方は、

Point p11 = panel1.Location;    // フォーム(this)の座標系で表された位置
Point p21 = panel2.Location;    // panel1の座標系で表された位置
Point p31 = panel3.Location;    // panel2の座標系で表された位置
Point p41 = panel4.Location;    // フォーム(this)の座標系で表された位置

3.PointToScreenメソッドの使い方
 PointToScreenメソッドは、あるコントロールの座標系で表された点の位置を、スクリーン(モニタ)の左上を原点(0,0)とした座標系に変換するメソッドである。
 基本的な使い方は、

Point p = 点が含まれるコントロールのオブジェクト.PointToScreen(点が含まれるコントロールの座標系で表された座標);

 例えば写真-2を例に挙げるならば、panel1の(左上の角の)位置をスクリーンの座標系で表す時は、次のようになる

Point p11 = panel1.Location;            // panel1の左上の座標をフォーム(this)の座標系で表した点p11
Point p12 = this.PointToScreen(p11);    // 点p11をスクリーンの座標系で表した座標p12 

 また、panel2の位置をスクリーン座標系で表す時は、

Point p21 = panel2.Location                // panel2の左上の座標をpanel1の座標系で表した点p21
Point p22 = panel1.PointToScreen(p21);     // 点p21をスクリーンの座標系で表した座標p22

 ここで、注意しなければならないのは、PointToScreen()の前のオブジェクトは、PointToScreen()のパラメータに与えられる点が含まれるオブジェクトでなければならないことである。すなわち繰り返しになるが、panel1(の左上の点)が含まれるおbジェクトはフォーム(this)オブジェクトであり、またpanel2の(左上の点)が含まれるのはpanel1であるから、上記のような記述になる。
 では、panel3は、どのように記述されるであろうか。panel3のコントロールの親のコントロールはpanel2であるから、スクリーン座標系でpanel3の位置を表すと、

Point p31 = panel3.Location;             // panel3の左上の座標をpanel2の座標系で表した点p31
Point p32 = panel2.PointToScreen(p31);   // 点p31をスクリーンの座標系で表した座標p32

となる。

 それならばpanel4の場合は、親がpanel1と同様にフォーム(this)であるから、

Point p41 = panel4.Location;           // panel4の左上の座標をフォーム(this)の座標系で表した点p41
Point p42 = this.PointToScreen(p41);   // 点p41をスクリーンの座標系で表した座標p42

となる。

4.PointToClientメソッド
 PointToClientメソッドは、スクリーン座標系で表された(コントロールの左上の角の)点を、別のコントロールの座標系に変換するメソッドである。
 基本的な使い方は、

Point p = 表したい座標系を持つコントロールのオブジェクト.PointToClient(知りたい点のスクリーン座標)

 また写真-2を例に挙げて説明する。
 panel1の(左上の角の)位置を、Locationプロパティで表したフォームの座標系、PointToScreenメソッドで用いたスクリーンの座標系、スクリーン座標をPointToClientメソッドでフォームの座標系で表した例を示す。

Point p11 = panel1.Location;            // panel1の左上の座標をフォーム(this)の座標系で表した点p11
Point p12 = this.PointToScreen(p11);    // 点p11をスクリーンの座標系で表した座標p12 
Point p13 = this.PointToClient(p12);    // スクリーン座標で表されたp12をフォーム(this)の座標系に変換する

 こので注意しなければならないのは、PointToClientメソッドの前のオブジェクトは、表したい座標系のオブジェクトでなければならないのであり、この場合はフォームを表すthisでなければならない。

 次にpanel2の(左上の角の)位置を、Locationプロパティで表したフォームの座標系、PointToScreenメソッドで用いたスクリーンの座標系、スクリーン座標をPointToClientメソッドでフォームの座標系、panel1の座標系、panel2の座標系に変換して表した例を示す。

Point p21 = panel2.Location                 // panel2の左上の座標をpanel1の座標系で表した点p21
Point p22 = panel1.PointToScreen(p21);      // 点p21をスクリーンの座標系で表した座標p22
Point p23 = this.PointToClient(p22);        // 点p22をフォーム(this)の座標系で表した座標p23
Point p24 = panel1.PointToClient(p22);      // 点p21をpanel1の座標系で表した座標p24
Point p25 = panel2.PointToClient(p22);      // 点p21をpanel2の座標系で表した座標p25

 ここで注意しなければならないのは、panel2の左上の点をpanel2の座標系で表した点p25は、その座標が(0,0)になることである。(当然の話ではあるが、、、)

 さらに次に、panel4をpanel1からpanel3の座標系で表す例を示す。panel4は、panel1同様、前提条件からフォーム(this)に属している。しかし、panel2とpanel3とは、直接的な関係はない。しかし、一方でスクリーン座標系を通して変換することができる。

Point p41 = panel4.Location;                // panel2の左上の座標をフォーム(this)の座標系で表した点p41
Point p42 = this.PointToScreen(p41);        // 点p41をスクリーンの座標系で表した座標p42
Point p44 = panel1.PointToClient(p42);      // 点p42をpanel1の座標系で表した座標p44
Point p45 = panel2.PointToClient(p42);      // 点p42をpanel2の座標系で表した座標p45
Point p46 = panel3.PointToClient(p42);      // 点p42をpanel3の座標系で表した座標p46

4.以上をまとめたソースコード
 以上をまとめたソースコードを次に示す。コンパイルすると写真-1で示したフォームの実行ファイルができる。それを起動し、そのフォームをドラッグして動かすと、スクリーン座標系で表されたコントロールの座標の値が変わる。またスクリーン座標をPointToClientメソッドそれぞれの座標系に変換された座標が表示される。

                 ソースコード

ToScreenToClient.cs
using System;
using System.Drawing;
using System.Windows.Forms;

namespace ToScreenMethod
{
    class Form1 : Form
    {
        Panel panel1;
        Label label11, label12, label13, label14, label15;
        Point p11, p12, p13, p14;

        Panel panel2;
        Label label21, label22, label23, label24, label25, label26;
        Point p21, p22, p23, p24, p25;

        Panel panel3;
        Label label31, label32, label33, label34, label35, label36, label37;
        Point p31, p32, p33, p34, p35, p36;

        Panel panel4;
        Label label41, label42,label43, label44,label45,label46, label47;
        Point p41, p42, p43, p44, p45, p46;

        public static void Main()
        {
            Application.Run(new Form1());
        }

        public Form1()
        {
            // 
            // label41を定義
            label41 = new Label();
            label41.Location = new Point(0, 0);
            label41.AutoSize = true;

            // label42を定義
            label42 = new Label();
            label42.Location = new Point(0, label41.Height);
            label42.AutoSize = true;

            // label43を定義
            label43 = new Label();
            label43.AutoSize = true;
            label43.Location = new Point(0, label42.Location.Y + label42.Height);

            // label44を定義
            label44 = new Label();
            label44.AutoSize = true;
            label44.Location = new Point(0, label43.Location.Y + label43.Height);

            // label45を定義
            label45 = new Label();
            label45.AutoSize = true;
            label45.Location = new Point(0, label44.Location.Y + label44.Height);

            // label46を定義
            label46 = new Label();
            label46.AutoSize = true;
            label46.Location = new Point(0, label45.Location.Y + label45.Height);

            // label47を定義
            label47 = new Label();
            label47.AutoSize = true;
            label47.Location = new Point(0, label46.Location.Y + label46.Height);

            // panel4を定義
            panel4 = new Panel();
            panel4.Location = new Point(50, 700);
            panel4.Size = new Size(1100, 200);
            panel4.BorderStyle = BorderStyle.None;
            panel4.BackColor = Color.LightGreen;
            panel4.Controls.Add(label41);
            panel4.Controls.Add(label42);
            panel4.Controls.Add(label43);
            panel4.Controls.Add(label44);
            panel4.Controls.Add(label45);
            panel4.Controls.Add(label46);
            panel4.Controls.Add(label47);

            //
            // label31を定義
            label31 = new Label();
            label31.Location = new Point(0, 0);
            label31.AutoSize = true;

            // label32を定義
            label32 = new Label();
            label32.Location = new Point(0, label31.Height);
            label32.AutoSize = true;

            // label33を定義
            label33 = new Label();
            label33.AutoSize = true;
            label33.Location = new Point(0, label32.Location.Y + label32.Height);

            // label34を定義
            label34 = new Label();
            label34.AutoSize = true;
            label34.Location = new Point(0, label33.Location.Y + label33.Height);

            // label35を定義 
            label35 = new Label();
            label35.AutoSize = true;
            label35.Location = new Point(0, label34.Location.Y + label34.Height);

            // label36を定義
            label36 = new Label();
            label36.AutoSize = true;
            label36.Location = new Point(0, label35.Location.Y + label35.Height);

            // label37を定義
            label37 = new Label();
            label37.AutoSize = true;
            label37.Location = new Point(0, label36.Location.Y + label36.Height);

            // panel3を定義
            panel3 = new Panel();
            panel3.Location = new Point(50, 150);
            panel3.Size = new Size(900, 200);
            panel3.BorderStyle = BorderStyle.None;
            panel3.BackColor = Color.Pink;
            panel3.Controls.Add(label31);
            panel3.Controls.Add(label32);
            panel3.Controls.Add(label33);
            panel3.Controls.Add(label34);
            panel3.Controls.Add(label35);
            panel3.Controls.Add(label36);
            panel3.Controls.Add(label37);

            //
            // label21を定義
            label21 = new Label();
            label21.Location = new Point(0, 0);
            label21.AutoSize = true;

            // label22を定義
            label22 = new Label();
            label22.Location = new Point(0, label21.Height);
            label22.AutoSize = true;

            // label23を定義
            label23 = new Label();
            label23.AutoSize = true;
            label23.Location = new Point(0, label22.Location.Y + label22.Height);

            // label24を定義
            label24 = new Label();
            label24.AutoSize = true;
            label24.Location = new Point(0, label23.Location.Y + label23.Height);

            // label25を定義 
            label25 = new Label();
            label25.AutoSize = true;
            label25.Location = new Point(0, label24.Location.Y + label24.Height);

            // label26を定義
            label26 = new Label();
            label26.AutoSize = true;
            label26.Location = new Point(0, label25.Location.Y + label25.Height);

            // panel2を定義
            panel2 = new Panel();
            panel2.Location = new Point(50, 150);
            panel2.Size = new Size(1000, 400);
            panel2.BorderStyle = BorderStyle.None;
            panel2.BackColor = Color.Aqua;
            panel2.Controls.Add(label21);
            panel2.Controls.Add(label22);
            panel2.Controls.Add(label23);
            panel2.Controls.Add(label24);
            panel2.Controls.Add(label25);
            panel2.Controls.Add(label26);
            panel2.Controls.Add(panel3);  // panel2の上にパネルpanel3を追加

            // 
            // label11を定義
            label11 = new Label();
            label11.Location = new Point(0, 0);
            label11.AutoSize = true;

            // label12を定義
            label12 = new Label();
            label12.Location = new Point(0, label11.Height);
            label12.AutoSize = true;

            // label13を定義
            label13 = new Label();
            label13.AutoSize = true;
            label13.Location = new Point(0, label12.Location.Y + label12.Height);

            // label14を定義
            label14 = new Label();
            label14.AutoSize = true;
            label14.Location = new Point(0, label13.Location.Y + label13.Height);

            // label15を定義
            label15 = new Label();
            label15.AutoSize = true;
            label15.Location = new Point(0, label14.Location.Y + label14.Height);

            // panel1を定義
            panel1 = new Panel();
            panel1.Location = new Point(50, 50);
            panel1.Size = new Size(1100, 600);
            panel1.BorderStyle = BorderStyle.None;
            panel1.BackColor = Color.Yellow;
            panel1.Controls.Add(label11);
            panel1.Controls.Add(label12);
            panel1.Controls.Add(label13);
            panel1.Controls.Add(label14);
            panel1.Controls.Add(label15);
            panel1.Controls.Add(panel2);  // panel1の上にパネルpanel2を追加

            //
            // フォームを定義
            this.Width = 1200;
            this.Height = 950;
            this.Text = "ToScreenToClient";
            this.Controls.Add(panel1);  // フォーム(this)上にパネルpanel1を追加
            this.Controls.Add(panel4);  // フォーム(this)上にパネルpanel4を追加

            // イベントハンドラを登録
            this.LocationChanged += new EventHandler(Form1_LocationChanged);    // フォームが移動したことを検出

        }

        //フォームを移動した時に実行
        private void Form1_LocationChanged(object sender, EventArgs e)
        {
            //panel1
            label11.Text = "panel1の左上の座標";

            p11 = panel1.Location;
            label12.Text = "(1) panel1.Locationで示される座標(" + p11.X + "," + p11.Y + ")";

            p12 = this.PointToScreen(p11);  
            label13.Text = "(2) this.PointToScreen( (1)の座標系 ) で求められたスクリーン(モニタ)の左上を基準にした座標(" + p12.X + "," + p12.Y + ") <--- フォームをドラッグして動かすと、座標の表示が変わります。";

            p13 = this.PointToClient(p12);
            label14.Text = "(3) this.PointToClient( (2)のスクリーン座標系 ) で求められたフォーム(this)の左上を基準にした座標(" + p13.X + "," + p13.Y + ")     フォームを動かしても、(1)と同じ値。";

            p14 = panel1.PointToClient(p12);
            label15.Text = "(3) panel1.PointToClient( (2)のスクリーン座標系 ) で求められたpanel1の左上を基準にした座標(" + p14.X + "," + p14.Y + ")";


            //panel2
            label21.Text = "panel2の左上の座標";

            p21 = panel2.Location;
            label22.Text = "(1) Locationメソッドで示される座標(" + p21.X + "," + p21.Y + ")";

            p22 = panel1.PointToScreen(p21);  
            label23.Text = "(2) panel1.PointToScreen( (1)の座標系 ) で求められたスクリーン(モニタ)の左上を基準にした座標(" + p22.X + "," + p22.Y + ") <--- フォームをドラッグして動かすと、座標の表示が変わります。";

            p23 = this.PointToClient(p22);  
            label24.Text = "(3) this.PointToClient( (2)のスクリーン座標系 ) で求められたフォーム(this)の左上を基準にした座標(" + p23.X + "," + p23.Y + ") ";

            p24 = panel1.PointToClient(p22);
            label25.Text = "(4) panel1.PointToClient( (2)のスクリーン座標系 ) で求められたpanel1の左上を基準にした座標(" + p24.X + "," + p24.Y + ")     フォームを動かしても、(1)と同じ値。";

            p25 = panel2.PointToClient(p22);
            label26.Text = "(5) panel2.PointToClient( (2)のスクリーン座標系 ) で求められたpanel2の左上を基準にした座標(" + p25.X + "," + p25.Y + ")";


            //panel3
            label31.Text = "panel3の左上の座標";

            p31 = panel3.Location;
            label32.Text = "(1) Locationメソッドで示される座標(" + p31.X + "," + p31.Y + ")";

            p32 = panel2.PointToScreen(p31); 
            label33.Text = "(2) panel2.PointToScreen( (1)の座標系 ) で求められたスクリーン(モニタ)の左上を基準にした座標(" + p32.X + "," + p32.Y + ") <--- フォームをドラッグして動かすと、座標の表示が変わります。";

            p33 = this.PointToClient(p32);  
            label34.Text = "(3) this.PointToClient( (2)のスクリーン座標系 ) で求められたフォーム(this)の左上を基準にした座標(" + p33.X + "," + p33.Y + ") ";

            p34 = panel1.PointToClient(p32);
            label35.Text = "(4) panel1.PointToClient( (2)のスクリーン座標系 ) で求められたpanel1の左上を基準にした座標(" + p34.X + "," + p34.Y + ")";

            p35 = panel2.PointToClient(p32);
            label36.Text = "(5) panel2.PointToClient( (2)のスクリーン座標系 ) で求められたpanel2の左上を基準にした座標(" + p35.X + "," + p35.Y + ")     フォームを動かしても、(1)と同じ値。";

            p36 = panel3.PointToClient(p32);
            label37.Text = "(6) panel3.PointToClient( (2)のスクリーン座標系 ) で求められたpanel3の左上を基準にした座標(" + p36.X + "," + p36.Y + ")";


            //panel4
            label41.Text = "panel4の左上の座標";

            p41 = panel4.Location;
            label42.Text = "(1) Locationメソッドで示される座標(" + p41.X + "," + p41.Y + ")";

            p42 = this.PointToScreen(p41);
            label43.Text = "(2) this.PointToScreen( (1)の座標系 ) で求められたスクリーン(モニタ)の左上を基準にした座標(" + p42.X + "," + p42.Y + ") <--- フォームをドラッグして動かすと、座標の表示が変わります。";

            p43 = this.PointToClient(p42);
            label44.Text = "(3) this.PointToClient( (2)のスクリーン座標系 ) で求められたフォーム(this)の左上を基準にした座標(" + p43.X + "," + p43.Y + ")      フォームを動かしても、(1)と同じ値。";

            p44 = panel1.PointToClient(p42);
            label45.Text = "(4) panel1.PointToClient( (2)のスクリーン座標系 ) で求められたpanel1の左上を基準にした座標(" + p44.X + "," + p44.Y + ")";

            p45 = panel2.PointToClient(p42);
            label46.Text = "(5) panel2.PointToClient( (2)のスクリーン座標系 ) で求められたpanel2の左上を基準にした座標(" + p45.X + "," + p45.Y + ")";

            p46 = panel3.PointToClient(p42);
            label47.Text = "(6) panel3.PointToClient( (2)のスクリーン座標系 ) で求められたpanel3の左上を基準にした座標(" + p46.X + "," + p46.Y + ")";

        }

    }
}

以上

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Locationプロパティ、PointToScreen、PointToClient メソッドの使い方

 ControlのLocationメソッド、PointToScreenメソッド、そしてPointToClientメソッドの使い方をまとめる。本記事では、特に下の写真-1のように複数のControl(ここではPanel)が入れ子上になっている状態での、あるコントロールの座標を他のコントロールの座標系で表す方法について重点を置く。

スクリーンショット2.png
                       写真-1 

0.前提条件
 上の写真-1では、フォームの上にpanel1から4までのパネルが計4枚配置されている。それぞれの関係は次のとおり、フォームの上にpanel1(黄色)とpanel4(ライトグリーン)の二枚のパネルが配置され、さらにpanel1の上にpanel2(水色)が一枚配置され、そのpanel2のパネルの上にpanel3(ピング)が一枚配置されている。

            this.Controls.Add(panel1);    // フォーム(this)上にパネルpanel1(黄色)を追加
            this.Controls.Add(panel4);    // フォーム(this)上にパネルpanel4(ライトグリーン)を追加

            panel1.Controls.Add(panel2);  // panel1(黄色)の上にパネルpanel2(水色)を追加

            panel2.Controls.Add(panel3);  // panel2(水色)の上にパネルpanel3(ピンク)を追加

1.座標系
 この写真-1のスクリーン(モニタ)画面の中には、下の写真-2のように6つの座標系が含まれている。
     a.スクリーン(モニタ)の座標系
     b.フォーム(this)の座標系
     c.panel1の座標系
     d.panle2の座標系
     e.panel3の座標系
     f.panel4の座標系
  
 それぞれの座標系は、それぞれの領域の左上が原点になり、またそれぞれの座標軸の方向に従って座標を持つ。

スクリーンショット3.png
                       写真-2

2.Locationプロパティで得られる値
 写真-2において、それぞれのコントロール(panel1~4)のLocationプロパティで得られる値は、その親の座標系で表される値である。すなわち、
   panel1.Locationであれば、フォーム(this)の座標系であり、
   panel2.Locationであれば、panel1の座標系、
   panel3.locationであれば、panel2の座標系になる。
 また、
   panel4.Locationであれば、前提条件からこれもpanel1同様フォーム(this)の座標系になる。
  
 実際にその使い方は、

Point p11 = panel1.Location;    // フォーム(this)の座標系で表された位置
Point p21 = panel2.Location;    // panel1の座標系で表された位置
Point p31 = panel3.Location;    // panel2の座標系で表された位置
Point p41 = panel4.Location;    // フォーム(this)の座標系で表された位置

3.PointToScreenメソッドの使い方
 PointToScreenメソッドは、あるコントロールの座標系で表された点の位置を、スクリーン(モニタ)の左上を原点(0,0)とした座標系に変換するメソッドである。
 基本的な使い方は、

Point p = 点が含まれるコントロールのオブジェクト.PointToScreen(点が含まれるコントロールの座標系で表された座標);

 例えば写真-2を例に挙げるならば、panel1の(左上の角の)位置をスクリーンの座標系で表す時は、次のようになる

Point p11 = panel1.Location;            // panel1の左上の座標をフォーム(this)の座標系で表した点p11
Point p12 = this.PointToScreen(p11);    // 点p11をスクリーンの座標系で表した座標p12 

 また、panel2の位置をスクリーン座標系で表す時は、

Point p21 = panel2.Location                // panel2の左上の座標をpanel1の座標系で表した点p21
Point p22 = panel1.PointToScreen(p21);     // 点p21をスクリーンの座標系で表した座標p22

 ここで、注意しなければならないのは、PointToScreen()の前のオブジェクトは、PointToScreen()のパラメータに与えられる点が含まれるオブジェクトでなければならないことである。すなわち繰り返しになるが、panel1(の左上の点)が含まれるおbジェクトはフォーム(this)オブジェクトであり、またpanel2の(左上の点)が含まれるのはpanel1であるから、上記のような記述になる。
 では、panel3は、どのように記述されるであろうか。panel3のコントロールの親のコントロールはpanel2であるから、スクリーン座標系でpanel3の位置を表すと、

Point p31 = panel3.Location;             // panel3の左上の座標をpanel2の座標系で表した点p31
Point p32 = panel2.PointToScreen(p31);   // 点p31をスクリーンの座標系で表した座標p32

となる。

 それならばpanel4の場合は、親がpanel1と同様にフォーム(this)であるから、

Point p41 = panel4.Location;           // panel4の左上の座標をフォーム(this)の座標系で表した点p41
Point p42 = this.PointToScreen(p41);   // 点p41をスクリーンの座標系で表した座標p42

となる。

4.PointToClientメソッド
 PointToClientメソッドは、スクリーン座標系で表された(コントロールの左上の角の)点を、別のコントロールの座標系に変換するメソッドである。
 基本的な使い方は、

Point p = 表したい座標系を持つコントロールのオブジェクト.PointToClient(知りたい点のスクリーン座標)

 また写真-2を例に挙げて説明する。
 panel1の(左上の角の)位置を、Locationプロパティで表したフォームの座標系、PointToScreenメソッドで用いたスクリーンの座標系、スクリーン座標をPointToClientメソッドでフォームの座標系で表した例を示す。

Point p11 = panel1.Location;            // panel1の左上の座標をフォーム(this)の座標系で表した点p11
Point p12 = this.PointToScreen(p11);    // 点p11をスクリーンの座標系で表した座標p12 
Point p13 = this.PointToClient(p12);    // スクリーン座標で表されたp12をフォーム(this)の座標系に変換する

 こので注意しなければならないのは、PointToClientメソッドの前のオブジェクトは、表したい座標系のオブジェクトでなければならないのであり、この場合はフォームを表すthisでなければならない。

 次にpanel2の(左上の角の)位置を、Locationプロパティで表したフォームの座標系、PointToScreenメソッドで用いたスクリーンの座標系、スクリーン座標をPointToClientメソッドでフォームの座標系、panel1の座標系、panel2の座標系に変換して表した例を示す。

Point p21 = panel2.Location                 // panel2の左上の座標をpanel1の座標系で表した点p21
Point p22 = panel1.PointToScreen(p21);      // 点p21をスクリーンの座標系で表した座標p22
Point p23 = this.PointToClient(p22);        // 点p22をフォーム(this)の座標系で表した座標p23
Point p24 = panel1.PointToClient(p22);      // 点p21をpanel1の座標系で表した座標p24
Point p25 = panel2.PointToClient(p22);      // 点p21をpanel2の座標系で表した座標p25

 ここで注意しなければならないのは、panel2の左上の点をpanel2の座標系で表した点p25は、その座標が(0,0)になることである。(当然の話ではあるが、、、)

 さらに次に、panel4をpanel1からpanel3の座標系で表す例を示す。panel4は、panel1同様、前提条件からフォーム(this)に属している。しかし、panel2とpanel3とは、直接的な関係はない。しかし、一方でスクリーン座標系を通して変換することができる。

Point p41 = panel4.Location;                // panel2の左上の座標をフォーム(this)の座標系で表した点p41
Point p42 = this.PointToScreen(p41);        // 点p41をスクリーンの座標系で表した座標p42
Point p44 = panel1.PointToClient(p42);      // 点p42をpanel1の座標系で表した座標p44
Point p45 = panel2.PointToClient(p42);      // 点p42をpanel2の座標系で表した座標p45
Point p46 = panel3.PointToClient(p42);      // 点p42をpanel3の座標系で表した座標p46

4.以上をまとめたソースコード
 以上をまとめたソースコードを次に示す。コンパイルすると写真-1で示したフォームの実行ファイルができる。それを起動し、そのフォームをドラッグして動かすと、スクリーン座標系で表されたコントロールの座標の値が変わる。またスクリーン座標をPointToClientメソッドそれぞれの座標系に変換された座標が表示される。

                 ソースコード

ToScreenToClient.cs
using System;
using System.Drawing;
using System.Windows.Forms;

namespace ToScreenMethod
{
    class Form1 : Form
    {
        Panel panel1;
        Label label11, label12, label13, label14, label15;
        Point p11, p12, p13, p14;

        Panel panel2;
        Label label21, label22, label23, label24, label25, label26;
        Point p21, p22, p23, p24, p25;

        Panel panel3;
        Label label31, label32, label33, label34, label35, label36, label37;
        Point p31, p32, p33, p34, p35, p36;

        Panel panel4;
        Label label41, label42,label43, label44,label45,label46, label47;
        Point p41, p42, p43, p44, p45, p46;

        public static void Main()
        {
            Application.Run(new Form1());
        }

        public Form1()
        {
            // 
            // label41を定義
            label41 = new Label();
            label41.Location = new Point(0, 0);
            label41.AutoSize = true;

            // label42を定義
            label42 = new Label();
            label42.Location = new Point(0, label41.Height);
            label42.AutoSize = true;

            // label43を定義
            label43 = new Label();
            label43.AutoSize = true;
            label43.Location = new Point(0, label42.Location.Y + label42.Height);

            // label44を定義
            label44 = new Label();
            label44.AutoSize = true;
            label44.Location = new Point(0, label43.Location.Y + label43.Height);

            // label45を定義
            label45 = new Label();
            label45.AutoSize = true;
            label45.Location = new Point(0, label44.Location.Y + label44.Height);

            // label46を定義
            label46 = new Label();
            label46.AutoSize = true;
            label46.Location = new Point(0, label45.Location.Y + label45.Height);

            // label47を定義
            label47 = new Label();
            label47.AutoSize = true;
            label47.Location = new Point(0, label46.Location.Y + label46.Height);

            // panel4を定義
            panel4 = new Panel();
            panel4.Location = new Point(50, 700);
            panel4.Size = new Size(1100, 200);
            panel4.BorderStyle = BorderStyle.None;
            panel4.BackColor = Color.LightGreen;
            panel4.Controls.Add(label41);
            panel4.Controls.Add(label42);
            panel4.Controls.Add(label43);
            panel4.Controls.Add(label44);
            panel4.Controls.Add(label45);
            panel4.Controls.Add(label46);
            panel4.Controls.Add(label47);

            //
            // label31を定義
            label31 = new Label();
            label31.Location = new Point(0, 0);
            label31.AutoSize = true;

            // label32を定義
            label32 = new Label();
            label32.Location = new Point(0, label31.Height);
            label32.AutoSize = true;

            // label33を定義
            label33 = new Label();
            label33.AutoSize = true;
            label33.Location = new Point(0, label32.Location.Y + label32.Height);

            // label34を定義
            label34 = new Label();
            label34.AutoSize = true;
            label34.Location = new Point(0, label33.Location.Y + label33.Height);

            // label35を定義 
            label35 = new Label();
            label35.AutoSize = true;
            label35.Location = new Point(0, label34.Location.Y + label34.Height);

            // label36を定義
            label36 = new Label();
            label36.AutoSize = true;
            label36.Location = new Point(0, label35.Location.Y + label35.Height);

            // label37を定義
            label37 = new Label();
            label37.AutoSize = true;
            label37.Location = new Point(0, label36.Location.Y + label36.Height);

            // panel3を定義
            panel3 = new Panel();
            panel3.Location = new Point(50, 150);
            panel3.Size = new Size(900, 200);
            panel3.BorderStyle = BorderStyle.None;
            panel3.BackColor = Color.Pink;
            panel3.Controls.Add(label31);
            panel3.Controls.Add(label32);
            panel3.Controls.Add(label33);
            panel3.Controls.Add(label34);
            panel3.Controls.Add(label35);
            panel3.Controls.Add(label36);
            panel3.Controls.Add(label37);

            //
            // label21を定義
            label21 = new Label();
            label21.Location = new Point(0, 0);
            label21.AutoSize = true;

            // label22を定義
            label22 = new Label();
            label22.Location = new Point(0, label21.Height);
            label22.AutoSize = true;

            // label23を定義
            label23 = new Label();
            label23.AutoSize = true;
            label23.Location = new Point(0, label22.Location.Y + label22.Height);

            // label24を定義
            label24 = new Label();
            label24.AutoSize = true;
            label24.Location = new Point(0, label23.Location.Y + label23.Height);

            // label25を定義 
            label25 = new Label();
            label25.AutoSize = true;
            label25.Location = new Point(0, label24.Location.Y + label24.Height);

            // label26を定義
            label26 = new Label();
            label26.AutoSize = true;
            label26.Location = new Point(0, label25.Location.Y + label25.Height);

            // panel2を定義
            panel2 = new Panel();
            panel2.Location = new Point(50, 150);
            panel2.Size = new Size(1000, 400);
            panel2.BorderStyle = BorderStyle.None;
            panel2.BackColor = Color.Aqua;
            panel2.Controls.Add(label21);
            panel2.Controls.Add(label22);
            panel2.Controls.Add(label23);
            panel2.Controls.Add(label24);
            panel2.Controls.Add(label25);
            panel2.Controls.Add(label26);
            panel2.Controls.Add(panel3);  // panel2の上にパネルpanel3を追加

            // 
            // label11を定義
            label11 = new Label();
            label11.Location = new Point(0, 0);
            label11.AutoSize = true;

            // label12を定義
            label12 = new Label();
            label12.Location = new Point(0, label11.Height);
            label12.AutoSize = true;

            // label13を定義
            label13 = new Label();
            label13.AutoSize = true;
            label13.Location = new Point(0, label12.Location.Y + label12.Height);

            // label14を定義
            label14 = new Label();
            label14.AutoSize = true;
            label14.Location = new Point(0, label13.Location.Y + label13.Height);

            // label15を定義
            label15 = new Label();
            label15.AutoSize = true;
            label15.Location = new Point(0, label14.Location.Y + label14.Height);

            // panel1を定義
            panel1 = new Panel();
            panel1.Location = new Point(50, 50);
            panel1.Size = new Size(1100, 600);
            panel1.BorderStyle = BorderStyle.None;
            panel1.BackColor = Color.Yellow;
            panel1.Controls.Add(label11);
            panel1.Controls.Add(label12);
            panel1.Controls.Add(label13);
            panel1.Controls.Add(label14);
            panel1.Controls.Add(label15);
            panel1.Controls.Add(panel2);  // panel1の上にパネルpanel2を追加

            //
            // フォームを定義
            this.Width = 1200;
            this.Height = 950;
            this.Text = "ToScreenToClient";
            this.Controls.Add(panel1);  // フォーム(this)上にパネルpanel1を追加
            this.Controls.Add(panel4);  // フォーム(this)上にパネルpanel4を追加

            // イベントハンドラを登録
            this.LocationChanged += new EventHandler(Form1_LocationChanged);    // フォームが移動したことを検出

        }

        //フォームを移動した時に実行
        private void Form1_LocationChanged(object sender, EventArgs e)
        {
            //panel1
            label11.Text = "panel1の左上の座標";

            p11 = panel1.Location;
            label12.Text = "(1) panel1.Locationで示される座標(" + p11.X + "," + p11.Y + ")";

            p12 = this.PointToScreen(p11);  
            label13.Text = "(2) this.PointToScreen( (1)の座標系 ) で求められたスクリーン(モニタ)の左上を基準にした座標(" + p12.X + "," + p12.Y + ") <--- フォームをドラッグして動かすと、座標の表示が変わります。";

            p13 = this.PointToClient(p12);
            label14.Text = "(3) this.PointToClient( (2)のスクリーン座標系 ) で求められたフォーム(this)の左上を基準にした座標(" + p13.X + "," + p13.Y + ")     フォームを動かしても、(1)と同じ値。";

            p14 = panel1.PointToClient(p12);
            label15.Text = "(3) panel1.PointToClient( (2)のスクリーン座標系 ) で求められたpanel1の左上を基準にした座標(" + p14.X + "," + p14.Y + ")";


            //panel2
            label21.Text = "panel2の左上の座標";

            p21 = panel2.Location;
            label22.Text = "(1) Locationメソッドで示される座標(" + p21.X + "," + p21.Y + ")";

            p22 = panel1.PointToScreen(p21);  
            label23.Text = "(2) panel1.PointToScreen( (1)の座標系 ) で求められたスクリーン(モニタ)の左上を基準にした座標(" + p22.X + "," + p22.Y + ") <--- フォームをドラッグして動かすと、座標の表示が変わります。";

            p23 = this.PointToClient(p22);  
            label24.Text = "(3) this.PointToClient( (2)のスクリーン座標系 ) で求められたフォーム(this)の左上を基準にした座標(" + p23.X + "," + p23.Y + ") ";

            p24 = panel1.PointToClient(p22);
            label25.Text = "(4) panel1.PointToClient( (2)のスクリーン座標系 ) で求められたpanel1の左上を基準にした座標(" + p24.X + "," + p24.Y + ")     フォームを動かしても、(1)と同じ値。";

            p25 = panel2.PointToClient(p22);
            label26.Text = "(5) panel2.PointToClient( (2)のスクリーン座標系 ) で求められたpanel2の左上を基準にした座標(" + p25.X + "," + p25.Y + ")";


            //panel3
            label31.Text = "panel3の左上の座標";

            p31 = panel3.Location;
            label32.Text = "(1) Locationメソッドで示される座標(" + p31.X + "," + p31.Y + ")";

            p32 = panel2.PointToScreen(p31); 
            label33.Text = "(2) panel2.PointToScreen( (1)の座標系 ) で求められたスクリーン(モニタ)の左上を基準にした座標(" + p32.X + "," + p32.Y + ") <--- フォームをドラッグして動かすと、座標の表示が変わります。";

            p33 = this.PointToClient(p32);  
            label34.Text = "(3) this.PointToClient( (2)のスクリーン座標系 ) で求められたフォーム(this)の左上を基準にした座標(" + p33.X + "," + p33.Y + ") ";

            p34 = panel1.PointToClient(p32);
            label35.Text = "(4) panel1.PointToClient( (2)のスクリーン座標系 ) で求められたpanel1の左上を基準にした座標(" + p34.X + "," + p34.Y + ")";

            p35 = panel2.PointToClient(p32);
            label36.Text = "(5) panel2.PointToClient( (2)のスクリーン座標系 ) で求められたpanel2の左上を基準にした座標(" + p35.X + "," + p35.Y + ")     フォームを動かしても、(1)と同じ値。";

            p36 = panel3.PointToClient(p32);
            label37.Text = "(6) panel3.PointToClient( (2)のスクリーン座標系 ) で求められたpanel3の左上を基準にした座標(" + p36.X + "," + p36.Y + ")";


            //panel4
            label41.Text = "panel4の左上の座標";

            p41 = panel4.Location;
            label42.Text = "(1) Locationメソッドで示される座標(" + p41.X + "," + p41.Y + ")";

            p42 = this.PointToScreen(p41);
            label43.Text = "(2) this.PointToScreen( (1)の座標系 ) で求められたスクリーン(モニタ)の左上を基準にした座標(" + p42.X + "," + p42.Y + ") <--- フォームをドラッグして動かすと、座標の表示が変わります。";

            p43 = this.PointToClient(p42);
            label44.Text = "(3) this.PointToClient( (2)のスクリーン座標系 ) で求められたフォーム(this)の左上を基準にした座標(" + p43.X + "," + p43.Y + ")      フォームを動かしても、(1)と同じ値。";

            p44 = panel1.PointToClient(p42);
            label45.Text = "(4) panel1.PointToClient( (2)のスクリーン座標系 ) で求められたpanel1の左上を基準にした座標(" + p44.X + "," + p44.Y + ")";

            p45 = panel2.PointToClient(p42);
            label46.Text = "(5) panel2.PointToClient( (2)のスクリーン座標系 ) で求められたpanel2の左上を基準にした座標(" + p45.X + "," + p45.Y + ")";

            p46 = panel3.PointToClient(p42);
            label47.Text = "(6) panel3.PointToClient( (2)のスクリーン座標系 ) で求められたpanel3の左上を基準にした座標(" + p46.X + "," + p46.Y + ")";

        }

    }
}

以上

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

WPF Prism の IDialogService で汎用的なダイアログを出せるものを作った

はじめに

Prism7.2 から IDialogService が実装されてダイアログ表示がいい感じになった
しかし、通知用や確認用などの汎用的なダイアログをプロジェクトごとにいちいち作るのも面倒くさい
なので IDialogService で呼び出せる一般的に使いそうなダイアログを作ってライブラリ化した

できたもの

Prism.CommonDialogPack

機能

通知ダイアログ

Norification.png

確認ダイアログ

Confirmation.png

ファイル選択ダイアログ

SingleFileSelect.png
MultiFileSelect.png

フォルダ選択ダイアログ

SingleFolderSelect.png
MultiFolderSelect.png

ファイル保存ダイアログ

FileSave.png

アイコンなどのカスタマイズ

Customize.png

Window のカスタマイズ

MahApps.png

使い方

IDialogService 自体の使い方は公式ドキュメントを読むのが早い。
ここでは Prism.CommonDialogPack の使い方だけを記述する。

登録

まずは App でモジュールの登録と独自に作った IDialogService の登録を行う。

App.xaml.cs
public partial class App
{
    protected override Window CreateShell()
    {
        return Container.Resolve<MainWindow>();
    }

    protected override void RegisterTypes(IContainerRegistry containerRegistry)
    {

    }

    protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
    {
        base.ConfigureModuleCatalog(moduleCatalog);
        moduleCatalog.AddModule<CommonDialogPackModule>();
    }

    protected override void RegisterRequiredTypes(IContainerRegistry containerRegistry)
    {
        base.RegisterRequiredTypes(containerRegistry);
        CommonDialogPackModule.RegisterRequiredTypes(containerRegistry);
    }
}

Prism が提供してくれている DialogService は Window の Style を DialogWindow を介してセットしているが、Window に単に代入するような実装になっているのでライブラリにした時に使う側から Style を指定することができない。
Prism.CommonDialogPack では Dialog の呼び出し側から Style を指定できるようにするため、StyleableDialogService という独自の IDialogService 実装を作っている。
違いはConfigureDialogWindowPropertiesメソッドだけで、ViewModel が IStyleableDialogAware だった場合は Style をバインディングするようにしている。
(ConfigureDialogWindowPropertiesメソッドに virtual がついていないのでもとの DialogServiceを模倣している)

IStyleableDialogAware は IDialogAware に WindowStyle や Height, Width などを追加したインターフェイスで、ダイアログとして表示する View の ViewModel に実装することでライブラリの呼び出し側からの Style 指定などを可能にしている。

RegisterRequiredTypes では標準の IDialogService の実態を DialogService ではなく StyleableDialogServiceにするようにコンテナに登録している。

呼び出し

呼び出しは IDialogService を介して行う。

MainWindowViewModel.cs
private void ShowNotificationDialog(IDialogService dialogService)
{
    var param = new DialogParameters
    {
        { DialogParameterNames.Title, "myNotification" }
    };
    dialogService.ShowDialog(DialogNames.Notification, param, res => 
    {
    });
}

こんな感じで通常の DialogService と変わらない。
呼び出せるダイアログの名前は DialogNamesに、
指定できるパラメーターの名前はDialogParameterNamesに、
受け取れるパラメーターの名前はDialogResultParameterNamesに定義してある。
パラメーターの受け取りは FileSelectDialog、FolderSelectDialog、FileSaveDialog でのみ可能で、コールバックで受け取れる IDialogResult の Parameters プロパティから取得する。

各ダイアログで指定できるパラメーターは以下の通り

共通

名前 内容
Title string Window のタイトル
Width double Window の幅
Height double Window の高さ
ContentWidth double Content の幅
ContentHeight double Content の高さ
WindowStyle System.Windows.Style Window の Style

NotificationDialog

名前 内容
Message string 表示するメッセージ
ButtonText sgring ボタンのテキスト

ConfirmationDialog

名前 内容
Message string 表示するメッセージ
OKButtonText sgring OK ボタンのテキスト
CancelButtonText sgring Cancel ボタンのテキスト

FileSelectDialog

名前 内容
ExplorerIcons Prism.CommonDialogPack.ExplorerIcons アイコン
FileNameText string "ファイル名"のテキスト
SelectButtonText string 選択ボタンのテキスト
CancelButtonText string Cancel ボタンのテキスト
Filters IEnumerable<Prism.CommonDialogPack.FileFilter> 表示するファイルのフィルター
TextResource Prism.CommonDialogPack.ExplorerBaseTextResource ExplorerBase に表示するテキスト
CanMultiSelect bool 複数選択可能かどうか
RootFolders IEnumerable<string> ルートにするフォルダーのパス

FolderSelectDialog

名前 内容
ExplorerIcons Prism.CommonDialogPack.ExplorerIcons アイコン
FolderNameText string "フォルダー名"のテキスト
SelectButtonText string 選択ボタンのテキスト
CancelButtonText string Cancel ボタンのテキスト
TextResource Prism.CommonDialogPack.ExplorerBaseTextResource ExplorerBase に表示するテキスト
CanMultiSelect bool 複数選択可能かどうか
RootFolders IEnumerable<string> ルートにするフォルダーのパス

FileSaveDialog

名前 内容
ExplorerIcons Prism.CommonDialogPack.ExplorerIcons アイコン
FileNameText string "ファイル名"のテキスト
FileTypeText string "ファイルの種類"のテキスト
SaveButtonText string 保存ボタンのテキスト
CancelButtonText string Cancel ボタンのテキスト
InitialSaveFileName string 初期ファイル名
Filters IEnumerable<Prism.CommonDialogPack.FileFilter> 表示するファイルのフィルター
TextResource Prism.CommonDialogPack.ExplorerBaseTextResource ExplorerBase に表示するテキスト
CanMultiSelect bool 複数選択可能かどうか
RootFolders IEnumerable<string> ルートにするフォルダーのパス
OverwriteConfirmationTitle string 上書き確認ダイアログのタイトル
OverwriteConfirmationMessageFunc Func<string, string> 上書き確認ダイアログのメッセージ生成関数
OverwriteConfirmationOKButtonText string 上書き確認ダイアログの OK ボタンのテキスト
OverwriteConfirmationCancelButtonText string 上書き確認ダイアログの Cancel ボタンのテキスト

OverwriteConfirmationMessageFunc にはファイルのフルパスが渡される

その他のクラスについて

ExplorerIcons

パラメーターで渡せば FileSelectDialog, FolderSelectDialog, FileSaveDialog のアイコンをカスタムできる。

FileFilter

パラメーターで渡せば FileSelectDialog, FileSaveDialog で表示するファイルの拡張子にフィルターをかけることができる。

new FileFilter("All Files (*.*)"),
new FileFilter("Text File (*.txt; *.csv)", new[] { ".txt", ".csv" }),
new FileFilter("Excel File (*.xlsx; *.xlsm; *.xls)", ".xlsx", ".xlsm", ".xls"),

使い方はこんな感じで、Text プロパティの文字列が ComboBox に表示され、Extensions プロパティの文字列が実際にフィルターする拡張子となる。
Extensions が空だとフィルターしない。
FileSaveDialog の場合は保存するファイルの拡張子を指定する意図で使用するため、Extensions を複数指定しても最初のものだけフィルターされる。

ExplorerBaseTextResource

パラメーターで渡せば ExplorerBase の各テキストをカスタムできる。

DialogServiceExtensions

ダイアログの呼び出しを簡素化した拡張メソッドを定義したクラス。

Window のカスタマイズ

これ自体は IDialogService の機能なので、やり方も同じ。
ダイアログに使いたい Window にコードビハインドでIDialogWindowを実装する
IDialogWindowIDialogResultプロパティを持っているだけ

MyMetroWindow.xaml.cs
public partial class MyMetroWindow : MetroWindow, IDialogWindow
{
    public IDialogResult Result { get; set; }

    public MyMetroWindow()
    {
        InitializeComponent();
    }
}

あとはRegisterDialogWindowでコンテナに登録する

App.xaml.cs
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
    containerRegistry.RegisterDialogWindow<MyMetroWindow>();
}

おわりに

Prism.CommonDialogPack にはサンプルもつけているので、詳細はそっちを見ればわかるかも。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Unity】3D Game Kitのアセットをインポートしたらエラーが出た場合の対処法

現象

Unityの公式の「3D Game Kit」という3Dアクションゲームのテンプレートアセットがあるのですが、こちらをインポートしたところ以下のようなエラーが出ました。

Library\PackageCache\com.unity.timeline@1.2.6\Runtime\Utilities\AnimatorBindingCache.cs(91,40): error CS0117: 'AnimationMode' does not contain a definition for 'GetCurveBindings'

この解決法を調べたところいくつか解決策を載せてくれているのですが、私のバージョンでは上手くいかなかったので、自分のバージョンでの解決策を載せておきます。

環境

Unity : 2019.3.0a5
3D Game Kit : 1.9
OS : Windows10

解決策

このエラーはUnityのパッケージの最新バージョンにこのアセットが対応していないことによるエラーなので、パッケージのバージョンを前のバージョンに戻すことで解決できます。

  1. 上のメニューから Window > Package Manager を開きます。
  2. 検索欄にTimelineと入力してTimelineのパッケージを探します。
  3. 左の三角アイコンをクリックして利用可能なバージョンを出します。
  4. 以前のバージョンを選択して右下のUpdateを押します。

この記事を書いたときは1.2.10から1.1.0にダウングレードしました。
image.png

すると最初のエラーは消えるはずです。

しかし今度は以下のようなエラーがでます。

Library\PackageCache\com.unity.ide.rider@1.1.4\Rider\Editor\RiderScriptEditor.cs(385,65): error CS0117: 'AssetDatabaseExperimental' does not contain a definition for 'IsAssetImportWorkerProcess'

同様の手順で、「Rider Editor」をパッケージマネージャーで検索してverifiedバージョンにupdateします。

最後に「ProBuilder」も同様の手順でupdateします。

Library\PackageCache\com.unity.probuilder@4.2.3\Editor\EditorCore\ShapeEditor.cs(186,37): error CS0117: 'ActiveEditorTracker' does not contain a definition for 'RebuildAllIfNecessary'

これでサンプルシーンから実行ができるようになりました!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む