Foren: Offene Diskussion (Thread #36144)

FormForwarder で Forward した時の フォーカスについて (2014-11-05 11:49 by kawada #74737)

お世話になっております。
標題のフォーカスにについて、お聞きいたいことがございます。

画面A
画面B
画面C

上記が存在します。
FormForwarder の Forward で画面を表示しています。

①画面A :ボタン押下
     FormForwarder の Forward で 画面Cを表示
 → フォーカスは、画面Cにあります。

②画面A:ボタン押下
     FormForwarder の Forward で 画面Bを表示
     画面B をクローズ
     画面A で 画面B からの ForwardFormClosed で 画面Cを表示
     (FormForwarder の Forward で 画面Cを表示)
 → フォーカスがなく、マウスで、画面をクリックしないと入力エリアに入力できない

①画面A → 画面C
②画面A → 画面B→(画面A)→画面C

上記で、②ですと、画面Cの入力エリア(画面C)にフォーカスがいきません。
Microsoft.VisualBasic.Interaction.AppActivate など試してみましたがうまくいきません。

申し訳ありませんが、
ご教授よろしくお願いいたします。

Reply to #74737×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Anmelden

Re: FormForwarder で Forward した時の フォーカスについて (2014-11-05 14:03 by kawada #74739)

環境を追記致します。
C#
TERASOLUNA Framework for .NET 3.0.0.0
上記での環境になります。
Reply to #74737

Reply to #74739×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Anmelden

Re: FormForwarder で Forward した時の フォーカスについて (2014-11-13 11:48 by futamuraa #74819)

いただいた情報からだけでは事象を特定しかねる部分がありますので、
いくつか追加で情報をご提供いただければと思います。

1.「画面の入力エリア(画面C)にフォーカスがいかない」とは、以下のいずれであるか
 ・アプリケーションの別ウインドウ(画面A?)がアクティブになってしまう
 ・別アプリケーションがアクティブになってしまう

2.各遷移のFormForwarder#ForwardTypeには何を設定しているか
 (ShowModeless、ShowAndHide等のいずれであるか)

3.FormForwarder以外で、画面の表示に関わる制御を実施しているか
 (FormのShow()、Hide()、Close()、Activate()、Dispose()、Visible変更等)

上記に加えて可能であれば、事象が発生するFormの最小限のソースコードを
ご提示いただけると、詳細な判断が可能かと思います。
Reply to #74739

Reply to #74819×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Anmelden

Re: FormForwarder で Forward した時の フォーカスについて (2014-11-13 14:28 by kawada #74821)

[メッセージ #74819 への返信]
> いただいた情報からだけでは事象を特定しかねる部分がありますので、
> いくつか追加で情報をご提供いただければと思います。
>
> 1.「画面の入力エリア(画面C)にフォーカスがいかない」とは、以下のいずれであるか
>  ・アプリケーションの別ウインドウ(画面A?)がアクティブになってしまう
>  ・別アプリケーションがアクティブになってしまう
>

画面A、画面B、画面C、画面Dとします。
画面Aは初期画面で、
ForwardType ShowAsChildで、画面Bを開きます。
画面Bから
ForwardType ShowWindowModalで、画面Cを開きます。
画面CをCloseして、画面Bに戻ったForwardFormClosed で
ForwardType ShowAsChildで、画面Dを開きます。

 フォーカスはありませんが、制御が画面Bにあります。
 画面B(または画面D)をクリックすると、画面Dのテキストボックスに、フォーカスが来ます

> 2.各遷移のFormForwarder#ForwardTypeには何を設定しているか
>  (ShowModeless、ShowAndHide等のいずれであるか)
>
上記に記載した通り、
はじめは、ShowAsChild でそれ以降は、すべて
ShowWindowModal

> 3.FormForwarder以外で、画面の表示に関わる制御を実施しているか
>  (FormのShow()、Hide()、Close()、Activate()、Dispose()、Visible変更等)
>
なし

> 上記に加えて可能であれば、事象が発生するFormの最小限のソースコードを
> ご提示いただけると、詳細な判断が可能かと思います。

private void 画面B_ボタンクリック(object sender, EventArgs e)
{
formForwarder1.Forward(); → 画面Cを開く
}

private void formForwarder1_ForwardFormClosed(object sender, ForwardFormClosedEventArgs e)
{
formForwarder2.Forward(); → 画面Dを開く
}

以上
Reply to #74819

Reply to #74821×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Anmelden

Re: FormForwarder で Forward した時の フォーカスについて (2014-11-18 12:04 by futamuraa #74861)

詳細な情報ありがとうございます。

事象と回避方法について説明いたします。

[原因]
画面Dがアクティブにならない原因は、
画面Dの表示後に、画面Cのクローズによって画面Bがアクティブになるためです。

これは、FormForwarderが遷移先画面をクローズするタイミングが、
見た目(Form.Close()を実施するタイミング)より遅いことに起因します。

FormForwarderは遷移元画面で遷移先画面がクローズされたことを受け取る
ForwardFormClosedイベントを実行するため、FormのFormClosedイベントハンドラを追加しており、
その中で、以下の順番で処理を行っています。
 1.ForwardFormClosedイベントの通知
 2.ShowWindowModalで開いた場合、遷移元画面のアクティブ化
 3.遷移先画面のクローズ

このため、ForwardFormClosedイベントで次画面への遷移を行った場合、
 1.画面Cのクローズ
 2.画面Dのオープン(最前面に表示しアクティブ化)
 3.画面Bのアクティブ化
 4.画面Cのクローズが完了

という順番になり、「最前面に画面Dが表示されるが画面Bがアクティブ」という状態になります。

[対策]
・画面Bで処理順序を制御する場合

 以下のように、画面Bがアクティブになった後に画面Dをオープンします。
 ※以下は一例ですので、実際の実装と見合わせてご検討ください。

private Action asyncAction; // Forwardを渡すためのアクション
private void formForwarderToC_ForwardFormClosed(object sender, ForwardFormClosedEventArgs e)
{
//formForwarderToD.Forward(); ここでのForwardを止めて
asyncAction = new Action(formForwarderToD.Forward); // Forwardを登録する
}

private void BView_Activated(object sender, EventArgs e)
{
// 画面Bがアクティブになったときにアクションが登録されていれば
if (asyncAction != null)
{
BeginInvoke(asyncAction); // アクション(Forward)を実行する。
asyncAction = null;
}
}

・FormForwarderの処理順序を変更する場合

 以下の手順で、FormForwarderの処理順序を変更することが可能です。
 ※すべてのForwardに適用されるため、他に影響がないことをご確認ください。

 1.Terasoluna.Windows.Forms.FormForward.FileOpenerクラスを拡張する。
public class FormOpenerEx : FormOpener
{
protected override void CloseTargetForm(Form form, FormClosedEventArgs e)
{
FormInfo info = InfoManager.GetFormInfo(form);
if (IsManagedShowing(info))
{
// ReportForwardFormClosed(form, e); ここから
if (info.State == FormState.ShowingWindowModal)
{
TryEnableOpenerFormForWindowModal(form);
TryActiveOpenerForm(form);
}
ReportForwardFormClosed(form, e); // ここに移動する
InfoManager.Close(form);
}
UnwireupEvents(form);
}
}
 2.Terasoluna.Windows.Forms.FormForward.FormForwardExtensionクラスを拡張する。
public class FormForwardExtensionEx : FormForwardExtension
{
protected override void Initialize()
{
base.Initialize();
Container.RegisterType<IFormOpener, FormOpenerEx>( // 1.で作成したクラスを適用
new ContainerControlledLifetimeManager());
}
}
 3.TerasolunaFramework.configを変更して拡張FormForwarderを適用する。
  以下の部分を作成したクラス(完全修飾名)およびアセンブリ名に変更します。
<!-- 画面遷移機能のデフォルト設定 -->
<add type="Terasoluna.Windows.Forms.FormForward.FormForwardExtension,
Terasoluna.Windows.Forms" />

以上となります。
Reply to #74821

Reply to #74861×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Anmelden

Re: FormForwarder で Forward した時の フォーカスについて (2014-11-18 16:13 by kawada #74865)

[メッセージ #74861 への返信]
> 詳細な情報ありがとうございます。
>
> 事象と回避方法について説明いたします。
>
> [原因]
> 画面Dがアクティブにならない原因は、
> 画面Dの表示後に、画面Cのクローズによって画面Bがアクティブになるためです。
>
> これは、FormForwarderが遷移先画面をクローズするタイミングが、
> 見た目(Form.Close()を実施するタイミング)より遅いことに起因します。
>
> FormForwarderは遷移元画面で遷移先画面がクローズされたことを受け取る
> ForwardFormClosedイベントを実行するため、FormのFormClosedイベントハンドラを追加しており、
> その中で、以下の順番で処理を行っています。
>  1.ForwardFormClosedイベントの通知
>  2.ShowWindowModalで開いた場合、遷移元画面のアクティブ化
>  3.遷移先画面のクローズ
>
> このため、ForwardFormClosedイベントで次画面への遷移を行った場合、
>  1.画面Cのクローズ
>  2.画面Dのオープン(最前面に表示しアクティブ化)
>  3.画面Bのアクティブ化
>  4.画面Cのクローズが完了
>
> という順番になり、「最前面に画面Dが表示されるが画面Bがアクティブ」という状態になります。
>
> [対策]
> ・画面Bで処理順序を制御する場合
>
>  以下のように、画面Bがアクティブになった後に画面Dをオープンします。
>  ※以下は一例ですので、実際の実装と見合わせてご検討ください。
>
> private Action asyncAction; // Forwardを渡すためのアクション
> private void formForwarderToC_ForwardFormClosed(object sender, ForwardFormClosedEventArgs e)
> {
> //formForwarderToD.Forward(); ここでのForwardを止めて
> asyncAction = new Action(formForwarderToD.Forward); // Forwardを登録する
> }
>
> private void BView_Activated(object sender, EventArgs e)
> {
> // 画面Bがアクティブになったときにアクションが登録されていれば
> if (asyncAction != null)
> {
> BeginInvoke(asyncAction); // アクション(Forward)を実行する。
> asyncAction = null;
> }
> }
>
> ・FormForwarderの処理順序を変更する場合
>
>  以下の手順で、FormForwarderの処理順序を変更することが可能です。
>  ※すべてのForwardに適用されるため、他に影響がないことをご確認ください。
>
>  1.Terasoluna.Windows.Forms.FormForward.FileOpenerクラスを拡張する。
> public class FormOpenerEx : FormOpener
> {
> protected override void CloseTargetForm(Form form, FormClosedEventArgs e)
> {
> FormInfo info = InfoManager.GetFormInfo(form);
> if (IsManagedShowing(info))
> {
> // ReportForwardFormClosed(form, e); ここから
> if (info.State == FormState.ShowingWindowModal)
> {
> TryEnableOpenerFormForWindowModal(form);
> TryActiveOpenerForm(form);
> }
> ReportForwardFormClosed(form, e); // ここに移動する
> InfoManager.Close(form);
> }
> UnwireupEvents(form);
> }
> }
>  2.Terasoluna.Windows.Forms.FormForward.FormForwardExtensionクラスを拡張する。
> public class FormForwardExtensionEx : FormForwardExtension
> {
> protected override void Initialize()
> {
> base.Initialize();
> Container.RegisterType<IFormOpener, FormOpenerEx>( // 1.で作成したクラスを適用
> new ContainerControlledLifetimeManager());
> }
> }
>  3.TerasolunaFramework.configを変更して拡張FormForwarderを適用する。
>   以下の部分を作成したクラス(完全修飾名)およびアセンブリ名に変更します。
> <!-- 画面遷移機能のデフォルト設定 -->
> <add type="Terasoluna.Windows.Forms.FormForward.FormForwardExtension,
> Terasoluna.Windows.Forms" />
>
> 以上となります。

対処法ありがとうございます。
さっそく試してみます。

今後もよろしくお願い致します。
Reply to #74861

Reply to #74865×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Anmelden