У меня есть приложение C #, которое сохраняет свое состояние при закрытии, а затем читает в сохраненном состоянии при запуске. Один элемент, который сохраняется, - это расположение основной формы. Обычно это отлично работает - в моем коде есть такая строка, которая сохраняет местоположение в файл, который затем считывается при запуске:

streamWriter.WriteLine("location:" + this.Location.X + "," + this.Location.Y);

Обычно координаты местоположения на моем компьютере с несколькими мониторами выглядят следующим образом:

location:-1069,283

Иногда я вижу координаты, которые сохраняются следующим образом:

location:-32000,-32000

А затем, когда пользователь снова запускает приложение, форма оказывается далеко за пределами рабочего стола и не может (легко) быть извлечена обычным пользователем.

Что происходит для того, чтобы координаты считывались таким образом, и есть ли предложения по предотвращению такой ситуации?

7
Dave 25 Сен 2009 в 22:02

3 ответа

Лучший ответ

Координаты, которые вы видите, связаны с тем, что приложение свернуто при закрытии. Windows «скрывает» вашу форму, фактически перемещая ее от ее координат к некоторым смехотворно большим отрицательным координатам X, Y.

Проверено программно:

Вывод из приложения формы в Vista:

Текущие координаты X: 184 Y: 184 * Местоположение по умолчанию
Текущие координаты X: - 32000 Y: - 32000 * Свернутое местоположение

Из кода:

System.Diagnostics.Debug.WriteLine("Current coordinates X: " + Location.X + "  Y: " + Location.Y );

Чтобы решить эту проблему, я бы просто проверил такое значение, когда ваше приложение закрывается, а не сохранял его в файл.

Если вы не хотите возиться с вычислениями с произвольными значениями координат, вы также можете проверить WindowState. См. здесь, в MSDN

10
Josh Darnell 24 Мар 2021 в 23:21
Лучшее решение - сохранить не свернутые координаты в памяти, а затем сохранить их при закрытии.
 – 
mpen
25 Сен 2009 в 22:25
Как мне определить не свернутые координаты?
 – 
Dave
25 Сен 2009 в 22:28
@Mark: Где бы вы ни разместили логику, вы должны проверить и решить, минимизированы ли координаты или нет.
 – 
Paul Sasik
25 Сен 2009 в 22:29
Проверьте перечисление WindowState: msdn.microsoft.com/en- us / library /…
 – 
Paul Sasik
25 Сен 2009 в 22:46

Используйте свойство RestoreBounds в своей форме.

Изменить: вот копия / вставка из некоторого моего кода (возможно, можно было бы немного очистить, но это дает понять). Это из обработчика события FormClosing моей основной формы:

// Save the last form state
Program.AppSettings.MainWindowFormState = this.WindowState;

// Check if the window is minimized or maximized
if ((this.WindowState == FormWindowState.Minimized) ||
    (this.WindowState == FormWindowState.Maximized))
{
    // Use the restored state values
    Program.AppSettings.MainWindowX = this.RestoreBounds.Left;
    Program.AppSettings.MainWindowY = this.RestoreBounds.Top;
    Program.AppSettings.MainWindowWidth = this.RestoreBounds.Width;
    Program.AppSettings.MainWindowHeight = this.RestoreBounds.Height;
}
else
{
    // Use the normal state values
    Program.AppSettings.MainWindowX = this.Left;
    Program.AppSettings.MainWindowY = this.Top;
    Program.AppSettings.MainWindowWidth = this.Width;
    Program.AppSettings.MainWindowHeight = this.Height;
}

А вот как восстановить состояние при загрузке (не забудьте установить режим начального положения вашей формы на Вручную, чтобы избежать мерцания):

// Set the initial form state
this.WindowState = Program.AppSettings.MainWindowFormState;
this.Left = Program.AppSettings.MainWindowX;
this.Top = Program.AppSettings.MainWindowY;
this.Width = Program.AppSettings.MainWindowWidth;
this.Height = Program.AppSettings.MainWindowHeight;
5
Jon Seigel 25 Сен 2009 в 22:54
Спасибо, Джон. Можете ли вы указать мне URL-адрес, в котором объясняется, как вы используете Program.AppSettings? У меня нет AppSettings под моим объектом Program.
 – 
Dave
30 Сен 2009 в 14:17
Это мой собственный класс, который управляет настройками приложения. Как я уже сказал, этот код был скопирован / вставлен прямо из одной из моих программ.
 – 
Jon Seigel
30 Сен 2009 в 16:27
Это правильный и единственный способ предотвратить мерцание или изменение местоположения формы до события Show. Вторая часть кода должна выполняться после InitializeComponent() и до события Show, и, как упомянул Джон, свойство StartPosition объекта form должен быть установлен на FormStartPosition.Manual, иначе некоторые параметры могут быть изменены после установки (перед событием Show). Пользовательский файл Xml можно использовать вместо злых настроек, чтобы избежать очень раздражающей схемы именования каталогов.
 – 
RedGlyph
9 Янв 2010 в 19:50

Отвечая на главный вопрос « что происходит »:

Я обнаружил, что это легко воспроизводится при нажатии Ctrl + D во время работы приложения (= ярлык для свертывания всех окон и просмотра рабочего стола).

Пока ваше окно сворачивается и вы сразу устанавливаете window.Visible = False, вы получите обе координаты (top,left) = -32000. Эта попытка неверна, поскольку окно уже свернуто (= скрыто), и вы дважды меняете координаты.

Вместо этого вы должны установить window.ShowInTaskbar = False, что более правильно, и проблема с координатами -32000 исчезнет.

0
JCM 13 Июн 2018 в 17:30