ページ「X11vnc/ArchLinux」と「型付DataSetに列挙型を取り込む」の間の差分

提供: とある社畜の頭脳整理
(ページ間の差分)
ナビゲーションに移動 検索に移動
 
 
1行目: 1行目:
 +
型付DataSetに列挙型(enum)を取り込む場合、色々な方法があると思うんだ。一番簡単に想像できるのは、DataSetデザイナーで特定のテーブルの列の型を、ネームスペース含めて列挙型をしてしまうことなんだけど…。僕がやった限り、一回これをやってしまうとデータセットデザイナーが正しく開けなくなっちゃうんだよ。で、色々調べて・試してその結果たどり着いた(僕が)最善と思っている方法を紹介するよ。
  
= x11vncインストール =
+
== 考え方 ==
以下のコマンドを実行して、x11vncをインストールします。
+
色々やった結果…実はDataSetに列挙型を取り込むこと自体を諦めたんだよ…(^_^;)でも、コード上で毎回キャストしたくはなかったんだ…。そこで注目したのは、自動生成される型付DataSetはpartialクラスってことなんだ…。つまり、DataSetの定義は「Int32」でしておいて、DataSetのpartialを作って、そのクラスに列挙型で出し入れできるプロパティを作ってしまおうって事なんだよ。
<syntaxhighlight lang="bash">pacman -S x11vnc</syntaxhighlight>
 
  
= x11vncのパスワード設定 =
+
=== partialクラスってなに??? ===
誰でもつなげられるのはセキュリティ的に問題なので、パスワードを設定します。
+
partialクラスって言うのは、クラス定義を分割して定義している(ないしはできる)クラスのことを言うんだよ。たとえば、以下のようなクラスがあったとするよね…
<syntaxhighlight lang="bash">x11vnc -storepasswd</syntaxhighlight>
 
<syntaxhighlight lang="text">Enter VNC password:
 
Verify password:   
 
Write password to /home/user/.vnc/passwd?  [y]/n y
 
Password written to: /home/user/.vnc/passwd</syntaxhighlight>
 
上記の例ではホームディレクトリに保存していますが、別のディレクトリでも構いません。<br/>
 
別のディレクトリに保存した場合は、起動コマンドを見直してください。
 
  
= ログイン画面からvnc =
+
<syntaxhighlight lang="C#">
普通に使用するとログインしないとvncは使用できない?のですが…<br/>
+
namespace CommonCtrlLib
ログイン画面からvncで接続できるようにしてみます。
+
{
 +
    public class Class1
 +
    {
 +
        private Int32 m_field_A;
  
== gdmの場合 ==
+
        public Class1()
ディスプレイマネージャにgdmを使用している場合です。
+
        {
 +
            this.m_field_A = -1;
 +
        }
  
=== gdmの設定変更 ===
+
        public Int32 field_A
GNOMEでWaylandを使用している場合は、Waylandを無効化する必要があります。<br/>
+
        {
以下のファイルを編集して、Waylandを無効化します。
+
            get { return this.m_field_A; }
<syntaxhighlight lang="bash">nano /etc/gdm/custom.conf</syntaxhighlight>
+
            set { this.m_field_A = value; }
 +
        }
  
【修正前】
+
        public String field_B
<syntaxhighlight lang="text">#WaylandEnable=false</syntaxhighlight>
+
        {
【修正後】
+
            get { return this.m_field_A.ToString(); }
<syntaxhighlight lang="text">WaylandEnable=false</syntaxhighlight>
+
            set { this.m_field_A = Int32.Parse(value); }
 +
        }
 +
    }
 +
}
 +
</syntaxhighlight>
  
 +
クラス内の定義って言うのはclass{}の中に記述しないといけないから、つまるところ1ファイルの中にすべて書かないといけないって事になっちゃうんだよね。でも、諸事情により別のファイルに書きたいときもあると思うんだ。自動生成されたDataSetのファイルなんかは特にそうで…自動生成されたファイルをカスタマイズしちゃうと、また自動生成したときにカスタマイズが消えちゃったりするんだ。そんなときに、自分のカスタマイズ部分だけ別のファイルに書ければ…ってことになるんだよ。
  
編集後は再起動かgdmサービスのreloadをしてください。
+
そんなときはclassをpartial型で定義するとできちゃうんだよ。
  
=== x11vncの起動 ===
+
ファイル1
以下のコマンドを実行して、x11vncを起動します。<br/>
+
<syntaxhighlight lang="C#">
環境によって設定内容が異なるので、多少見直してください。
+
namespace TestLibrary
<syntaxhighlight lang="bash">sudo x11vnc -auth /run/user/120/gdm/Xauthority -display :0 -rfbauth /home/[userid]/.vnc/passwd -forever -noxdamage -xkb -wf -cursor most -fixscreen V=10 -fixscreen C=10 -loop</syntaxhighlight>
+
{
 +
    public partial class Class1
 +
    {
 +
        private Int32 m_field_A;
  
で…vncで接続してログインすると画面が真っ黒になる…<br/>
+
        public Class1()
調べたところログイン後はDisplay:1になるとのこと…<br/>
+
        {
なので、一旦「Ctrl+C」でx11vncを終了させて、改めて以下のコマンドを実行してvncでつなぎなおします。
+
            this.m_field_A = -1;
<syntaxhighlight lang="bash">x11vnc -display :1</syntaxhighlight>
+
        }
  
ちなみにポート番号は5900番のまま見たいです…<br/>
+
        public Int32 field_A
つなぎ直す必要があるのは面倒ですね…
+
        {
 +
            get { return this.m_field_A; }
 +
            set { this.m_field_A = value; }
 +
        }
 +
    }
 +
}
 +
</syntaxhighlight>
 +
ファイル2
 +
<syntaxhighlight lang="C#">
 +
namespace TestLibrary
 +
{
 +
    public partial class Class1
 +
    {
 +
        public String field_B
 +
        {
 +
            get { return this.m_field_A.ToString(); }
 +
            set { this.m_field_A = Int32.Parse(value); }
 +
        }
 +
    }
 +
}
 +
</syntaxhighlight>
  
== LightDMの場合 ==
+
こうやって定義すると、2つのファイルに分かれているclass定義でも、1つのclassとして扱うことができるんだ。
試しに、ディスプレイマネージャをLightDMに切り替えてvncしてみました。<br/>
 
以下のコマンドを実行して、x11vncを起動します。<br/>
 
gdmの時と同様に、環境によって設定内容が異なるので、多少見直してください。
 
<syntaxhighlight lang="bash">sudo x11vnc -auth /var/lib/lightdm/.Xauthority -display :0 -rfbauth /home/[userid]/.vnc/passwd -forever -noxdamage -xkb -wf -cursor most -fixscreen V=10 -fixscreen C=10 -loop</syntaxhighlight>
 
  
こちらの場合はつなぎ直す必要は無いようです。
+
== 型付DataSetの作成 ==
 +
列挙型を取り込みたいって悩んでいる人には、このステップは用済みかもしれないけど一応書いておくね。VisualStudioを起動してプロジェクトを開いている前提で手順をあげるよ。
  
= 経験したトラブル =
+
<ol>
== MAC error ==
+
<li>ソリューションエクスプローラーからDataSetを追加したいプロジェクトを右クリックする。</li>
ジャーナルに以下のメッセージを出力してVNCが切断される事象が発生しました。
+
<li>メニューから「追加」→「新しい項目」を選択する。</li>
<pre>archlinux sshd[1108]: error: Received disconnect from x:x:x:x:x:x:x:x port 56413:1: MAC Error</pre>
+
<li>(C♯の)一覧からデータセットを選択し、名前に適当なファイル名を入れ、「追加」ボタンをクリックする。</li>
何となく色の関係かなと思って、VNCViewerの色の数を少なくしたらひとまず発生しなくなりました…。<br/>
+
<li>デザイナーが開くので、ツールボックスからDataTableをデザイナーにドラッグアンドドロップしてテーブルを追加する。テーブル名は適当に変更する。</li>
(これが正しい対処なのかは不明です…)
+
<li>デザイナーのテーブルを右クリックして、「追加」→「列」を選択し、適当な列を追加する。</li>
 +
<li>必要に応じてキーを設定する</li>
 +
</ol>
  
= 参考サイト =
+
ここで、列挙型を保存したい列の型を「System.Int32」に変更するんだよ。
[https://wiki.archlinux.jp/index.php/X11vnc X11vnc - ArchWiki]<br/>
+
デザイナーで列を選択すると、プロパティウインドウに列のプロパティが表示されるんだ。その中の「DataType」プロパティの値を「System.Int32」に変更するんだよ。
[http://ossan-engineer.blogspot.com/2017/01/x11vncxvfbxdummyvirtualgl.html おっさんエンジニアの実験室: x11vnc、Xvfb、Xdummy、VirtualGLの使いこごち]<br/>
 
  
[[Category:ArchLinux]]
+
== partialクラスの追加 ==
[[Category:x11vnc]]
+
partialクラスを追加する方法もインターネットを調べると色々出てくるんだけど…どうやらMicrosoftはこの方法を推奨しているみたいなんだよ。
{{DISPLAYTITLE:x11vnc/ArchLinux}}
+
<ol>
 +
<li>データセットデザイナを表示する。</li>
 +
<li>データセットデザイナの何も書かれていないところ(余白?)をダブルクリックする。</li>
 +
<li>以下のようなコードが表示される(ネームスペースが「TestLibrary」で、データセットクラス名が「DataSet1」の場合)
 +
<source lang="csharp">
 +
namespace TestLibrary {
 +
   
 +
   
 +
    public partial class DataSet1 {
 +
    }
 +
}
 +
</source>
 +
</li>
 +
</ol>
 +
これでDataSetのpartialクラスが追加されたんだよ。ソリューションエクスプローラーを見ても「xxxxx.xsd」ファイルの配下にこのpartialクラスのファイルが入っていて、見た目にもすっきりしていると思うんだ。
 +
 
 +
== partialクラスにメソッドを追加 ==
 +
作成されたpartialクラスに列挙型で出し入れできる、プロパティを追加するよ。手順とかじゃなくて、追加したpartialクラスを以下の様に修正するんだよ。
 +
;namespace:TestLibrary
 +
;DataSet名:DataSet1
 +
;DataTable名:DataTable1
 +
;DataColumn名:DataColumn1
 +
;列挙型名:e_Test
 +
 
 +
<source lang="csharp">
 +
namespace TestLibrary {
 +
    public partial class DataSet1 {
 +
        partial class DataTable1Row
 +
        {
 +
            public e_Test EnumDataColumn1
 +
            {
 +
                get
 +
                {
 +
                    return (e_Test)this.DataColumn1;
 +
                }
 +
                set
 +
                {
 +
                    this.DataColumn1 = (Int32)value;
 +
                }
 +
            }
 +
        }
 +
    }
 +
}
 +
</source>
 +
 
 +
これで、列挙型で出し入れできるメソッドを追加することができたよ。もしWPFでバインドしたいときなどは、Int32で取り出すメソッド(この場合「DataColumn1」)でバインドすれば、特に悩むことなく実現できると思うんだ。
 +
 
 +
== 参考サイト ==
 +
[https://msdn.microsoft.com/ja-jp/library/ms171896.aspx MSDN - 方法 : データセットの機能を拡張する]<br/>
 +
[http://gushwell.ldblog.jp/archives/50810947.html Gushwell's C# Dev Notes - DataSetのカラムで列挙型を扱うには]
 +
 
 +
[[Category:C♯]]
 +
[[Category:Dataset]]

2019年7月26日 (金) 07:38時点における版

型付DataSetに列挙型(enum)を取り込む場合、色々な方法があると思うんだ。一番簡単に想像できるのは、DataSetデザイナーで特定のテーブルの列の型を、ネームスペース含めて列挙型をしてしまうことなんだけど…。僕がやった限り、一回これをやってしまうとデータセットデザイナーが正しく開けなくなっちゃうんだよ。で、色々調べて・試してその結果たどり着いた(僕が)最善と思っている方法を紹介するよ。

考え方

色々やった結果…実はDataSetに列挙型を取り込むこと自体を諦めたんだよ…(^_^;)でも、コード上で毎回キャストしたくはなかったんだ…。そこで注目したのは、自動生成される型付DataSetはpartialクラスってことなんだ…。つまり、DataSetの定義は「Int32」でしておいて、DataSetのpartialを作って、そのクラスに列挙型で出し入れできるプロパティを作ってしまおうって事なんだよ。

partialクラスってなに???

partialクラスって言うのは、クラス定義を分割して定義している(ないしはできる)クラスのことを言うんだよ。たとえば、以下のようなクラスがあったとするよね…

namespace CommonCtrlLib
{
    public class Class1
    {
        private Int32 m_field_A;

        public Class1()
        {
            this.m_field_A = -1;
        }

        public Int32 field_A
        {
            get { return this.m_field_A; }
            set { this.m_field_A = value; }
        }

        public String field_B
        {
            get { return this.m_field_A.ToString(); }
            set { this.m_field_A = Int32.Parse(value); }
        }
    }
}

クラス内の定義って言うのはclass{}の中に記述しないといけないから、つまるところ1ファイルの中にすべて書かないといけないって事になっちゃうんだよね。でも、諸事情により別のファイルに書きたいときもあると思うんだ。自動生成されたDataSetのファイルなんかは特にそうで…自動生成されたファイルをカスタマイズしちゃうと、また自動生成したときにカスタマイズが消えちゃったりするんだ。そんなときに、自分のカスタマイズ部分だけ別のファイルに書ければ…ってことになるんだよ。

そんなときはclassをpartial型で定義するとできちゃうんだよ。

ファイル1

namespace TestLibrary
{
    public partial class Class1
    {
        private Int32 m_field_A;

        public Class1()
        {
            this.m_field_A = -1;
        }

        public Int32 field_A
        {
            get { return this.m_field_A; }
            set { this.m_field_A = value; }
        }
    }
}

ファイル2

namespace TestLibrary
{
    public partial class Class1
    {
        public String field_B
        {
            get { return this.m_field_A.ToString(); }
            set { this.m_field_A = Int32.Parse(value); }
        }
    }
}

こうやって定義すると、2つのファイルに分かれているclass定義でも、1つのclassとして扱うことができるんだ。

型付DataSetの作成

列挙型を取り込みたいって悩んでいる人には、このステップは用済みかもしれないけど一応書いておくね。VisualStudioを起動してプロジェクトを開いている前提で手順をあげるよ。

  1. ソリューションエクスプローラーからDataSetを追加したいプロジェクトを右クリックする。
  2. メニューから「追加」→「新しい項目」を選択する。
  3. (C♯の)一覧からデータセットを選択し、名前に適当なファイル名を入れ、「追加」ボタンをクリックする。
  4. デザイナーが開くので、ツールボックスからDataTableをデザイナーにドラッグアンドドロップしてテーブルを追加する。テーブル名は適当に変更する。
  5. デザイナーのテーブルを右クリックして、「追加」→「列」を選択し、適当な列を追加する。
  6. 必要に応じてキーを設定する

ここで、列挙型を保存したい列の型を「System.Int32」に変更するんだよ。 デザイナーで列を選択すると、プロパティウインドウに列のプロパティが表示されるんだ。その中の「DataType」プロパティの値を「System.Int32」に変更するんだよ。

partialクラスの追加

partialクラスを追加する方法もインターネットを調べると色々出てくるんだけど…どうやらMicrosoftはこの方法を推奨しているみたいなんだよ。

  1. データセットデザイナを表示する。
  2. データセットデザイナの何も書かれていないところ(余白?)をダブルクリックする。
  3. 以下のようなコードが表示される(ネームスペースが「TestLibrary」で、データセットクラス名が「DataSet1」の場合)
    namespace TestLibrary {
        
        
        public partial class DataSet1 {
        }
    }
    

これでDataSetのpartialクラスが追加されたんだよ。ソリューションエクスプローラーを見ても「xxxxx.xsd」ファイルの配下にこのpartialクラスのファイルが入っていて、見た目にもすっきりしていると思うんだ。

partialクラスにメソッドを追加

作成されたpartialクラスに列挙型で出し入れできる、プロパティを追加するよ。手順とかじゃなくて、追加したpartialクラスを以下の様に修正するんだよ。

namespace
TestLibrary
DataSet名
DataSet1
DataTable名
DataTable1
DataColumn名
DataColumn1
列挙型名
e_Test
namespace TestLibrary {
    public partial class DataSet1 {
        partial class DataTable1Row
        {
            public e_Test EnumDataColumn1
            {
                get
                {
                    return (e_Test)this.DataColumn1;
                }
                set
                {
                    this.DataColumn1 = (Int32)value;
                }
            }
        }
    }
}

これで、列挙型で出し入れできるメソッドを追加することができたよ。もしWPFでバインドしたいときなどは、Int32で取り出すメソッド(この場合「DataColumn1」)でバインドすれば、特に悩むことなく実現できると思うんだ。

参考サイト

MSDN - 方法 : データセットの機能を拡張する
Gushwell's C# Dev Notes - DataSetのカラムで列挙型を扱うには