4

私はSOを見回していて、次の2つの記事を見つけました。

問題は、これらの記事が私の問題の球場にあるということですが、私が見ているようにそれらを使用することはできません(私の解決策を本当に複雑にしない限り)。記事では、アプリケーションを完全に閉じたときにフォームを復元する方法について説明していますが、それは私が達成しようとしていることではありません。

私がしているのは、同じ実行中のアプリケーション内で同じフォームを閉じたり開いたりすることです。これが起こったとき、私はそれが私が閉じるときと同じ正確な場所、状態、そしてサイズを持っていることを望みます。フォームオブジェクトから場所、状態、サイズを保存し、それを破棄して古い値を新しいフォームに適用できるため、これは簡単です。これは機能しますが、モニター2に最大化されたウィンドウがあり、閉じる/開く機能が実行されると、モニター1で最大化されたフォームが開きます。

上記の場合、モニター2に保持する簡単な方法はありますか、それとも複雑なライブラリに飛び込む必要がありますか?

4

4 に答える 4

1

私があなたなら、あなたの問題はそれらのリンクされた質問の単純な拡張であると考えます。唯一の変更は、アプリケーションが閉じられていないことです。ウィンドウだけが閉じられています(したがって、この情報をディスクに保持する必要はありません。ただそれをメモリに保管してください)。

その理由は、ユーザーがアプリケーションの実行中にディスプレイ構成(ディスプレイの数、ディスプレイの位置など)を変更できる(そして最終的にはそのうちの1つがおそらくそうする)ためです(たとえば、ラップトップユーザーが外部画面のプラグを抜く)。これを考慮しないでください。ユーザーがアクセスできない場所にウィンドウが画面外に配置されることになります。

于 2012-07-23T15:02:25.600 に答える
1

これを試して...

(Form2は、配置するフォームです。必要に応じて変更してください。)

using System;
using System.Drawing;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form2 : Form
    {
        static System.Drawing.Point _location = new Point();
        static System.Drawing.Size _size;
        static FormWindowState _state;

        public Form2()
        {
            InitializeComponent();

            this.Load += new EventHandler( Form2_Load );
            this.FormClosing += new FormClosingEventHandler( Form2_FormClosing );
        }

        void Form2_Load( object sender, EventArgs e )
        {
            // Restore the Form's position.
            //
            // Handle possibility that our previous screen location is no longer valid for
            // the current display environment (i.e., multiple->single display system).
            //

            Point location = _location;

            if ( location == new Point( 0, 0 ) || !IsScreenLocationValid( location ) )
            {
                if ( null != this.Parent )
                    this.StartPosition = FormStartPosition.CenterParent;
                else
                    this.StartPosition = FormStartPosition.CenterScreen;
            }
            else
            {
                this.Location = location;

                // Ensure that the Form's size is not smaller than its minimum allowed.
                //

                Size size = _size;

                size.Width = System.Math.Max( size.Width, this.MinimumSize.Width );
                size.Height = System.Math.Max( size.Height, this.MinimumSize.Height );

                this.Size = size;
            }

            // Only restore the Form's window state if it is not minimized.
            // (If we restore it as minimized, the user won't see it).
            //
            if ( _state == FormWindowState.Normal || _state == FormWindowState.Maximized )
            {
                this.WindowState = _state;
            }
        }

        /// <summary>
        /// Determines if the given screen location is valid for the current display system.
        /// </summary>
        /// <param name="location">A Point object describing the location</param>
        /// <returns>True if the location is valid; otherwise, false</returns>
        static bool IsScreenLocationValid( Point location )
        {
            Rectangle screenBounds = System.Windows.Forms.Screen.GetBounds( location );

            return screenBounds.Contains( location );
        }

        void Form2_FormClosing( object sender, FormClosingEventArgs e )
        {
            _state = this.WindowState;

            if ( _state == FormWindowState.Normal )
            {
                _location = this.Location;
                _size = this.Size;
            }
            else
            {
                _location = this.RestoreBounds.Location;
                _size = this.RestoreBounds.Size;
            }
        }
    }
}
于 2012-07-23T22:40:02.767 に答える
0

元の投稿のコメントにあるHansPassantの指示に従い、値を正しく設定すると問題が解決しました。私は今、FormsOnLoadイベントでこれを気に入っています。

if(UseGivenpositioningValues)
{
    Location = OverrideLocation;
    if (OverrideWindowState == FormWindowState.Normal)
        Size = OverrideSize;
    WindowState = OverrideWindowState;
    UseGivenpositioningValues = false;
}

最初に場所、次に状態。Justinが回答で指摘したように、これは完全な解決策ではありません。ユーザーが設定を変更でき、ユーザーが設定を変更するとフォームが画面外に表示される可能性があるためです。しかし、私の特定のケースでは、これは問題ではありません。

于 2012-07-24T06:23:31.687 に答える
0

アプリを閉じている場合でも、現在のウィンドウだけを閉じている場合でも機能する拡張メソッドを作成しました。form_loadイベントでRestoreLastLocationを呼び出し、form_closingイベントでSaveLastLocationを呼び出します。これは古いコードなので、少し粗雑な場合はお詫び申し上げます。

    public static void SaveLastLocation(this Form form, string UniqueName)
    {
        FormWindowState CurState = form.WindowState;
        if (CurState == FormWindowState.Minimized)
            CurState = FormWindowState.Normal;

        form.WindowState = FormWindowState.Normal;

        if (Properties.Settings.Default.WindowSettings == null)
            Properties.Settings.Default.WindowSettings = new System.Collections.Specialized.StringCollection();

        if(Properties.Settings.Default.WindowSettings.Count > 0)
            foreach (string S in Properties.Settings.Default.WindowSettings)
                if (S.Split('|').First().ToLower() == UniqueName.ToLower())
                {
                    Properties.Settings.Default.WindowSettings.Remove(S);
                    break;
                }

        Properties.Settings.Default.WindowSettings.Add(string.Format("{0}|{1}|{2}|{3}|{4}|{5}",
            UniqueName, form.Top.ToString(), form.Left.ToString(), form.Height.ToString(), form.Width.ToString(), form.WindowState.ToString()));

        Properties.Settings.Default.Save();
    }

    public static void RestoreLastLocation(this Form form, string UniqueName)
    {
        if (Properties.Settings.Default.WindowSettings != null && Properties.Settings.Default.WindowSettings.Count > 0)
            foreach (string S in Properties.Settings.Default.WindowSettings)
            {
                string[] Parts = S.Split('|');
                if (Parts[0].ToLower() == UniqueName.ToLower())
                {
                    form.Top = int.Parse(Parts[1]);
                    form.Left = int.Parse(Parts[2]);
                    form.Height = int.Parse(Parts[3]);
                    form.Width = int.Parse(Parts[4]);
                    form.WindowState = (FormWindowState)Enum.Parse(typeof(FormWindowState), Parts[5]);
                    break;
                }
            }
    }
于 2015-08-07T13:20:16.263 に答える