C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[4]: ユーザーコントロールの処理の方法について


(過去ログ 128 を表示中)

[トピック内 10 記事 (1 - 10 表示)]  << 0 >>

■75927 / inTopicNo.1)  ユーザーコントロールの処理の方法について
  
□投稿者/ よぽん (14回)-(2015/05/19(Tue) 11:37:06)

分類:[.NET 全般] 

環境は Windows7 VisualStudio2010 c# .NET4.5 です。

ユーザーコントロールを作ってフォームに貼付しました。
フォームのロード時の1回のみ処理をさせたいような場合。
どうすればよいのでしょうか?

Count(0) フラグを持って
VisibleChagnedイベントで
Count(0) の場合処理を行ってCount(1)にして、
Count(1) の場合に処理をしないようにするしかないのでしょうか?

処理する前に、プロパティの設定値を使用するので
コンストラクタはプロパティ設定の前に処理されるので、できませんでした。

引用返信 編集キー/
■75928 / inTopicNo.2)  Re[1]: ユーザーコントロールの処理の方法について
□投稿者/ shu (742回)-(2015/05/19(Tue) 12:34:08)
No75927 (よぽん さん) に返信

ユーザーコントロールにもLoadイベントがありますが駄目でしょうか?


VisibleChangedイベントを使うなら。こんな方法もあります。


    public partial class UserControl1 : UserControl
    {
        public UserControl1()
        {
            InitializeComponent();
            this.VisibleChanged += Init;
        }

        private void Init(object sender, EventArgs e)
        {
            this.VisibleChanged -= Init;
            //ここで処理
        }
    }

引用返信 編集キー/
■75929 / inTopicNo.3)  Re[2]: ユーザーコントロールの処理の方法について
□投稿者/ よぽん (15回)-(2015/05/19(Tue) 13:00:17)
ありがとうございます。
ユーザーコントロールにはあったんですね。

厳密には、ユーザーコントロールではないですね。

コードから下の1行を変更
public partial class UserControl1 : UserControl

public partial class UserControl1 : ComboBox

デザイナから下の1行を削除
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;

これを行った時点で Load イベントが消えるみたいですね。
消えていなければつかえたのですけど。


なるほどぉ、フラグ使わなくてもイベントごと消しちゃえばいいんですねぇ。
一回だけのものなら
this.VisibleChanged += Init0;
なら、必要なものは
this.VisibleChanged += Init1;

にしちゃって一回だけのものだけ消しちゃえばいいんだぁ
this.VisibleChanged -= Init0;

ちなみに、今調べてたんですけど、以下の1行でできるみたいな
ContentRendered += (s, e) => { MessageBox.Show("ContentRendered", "TEST"); };

調べてるんですけど ContentRenderd で「現在のコンテキスト内に存在しません。」
のエラーで行き詰ってます。

使い方教えてくださぁい。
引用返信 編集キー/
■75931 / inTopicNo.4)  Re[3]: ユーザーコントロールの処理の方法について
□投稿者/ 魔界の仮面弁士 (329回)-(2015/05/19(Tue) 13:26:09)
No75929 (よぽん さん) に返信
> ちなみに、今調べてたんですけど、以下の1行でできるみたいな

それは別の情報かと。


> ContentRendered += (s, e) => { MessageBox.Show("ContentRendered", "TEST"); };

ContentRendered は、WPF で用いられるイベントの一つですね。
右辺の (s, e) 以降は『ラムダ式』と呼ばれる記述です。


> 使い方教えてくださぁい。

以下に、『Form1 の Click イベント』を記述する例を 8 パターン挙げておきます。
よぽんさんが書かれたコードは、下記の「パターンC2」に相当する記述ですね。


// パターンA1:EventHandler デリゲートのインスタンスを割り当てる
private void Form1_Load(object sender, EventArgs e)
{
    this.Click += new EventHandler(Form1_Click);
}
void Form1_Click(object sender, EventArgs e)
{
    MessageBox.Show("Test");
}


// パターンA2:デリゲート型の指定を省略
private void Form1_Load(object sender, EventArgs e)
{
    this.Click += this.Form1_Click;
}
void Form1_Click(object sender, EventArgs e)
{
    MessageBox.Show("Test");
}


// パターンB1:匿名メソッドを割り当てる
private void Form1_Load(object sender, EventArgs e)
{
    this.Click += delegate(object o, EventArgs arg)
    {
        MessageBox.Show("Test");
    };
}


// パターンB2:匿名メソッドで引数指定を省く
private void Form1_Load(object sender, EventArgs e)
{
    this.Click += delegate
    {
        MessageBox.Show("Test");
    };
}


// パターンC1:単一行ラムダ式を割り当てる
private void Form1_Load(object sender, EventArgs e)
{
    this.Click += (object o, EventArgs arg) => MessageBox.Show("Test");
}


// パターンC2:単一行ラムダ式で型推論を用いる
private void Form1_Load(object sender, EventArgs e)
{
    this.Click += (o, arg) => MessageBox.Show("Test");
}


// パターンD1:複数行ラムダ式を割り当てる
private void Form1_Load(object sender, EventArgs e)
{
    this.Click += (object o, EventArgs arg) =>
    {
        var s = "Test";
        MessageBox.Show(s);
    };
}


// パターンD2:複数行ラムダ式で型推論を用いる
private void Form1_Load(object sender, EventArgs e)
{
    this.Click += (o, arg) =>
    {
        var s = "Test";
        MessageBox.Show(s);
    };
}

引用返信 編集キー/
■75933 / inTopicNo.5)  Re[3]: ユーザーコントロールの処理の方法について
□投稿者/ 魔界の仮面弁士 (331回)-(2015/05/19(Tue) 13:54:00)
No75927 (よぽん さん) に返信
> フォームのロード時の1回のみ処理をさせたいような場合。
> どうすればよいのでしょうか?

そのクラスに ISupportInitialize インターフェイスを実装しては如何でしょう。
https://social.msdn.microsoft.com/Forums/ja-JP/57d18cbf-4253-4090-89d9-0fc26f310306



No75929 (よぽん さん) に返信
> this.VisibleChanged += Init0;
> なら、必要なものは
> this.VisibleChanged += Init1;

こういう方法もあります。


protected override void OnVisibleChanged(EventArgs e)
{
 if(this.DesignMode && this.初回)
 {
  VisibleChangedイベントの直前に実施する処理();
 }

 // 本来の VisiblChanged イベントを発動
 base.OnVisibleChanged(e);

 if(this.DesignMode && this.初回)
 {
  VisibleChangedイベントの直後に実施する処理();
  this.初回 = false;
 }
}
引用返信 編集キー/
■75946 / inTopicNo.6)  Re[4]: ユーザーコントロールの処理の方法について
□投稿者/ よぽん (16回)-(2015/05/20(Wed) 09:47:53)
初心者的な質問ですけど

このユーザーコントロールが貼ってあるフォームが
ShowDialogで表示している場合は
VisibleChange って最初の一回だけしか呼ばれないのでしょうか?
試してみたのですが、最小化したり別のフォームを上に持っていったり
してみましたが、イベント発生しませんでした。

最初に Visible が true になると false にならないのであれば
Loadと同じ扱いができそうな気がすんですけど。

プログラム的には条件が限定されたユーザーコントロールはダメなんですけどね。
引用返信 編集キー/
■75948 / inTopicNo.7)  Re[4]: ユーザーコントロールの処理の方法について
□投稿者/ よぽん (17回)-(2015/05/20(Wed) 09:58:15)
No75933 (魔界の仮面弁士 さん) に返信

> そのクラスに ISupportInitialize インターフェイスを実装しては如何でしょう。
> https://social.msdn.microsoft.com/Forums/ja-JP/57d18cbf-4253-4090-89d9-0fc26f310306

ごめんなさい。よくわかりませんでした。

>
> こういう方法もあります。
>
>
> protected override void OnVisibleChanged(EventArgs e)
> {
>  if(this.DesignMode && this.初回)
>  {
>   VisibleChangedイベントの直前に実施する処理();
>  }
>
>  // 本来の VisiblChanged イベントを発動
>  base.OnVisibleChanged(e);
>
>  if(this.DesignMode && this.初回)
>  {
>   VisibleChangedイベントの直後に実施する処理();
>   this.初回 = false;
>  }
> }

試しにやってみたのですけど。
this.DesignMode は常に false のような気がします。

引用返信 編集キー/
■75949 / inTopicNo.8)  Re[5]: ユーザーコントロールの処理の方法について
□投稿者/ ザカート (1回)-(2015/05/20(Wed) 10:09:15)
VisibleChange って、表示/非表示(Closeではなく、表示されていないだけ)の
切り替えで発生するイベントですよ。

ところで、親フォームをShowDialogで開いているとのことですが、
この親フォームのインスタンスは1度だけ作成していますか?
それともShowDialogするたびに新しいインスタンスを作成していますか?
それにより、親フォームの内部状態は異なるため、対応も異なります。
引用返信 編集キー/
■75950 / inTopicNo.9)  Re[4]: ユーザーコントロールの処理の方法について
□投稿者/ よぽん (18回)-(2015/05/20(Wed) 10:09:54)
No75933 (魔界の仮面弁士 さん) に返信
>
> こういう方法もあります。
>

わかりましたかな?。
これって、実行時の1回じゃぁなくて
デザイン時に1回だけ処理するってことですよね?




引用返信 編集キー/
■75951 / inTopicNo.10)  Re[5]: ユーザーコントロールの処理の方法について
□投稿者/ 魔界の仮面弁士 (335回)-(2015/05/20(Wed) 10:59:52)
No75948 (よぽん さん) に返信
>>そのクラスに ISupportInitialize インターフェイスを実装しては如何でしょう。
>>https://social.msdn.microsoft.com/Forums/ja-JP/57d18cbf-4253-4090-89d9-0fc26f310306
> ごめんなさい。よくわかりませんでした。

「ISupportInitialize.EndInit メソッドが呼び出されたとき」を
「Form が Load される直前」とみなすという考え方です。


たとえば NumericUpDown コントロールにおいては、
 Minimumプロパティの値 ≦ Valueプロパティの値 ≦ Maximumプロパティの値
の関係を満たすよう実装されています。(Value が範囲外だと例外を発します)

しかしデザイナで設定された場合、プロパティの設定順が保証されません。
そのため、このクラスには ISupportInitialize インターフェイスが実装されています。
(NumericUpDown を貼ったフォームの InitializeComponent の内容を確認してみてください)


ISupportInitialize.BeginInit が呼び出された後は、プロパティの範囲チェックが行われませんが、
ISupportInitialize.EndInit が呼び出された後は、プロパティの範囲チェックを行われます。


EndInit は、InitializeComponent の末尾で呼ばれますので、
このタイミングで処理すれば、「フォームのロード時の1回のみ」の
代用となるのではないでしょうか。



>> if(this.DesignMode && this.初回)
> 試しにやってみたのですけど。
> this.DesignMode は常に false のような気がします。

失礼しました。 !this.DesignMode && の間違いです。

デザイナ画面に貼ったときには無視して、実際に実行する場合にのみ、
初回チェックを実行するという意図で書いていました。
(デザイン時にも実施したいなら、DesignMode の判定は不要です)
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -