Рейтинг:
2
OriginalGriff
В приведенном обработчике событий, установить width и height :
Rectangle screen = Screen.FromControl(this).Bounds;
Width = screen.Width;
Height = 200;
[редактировать]
Привет, Люк!
Как правило, я использую событие Load, а не конструктор - оно будет работать в показанном виде, но латы менее эффективны, как вы сказали.
На самом деле это очень просто: Windows рассматривает несколько мониторов как один большой рабочий стол.
Итак, это мой код запуска проекта по умолчанию:
/// <summary>
/// Restore size and location (if the user doesn't
/// override it)
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void FrmMain_Load(object sender, EventArgs e)
{
if ((ModifierKeys & Keys.Shift) == 0)
{
this.LoadLocation();
}
}
/// <summary>
/// Save the size and location (if the used doesn't
/// override it)
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
{
if ((ModifierKeys & Keys.Shift) == 0)
{
this.SaveLocation();
}
}
...
/// <summary>
/// Save the control location
/// (Because a Form is derived from Control, it works
/// for them as well)
/// </summary>
/// <param name="control">Form to save location of</param>
/// <param name="instance">Instance identifier (for use with multiple instances)</param>
public static void SaveLocation(this Control control, string instance = null)
{
string controlName = control.GetType().Name;
if (!File.Exists(LocationsStorageFile))
{
CreateBlankLocationFile();
}
if (!(control is Form f) || (f.Visible && f.WindowState == FormWindowState.Normal))
{
// For Forms, we don't want to save if hidden, or if maximized / minimized
// If we did, it causes the form to be misplaced, or far too small to see.
DataTable dt = ReadXML(LocationsStorageFile);
if (dt.Columns.Count >= 6)
{
bool ignoreInstance = string.IsNullOrWhiteSpace(instance);
DataRow current = dt.NewRow(); // Assume new row or instance.
current["ControlName"] = controlName;
current["Instance"] = instance ?? "";
foreach (DataRow row in dt.Rows)
{
if (row["ControlName"] as string == controlName && (ignoreInstance || row["Instance"] as string == instance))
{
// Found it!
//current = row;
dt.Rows.Remove(row);
break;
}
}
current["LocationX"] = control.Location.X;
current["LocationY"] = control.Location.Y;
current["SizeW"] = control.Size.Width;
current["SizeH"] = control.Size.Height;
dt.Rows.Add(current);
WriteXML(dt, LocationsStorageFile);
}
}
}
/// <summary>
/// Load the Control location
/// (Because a Form is derived from Control, it works
/// for them as well)
/// </summary>
/// <param name="control">Form to load location of</param>
/// <param name="instance">Instance identifier (for use with multiple instances)</param>
public static void LoadLocation(this Control control, string instance = null)
{
string controlName = control.GetType().Name;
if (!File.Exists(LocationsStorageFile))
{
CreateBlankLocationFile();
}
DataTable dt = ReadXML(LocationsStorageFile);
if (dt.Columns.Count >= 6)
{
bool ignoreInstance = string.IsNullOrWhiteSpace(instance);
DataRow current = dt.NewRow(); // Assume new row or instance.
current["ControlName"] = controlName;
current["Instance"] = instance ?? "";
current["LocationX"] = control.Location.X;
current["LocationY"] = control.Location.Y;
current["SizeW"] = control.Size.Width;
current["SizeH"] = control.Size.Height;
foreach (DataRow row in dt.Rows)
{
if (row["ControlName"] as string == controlName && (ignoreInstance || row["Instance"] as string == instance))
{
// Found it!
current = row;
if (int.TryParse(current["LocationX"].ToString(), out int x) &&
int.TryParse(current["LocationY"].ToString(), out int y) &&
int.TryParse(current["SizeW"].ToString(), out int w) &&
int.TryParse(current["SizeH"].ToString(), out int h))
{
control.Location = new Point(x, y);
control.Size = new Size(w, h);
}
break;
}
}
}
}
[/редактировать]
Luc Pattyn
Привет ОГ, я немного удивлен, что вы делаете это в показанном обработчике событий, так как это приведет ко второму макету (пересчет доков, якорей и т. д.) И видимому изменению размера.
Я склонен делать такие вещи в конструкторе форм сразу после вызова InitializeComponents; и, как правило, на основе Системная информация.WorkingArea
Это сослужило мне хорошую службу, кстати, мои системы являются одноэкранными, может быть, вы обрабатываете их по-разному, чтобы поддерживать несколько экранов?
:)
OriginalGriff
Привет, Люк! Давно не разговаривали ... В эти дни я запускаю три экрана: 22-дюймовый портрет, 22-дюймовый пейзаж и 19-дюймовый квадрат. Последний из них старый, но электронная почта и несколько других битов заполняют его красиво - и он соответствует цвету моего принтера, так что это мой "обзорный" экран для Paint Shop Pro. Получить этот матч было очень весело, так что я не хочу повторять его на новом мониторе в спешке! :смеяться:
Luc Pattyn
Да, я избегаю этого раздела QA настолько, насколько могу, то есть я читаю здесь вещи, но я избегаю входить в себя; то есть до тех пор, пока не появится что-то действительно интересное или озадачивающее меня. И тогда я пытаюсь получить некоторое представление о том, что обсуждается, что часто бывает трудно...
Несколько экранов вызывают ряд вопросов (в последний раз я делал это, может быть, 20 лет назад):
1. Как заставить ваше приложение автоматически запускаться на экране по вашему выбору? (если вам придется перемещать его вручную, показанный код обработчика не очень поможет, не так ли?)
2. Если в коде, который вы показали, форма ("Это") изначально не заподлицо слева, не будет ли установка ее ширины на screen.width заставлять ее выходить за пределы своего экрана, перетекая на следующий экран, если таковой имеется? если только вы тоже этого не сделаете Слева=экран.Слева; конечно...
3. и если вы каким-то образом приняли меры предосторожности, чтобы получить его заподлицо слева с самого начала, не могли бы вы применить тот же трюк, чтобы также получить правильную ширину сразу же, а не фиксировать ее сразу же?
:)
OriginalGriff
Смотрите измененное решение - я ненавижу код в полях комментариев! :смеяться:
Luc Pattyn
Спасибо, вы так улучшили свое решение, что мне пришлось его исправить
Д)
Рейтинг:
12
BillWoodruff
Альтернатива: Screen.PrimaryScreen.WorkingArea
дает вам границы экрана, исключая панели задач, закрепленные окна, закрепленные панели инструментов. Используйте его, чтобы не вмешиваться в конфигурацию экрана пользователя.
public void SetScreenRect(Form frm, bool fullwide, bool fullheight, int x = 0, int y = 0, int width = 0, int height = 0)
{
Rectangle scrn = Screen.PrimaryScreen.WorkingArea;
width = fullwide ? scrn.Width : width;
width -= x;
height = fullheight ? scrn.Height : height;
height -= y;
frm.Bounds = new Rectangle(x, y, width, height);
}
Пример использования:
SetScreenRect(this, true, true, y: 100);
Это будет использовать весь экран, но смещение верхней части формы на #100 и уменьшение высоты на ту же величину.
Этот код является примером; я бы реализовал проверку ошибок аргументов на практике.