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

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

ログ内検索
  • キーワードを複数指定する場合は 半角スペース で区切ってください。
  • 検索条件は、(AND)=[A かつ B] (OR)=[A または B] となっています。
  • [返信]をクリックすると返信ページへ移動します。
キーワード/ 検索条件 /
検索範囲/ 強調表示/ ON (自動リンクOFF)
結果表示件数/ 記事No検索/ ON
大文字と小文字を区別する

No.100455 の関連記事表示

<< 0 >>
■100455  【C#,VS2022,WPF】クリック待ちを実装したい
□投稿者/ エルデの王 -(2022/08/16(Tue) 03:10:20)

    分類:[.NET 全般] 

    2022/08/16(Tue) 03:18:02 編集(投稿者)


    お世話になっております。
    掲題の通り、C#のWPFです。

    ボタン押下などイベント実行後、
    ある程度処理をしたらクリックを行うまで処理を中断(つまり入力待ち)ということがしたいのですが、
    方法はあるでしょうか?

    ※ダイアログ、メッセージウィンドウなどの別ウィンドウを表示することは使用出来ません。
    ※言い換えれば、FrameのPageをShowDialogで出したい、みたいな感じです。

    ご指導ご鞭撻のほどよろしくお願いいたします……
親記事 /過去ログ175より / 関連記事表示
削除チェック/

■100458  Re[1]: 【C#,VS2022,WPF】クリック待ちを実装したい
□投稿者/ ぶなっぷ -(2022/08/16(Tue) 13:04:26)
    たぶん、みなさん、以下の意味が分からないと思われ。
    > ※言い換えれば、FrameのPageをShowDialogで出したい、みたいな感じです。
    
    もう少し、分かりやすく解説お願いいたします。
    
記事No.100455 のレス /過去ログ175より / 関連記事表示
削除チェック/

■100459  Re[1]: 【C#,VS2022,WPF】クリック待ちを実装したい
□投稿者/ KOZ -(2022/08/16(Tue) 16:00:46)
    No100455 (エルデの王 さん) に返信
    > ボタン押下などイベント実行後、
    > ある程度処理をしたらクリックを行うまで処理を中断(つまり入力待ち)ということがしたいのですが、
    > 方法はあるでしょうか?

    「C#でシグナル処理」
    https://qiita.com/rawr/items/6888778b53fc95c41f00

    ここが参考になりそうです。
記事No.100455 のレス /過去ログ175より / 関連記事表示
削除チェック/

■100460  Re[2]: 【C#,VS2022,WPF】クリック待ちを実装したい
□投稿者/ エルデの王 -(2022/08/16(Tue) 21:54:40)
    2022/08/16(Tue) 21:58:31 編集(投稿者)

    返信ありがとうございます。

    No100458 (ぶなっぷ さん) に返信
    > たぶん、みなさん、以下の意味が分からないと思われ。
    >>※言い換えれば、FrameのPageをShowDialogで出したい、みたいな感じです。
    >
    > もう少し、分かりやすく解説お願いいたします。
    >

    以下のようなことがしたいのです。
    Uri uri = new Uri("/Page010_SortieMenu.xaml", UriKind.Relative);
    using (Frame dlg = new Frame(uri))
    {
    if (dlg.ShowDialog() == DialogResult.OK)
    {
    //OKがクリックされた場合
    MessageBox.Show("aaa");
    } else
    {
    //キャンセルがクリックされた場合
    MessageBox.Show("キャンセルされました。");
    }
    }


    URLでの情報提供ありがとうございます。

    例を参考に記述したところ、画面は停止するものの、
    クリックを促す画面が表示されず、またクリックそのものも出来ない状態となりました……

    以下にコードを記しますので、何か不足の点がありましたら、お教えください。

    private readonly CountdownEvent condition = new CountdownEvent(1);
    private void Button_click(object sender, EventArgs e)
    {
            DoWork()
    //停止してここから先進まない
    MessageBox.Show("aaa");
    }
    private async void DoWork()
    {

    Uri uri = new Uri("/Page010_SortieMenu.xaml", UriKind.Relative);
          //以下が画面に表示されず
    await Task.Run(() =>
    {
    Application.Current.Dispatcher.Invoke((Action)(() =>
    {
    Frame frame = new Frame();
    frame.Source = uri;
    frame.Margin = new Thickness(0, 0, 0, 0);
    this.canvasMain.Children.Add(frame);
    }));
    });
          //アプリケーション全体が止まり、マウスを動かすことは出来るが、クリック出来ない
    condition.Wait();
    }

    private void Button_RightKeyDown(object sender, EventArgs e)
    {
          //wait後、クリック出来ないので意味がない
    condition.Signal();
    Thread.Sleep(1);
    condition.Reset();
    }
記事No.100455 のレス /過去ログ175より / 関連記事表示
削除チェック/

■100461  Re[3]: 【C#,VS2022,WPF】クリック待ちを実装したい
□投稿者/ Azulean -(2022/08/16(Tue) 23:18:55)
    No100460 (エルデの王 さん) に返信
    > クリックを促す画面が表示されず、またクリックそのものも出来ない状態となりました……
    
    プログラムは、書いた通りにしか動かないものです。
    コードを理解せずに適当に切り貼りしたら動かないのはそういうものです。
    
    
    >         private async void DoWork()
    >         {
    > 
    >             Uri uri = new Uri("/Page010_SortieMenu.xaml", UriKind.Relative);
    >       //以下が画面に表示されず
    >             await Task.Run(() =>
    >             {
    >                 Application.Current.Dispatcher.Invoke((Action)(() =>
    >                 {
    >                     Frame frame = new Frame();
    >                     frame.Source = uri;
    >                     frame.Margin = new Thickness(0, 0, 0, 0);
    >                     this.canvasMain.Children.Add(frame);
    >                 }));
    >             });
    >       //アプリケーション全体が止まり、マウスを動かすことは出来るが、クリック出来ない
    >             condition.Wait();
    >         }
    
    
    async キーワード内の await で処理再開した後(つまり元のスレッド=メインスレッド)で Wait したら固まるのはそうでしょう。
    今回のケースで Wait を書けて良いのは、別スレッド(Task 内)でしょうから。
    
    思うのですが、この内容なら別に DoWork とか await とかせず、Button_RightKeyDown の中に続きを書いたらよいのでは?
    経験が浅いと、1シーケンス(1つの関数の中でユーザー操作イベントを待つ)で作るしかない、そう作るのが楽だと思い込みがちですが、実際にはそう書く方が難しいので。
記事No.100455 のレス /過去ログ175より / 関連記事表示
削除チェック/

■100462  Re[4]: 【C#,VS2022,WPF】クリック待ちを実装したい
□投稿者/ エルデの王 -(2022/08/17(Wed) 02:23:25)
    返信ありがとうございます。

    > async キーワード内の await で処理再開した後(つまり元のスレッド=メインスレッド)で Wait したら固まるのはそうでしょう。
    > 今回のケースで Wait を書けて良いのは、別スレッド(Task 内)でしょうから。

    つまり、メインスレッドでクリック待ちをすることは、
    ダイアログボックスを用いることでしか出来ないということでしょうか?

    > 思うのですが、この内容なら別に DoWork とか await とかせず、Button_RightKeyDown の中に続きを書いたらよいのでは?
    > 経験が浅いと、1シーケンス(1つの関数の中でユーザー操作イベントを待つ)で作るしかない、そう作るのが楽だと思い込みがちですが、実際にはそう書く方が難しいので。

    提示したコードは使用感を確かめる為に記述したもので、
    実際にはゲームエンジンに内包されるコンパイラを実装する為にコードを書きます。
    よろしくお願いいたします。
記事No.100455 のレス /過去ログ175より / 関連記事表示
削除チェック/

■100463  Re[5]: 【C#,VS2022,WPF】クリック待ちを実装したい
□投稿者/ Azulean -(2022/08/17(Wed) 07:30:07)
    No100462 (エルデの王 さん) に返信
    > つまり、メインスレッドでクリック待ちをすることは、
    > ダイアログボックスを用いることでしか出来ないということでしょうか?

    基本的に、次の操作を受け付けるためには「メッセージループを回さないといけない」が Windows プログラミングの根底にあります。
    Windows Forms や WPF ではそのメッセージループを自分で書けないので、イベントハンドラの中でループし続けるようなことは避けなければなりません。


    ただし、async/await キーワードは擬似的に実現はできるでしょうね。
    別スレッド(Task)が終わってから再開するというコードが書けるため。
    ただし、右クリック以外のイベントも発生しますので、先にも書いたとおり、右クリックイベントに直接書いたら良いのでは?としました。


    > 提示したコードは使用感を確かめる為に記述したもので、
    > 実際にはゲームエンジンに内包されるコンパイラを実装する為にコードを書きます。

    都合良く、特定のイベントだけを待ち受けることはできませんので、仕様、あるいは設計から見直しましょう。
記事No.100455 のレス /過去ログ175より / 関連記事表示
削除チェック/

■100464  Re[6]: 【C#,VS2022,WPF】クリック待ちを実装したい
□投稿者/ kiku -(2022/08/17(Wed) 09:45:30)
    2022/08/17(Wed) 10:02:22 編集(投稿者)

    No100463 (Azulean さん) に返信
    > ■No100462 (エルデの王 さん) に返信
    >>つまり、メインスレッドでクリック待ちをすることは、
    >>ダイアログボックスを用いることでしか出来ないということでしょうか?

    Azuleanさんと同意見ですが、
    下記で実現できませんか? ==> エルデの王さん
    ※検証していません。
    ※メインスレッドを停止させずに待つ方法がawaitなので

    private readonly CountdownEvent condition = new CountdownEvent(1);
    private void Button_click(object sender, EventArgs e)
    {
            DoWork()
    MessageBox.Show("aaa");
    }
    private async void DoWork()
    {

    Uri uri = new Uri("/Page010_SortieMenu.xaml", UriKind.Relative);
          //以下が画面に表示されず
    await Task.Run(() =>
    {
    Application.Current.Dispatcher.Invoke((Action)(() =>
    {
    Frame frame = new Frame();
    frame.Source = uri;
    frame.Margin = new Thickness(0, 0, 0, 0);
    this.canvasMain.Children.Add(frame);
    }));
    });
    await Task.Run(() =>
    {
    condition.Wait();
    });
    }

    private void Button_RightKeyDown(object sender, EventArgs e)
    {
    condition.Signal();
    Thread.Sleep(1);
    condition.Reset();
    }
記事No.100455 のレス /過去ログ175より / 関連記事表示
削除チェック/

■100465  Re[7]: 【C#,VS2022,WPF】クリック待ちを実装したい
□投稿者/ Azulean -(2022/08/17(Wed) 10:44:09)
    野暮ですが…。

    No100464 (kiku さん) に返信
    > await Task.Run(() =>
    > {
    > condition.Wait();
    > });

    No100461 に「今回のケースで Wait を書けて良いのは、別スレッド(Task 内)でしょうから」と書きましたとおり、
    Dispatcher.Invoke である以上、メインスレッドの処理が終わるのを待つわけ(同期的実行)ですから、
    Dispatcher.Invoke の直後にそのまま書けば良く、Task.Run を2つに分ける必要はない認識です。
記事No.100455 のレス /過去ログ175より / 関連記事表示
削除チェック/

■100466  Re[8]: 【C#,VS2022,WPF】クリック待ちを実装したい
□投稿者/ kiku -(2022/08/17(Wed) 11:00:55)
    No100465 (Azulean さん) に返信
    > 野暮ですが…。
    >
    > ■No100464 (kiku さん) に返信
    >>await Task.Run(() =>
    >>{
    >> condition.Wait();
    >>});
    >
    > No100461 に「今回のケースで Wait を書けて良いのは、別スレッド(Task 内)でしょうから」と書きましたとおり、
    > Dispatcher.Invoke である以上、メインスレッドの処理が終わるのを待つわけ(同期的実行)ですから、
    > Dispatcher.Invoke の直後にそのまま書けば良く、Task.Run を2つに分ける必要はない認識です。

    同じ考えです。
    あえて分けて書いた方が、質問者さんにわかりやすいかなと思ったしだいです。
    自分も実際のコードでしたら、Invoke の直後に書くと思います。
記事No.100455 のレス /過去ログ175より / 関連記事表示
削除チェック/

■100469  Re[9]: 【C#,VS2022,WPF】クリック待ちを実装したい
□投稿者/ ぶなっぷ -(2022/08/17(Wed) 14:42:26)
    非同期にすべきは、バックグラウンドで行われる処理なのでは?
    
    WPFの仕様上、GUIはメインスレッドで行わないといけません。
    なので、こんな感じでどうでしょう?
    
    private void Button_click(object sender, EventArgs e)
    {
        Uri uri = new Uri("/Page010_SortieMenu.xaml", UriKind.Relative);
        Frame frame = new Frame();
        frame.Source = uri;
        frame.Margin = new Thickness(0, 0, 0, 0);
        this.canvasMain.Children.Add(frame);
        frame.ContentRendered += MainWindow_ContentRendered;
        frame.OKButton.Click += OKButton_Click;
    }
    
    private async void MainWindow_ContentRendered(object sender, EventArgs e)
    {
        await Task.Run(() =>
        {
            foreach(なんかループ)
            {
                // 非同期に行いたい処理
    
                // フラグが立っていたら、frameを閉じてbreak;
            }
        });
    }
    
    private void OKButton_Click(object sender, RoutedEventArgs e)
    {
        // フラグを立てる
    }
    
記事No.100455 のレス /過去ログ175より / 関連記事表示
削除チェック/

■100479  Re[10]: 【C#,VS2022,WPF】クリック待ちを実装したい
□投稿者/ エルデの王 -(2022/08/17(Wed) 17:53:05)
    No100469 (ぶなっぷ さん) に返信
    > 非同期にすべきは、バックグラウンドで行われる処理なのでは?
    > 
    > WPFの仕様上、GUIはメインスレッドで行わないといけません。
    > なので、こんな感じでどうでしょう?
    
    残念ですが、独自プログラミング言語を上から順番に実行していくものが作りたいので、、、
    
    まあつまり、
    event worldevent001
    <-
    	message("てst");
        if(true){
            	message("てstてst");
            }
    	message("てstてstてst");
    ->
    こういうコードがあるのですが、これを元に木構造を作り、
    ユーザーがクリックして進めるものにしたかったのです。
    
    案を頂きありがとうございます。
    
記事No.100455 のレス / END /過去ログ175より / 関連記事表示
削除チェック/

■100480  Re[9]: 【C#,VS2022,WPF】クリック待ちを実装したい
□投稿者/ KOZ -(2022/08/17(Wed) 18:04:29)
    2022/08/17(Wed) 18:04:56 編集(投稿者)

    No100466 (kiku さん) に返信
    > 同じ考えです。
    > あえて分けて書いた方が、質問者さんにわかりやすいかなと思ったしだいです。
    > 自分も実際のコードでしたら、Invoke の直後に書くと思います。

    待つところが違うような・・・

    private async void DoWork() {
    Uri uri = new Uri("/Page010_SortieMenu.xaml", UriKind.Relative);
    await Task.Run(() =>
    {
    condition.Reset();
    condition.Wait(); // ここで待つのでは?
    Application.Current.Dispatcher.Invoke((Action)(() =>
    {
    Frame frame = new Frame();
    frame.Source = uri;
    frame.Margin = new Thickness(0, 0, 0, 0);
    this.canvasMain.Children.Add(frame);
    }));
    });
    }
記事No.100455 のレス / END /過去ログ175より / 関連記事表示
削除チェック/

■100477  Re[7]: 【C#,VS2022,WPF】クリック待ちを実装したい
□投稿者/ エルデの王 -(2022/08/17(Wed) 17:41:39)
    No100464 (kiku さん) に返信
    > 2022/08/17(Wed) 10:02:22 編集(投稿者)
    >
    > ■No100463 (Azulean さん) に返信
    >>■No100462 (エルデの王 さん) に返信
    > >>つまり、メインスレッドでクリック待ちをすることは、
    > >>ダイアログボックスを用いることでしか出来ないということでしょうか?
    >
    > Azuleanさんと同意見ですが、
    > 下記で実現できませんか? ==> エルデの王さん

    遅くなりました。すみません。
    残念ですが検証した結果、待機状態になりませんでした。
    案を頂きありがとうございます。
記事No.100455 のレス /過去ログ175より / 関連記事表示
削除チェック/

■100481  Re[8]: 【C#,VS2022,WPF】クリック待ちを実装したい
□投稿者/ Azulean -(2022/08/17(Wed) 18:13:10)
    2022/08/17(Wed) 18:13:22 編集(投稿者)

    No100477 (エルデの王 さん) に返信
    > 遅くなりました。すみません。
    > 残念ですが検証した結果、待機状態になりませんでした。
    > 案を頂きありがとうございます。


    ああ、見逃していた。
    DoWork 呼び出し元に Task 返していない& DoWork 呼び出し箇所で await してないので、待つことなく実行されますね。

    private async void Button_click(object sender, EventArgs e)
    {
    await DoWork()
    MessageBox.Show("aaa");
    }
    private async Task DoWork()
    {
    // 以下略


    いずれにせよ、インタープリタを作っているなら、await(Task) を根っこまで返すのが面倒くさいような気がするので、難しいかもしれませんが。
記事No.100455 のレス / END /過去ログ175より / 関連記事表示
削除チェック/

■100482  Re[9]: 【C#,VS2022,WPF】クリック待ちを実装したい
□投稿者/ エルデの王 -(2022/08/18(Thu) 04:47:31)

    >
    > ああ、見逃していた。
    > DoWork 呼び出し元に Task 返していない& DoWork 呼び出し箇所で await してないので、待つことなく実行されますね。
    >

    ありがとうございます!望み通りの動きが出来ました!
記事No.100455 のレス / END /過去ログ175より / 関連記事表示
削除チェック/



<< 0 >>

パスワード/

- Child Tree -