DOBON.NETプログラミング道掲示板
(現在 過去ログ4 を表示中)

[ 最新記事及び返信フォームをトピックトップへ ]

■34452 / inTopicNo.1)  自分自身を呼び出すのはOKですか
  
□投稿者/ げんむ 一般人(6回)-(2020/03/23(Mon) 17:03:06)
  • アイコン環境/言語:[c# vs2019 .net 4.52] 
    分類:[.NET] 

    WinFormでWebBrowserControlを利用して、以下のような動作をするアプリを作っています。
    ボタン押下時に以下のように処理が走ります。
    
    イメージ的にはアマゾンの商品リストみたいに、1ページに10商品表示されていて、ページナビゲーションで
    複数のページがあるサイトです。
    
    private void btn_Click(object sender, EventArgs e)
    {
    	//@Webページを読み込む
    	//Aリンクを取得する処理
    	//B次へのボタンを押す(ページナビゲーションで1〜Nページまであります)
    	//C次のページを表示する。無ければ処理終了
    	//D
    }
    
    この処理をページ分ループ処理をさせたいのですが、何ページあるかわかりません。
    Cの次へのページが表示できなくなったら終了になります。btn_ClickをCの次のページが
    あったら繰り返し行いたいのですが、その方法がわかりません。
    
    Dとしてbtn_click(null,null)
    という処理を入れたら、目的のことは達成できました。しかし、こんな処理の方法で良いのか不安です。
    何か別の手立てがあるようでしたらお教えいただけないでしょうか。よろしくおねがいします。

引用返信 削除キー/
■34453 / inTopicNo.2)  Re[1]: 自分自身を呼び出すのはOKですか
□投稿者/ 魔界の仮面弁士 大御所(1278回)-(2020/03/23(Mon) 20:42:53)
  • アイコンNo34452に返信(げんむさんの記事)
    > ボタン押下時に以下のように処理が走ります。

    Click イベントの実行中は、WebBrowser のコンテンツは処理されません。
    イベント処理が行われていないアイドル時に処理される仕様です。

    また、WebBrowser は Visible = true の状態で利用するようにしてください。
    http://rucio.cloudapp.net/threaddetail.aspx?threadid=10505


    > btn_click(null,null)
    > という処理を入れたら、目的のことは達成できました。しかし、こんな処理の方法で良いのか不安です。

    Form 側にとっては、イベントは本来「呼ぶもの」では無く「呼ばれるもの」ですよね。
    イベントハンドラを直接呼び出すような書き方は望ましくありません。

    そもそもイベントの引数にも意味があります。直接呼ぶとしても、
     btn_click(btn, EventArgs.Empty);
    とする方が好ましいでしょう。

    また、btn を Click したことにしたいのであれば、
     btn.PerformClick();
    と記述することで、Click イベントが誘発されます。


    あるいは再帰的な呼び出しが必要なら、イベントハンドラを直接呼び出すのではなく、
    その処理をメソッドに切り出しておき、それをイベントなどから呼ぶという手もあります。

     private void btn_Click(object sender, EventArgs e)
     {
      Foo();
     }

     private void Foo()
     {
      bool isFinished = 処理();
      if(!isFinished)
      {
       Foo(); // 再帰呼び出し
      }
     }


    > 次へのボタンを押す(ページナビゲーションで1〜Nページまであります)

    「次へのボタン」というは、Form 上の btn のことですか?
    それとも、Web ページ上のボタンですか?

    Web ページのボタンだとした場合、各ページにあるボタンは 1 つだけですか?
    それとも、1 つのページから複数のページに枝分かれして画面遷移することがありますか?

    例えば、1ページ目は「東日本」「西日本」の 2 つのボタン、
    2 ページ目は都道府県別のボタンがあって、
    3 ページ目に市区町村別のボタンがあるような場合、
    全部を網羅するためには、遷移数は 3 回では済みませんよね。



    Form 上のボタンを押す方法については、上記に書いたように PerformClick() メソッドを使えます。


    Web ページ上のボタンの場合は、HTML コンテンツの内容や Cookie の管理などによって異なるので
    一概には言えませんが、たとえば該当要素の HTMLElement に対して .InvokeMember("click"); を呼び出す方法や、
    WebBrowser に対して Navigate しなおす方法などがあります。



    > イメージ的にはアマゾンの商品リストみたいに、1ページに10商品表示されていて、ページナビゲーションで
    > 複数のページがあるサイトです。

    以下、動くかどうかはテストしていませんが:


    // ナビゲーション状況を蓄えるキュー
    private Queue<string> urlList = new Queue<string>();

    private void btn_Click(…)
    {
     // 最初の画面遷移
     urlList.Enqueue(firstUrl);
     webBrowser1.Navigate(urlList.Dequeue());
    }

    // 画面遷移のたびに呼ばれるイベント
    private void webBrowser1_DocumentCompleted(…)
    {
     // 該当ページが frameset や iframe を持つ場合、フレーム毎にDocumentCompletedが発生します。
     // 場合によっては、URL や呼び出し回数などで判断する必要があるかもしれません。
     string currentUrl = e.Url;

     // ここでは、a href=〜 なリンクを取り出すような処理を想定しています。
     foreach(var url in 解析処理(webBrowser1.Document))
     {
      urlList.Enqueue(url);
     }

     if (urlList.Count == 0)
     {
      // すべて解析完了
      MessageBox.Show("終わり");
     }
     else
     {
      // 次の画面遷移
      webBrowser1.Navigate(urlList.Dequeue());
      // BeginInvoke(new MethodInvoker(() => webBrowser1.Navigate(urlList.Dequeue()) );
     }
    }
引用返信 削除キー/



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

このトピックに書きこむ

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

Mode/  Pass/


- Child Tree -