netlib.narod.ru< Назад | Оглавление | Далее >

Бросаем якорь

Все приведенные ранее версии программы TwoButtons перемещали две кнопки в центр клиентской области каждый раз при изменении размеров клиентской области. Возможно, иногда вам бы хотелось, чтобы элементы управления динамически изменяли свое положение и размер в зависимости от размера клиентской области, но вам совсем не хочется самостоятельно писать обработчик события OnResize. Вам повезло: Windows Forms поддерживает два свойства элементов управления, динамически их перемещающих (и даже изменяющих их размер) — Anchor и Dock:


Свойства Control (выборочно)



Тип Свойство Доступ

AnchorStyles Anchor Чтение/запись
DockStyle Dock Чтение/запись


Эти свойства легко перепутать! В некоторых отношениях они похожи, и перечисления AnchorStyles и DockStyle практически идентичны. Но эффект от их применения разный.


Перечисление AnchorStyles



Член Значение

None 0
Top 1
Bottom 2
Left 4
Right 8


Эти значения представляют собой одиночные биты. Значения перечисления AnchorStyles можно объединять, используя оператор «поразрядное ИЛИ» языка С#.

Свойство Anchor устанавливается для элемента управления, а не для формы. При изменении размера формы оно определяет, от какой стороны или сторон формы элемент управления должен находиться на постоянном расстоянии.

По умолчанию это свойство не равно AncborStyles.None! Значение по умолчанию — 5, что является комбинацией значений:

  AnchorStyles.Left | AnchorStyles.Top

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

Перепишем программу TwoButtons, задействовав преимущества свойства Anchor.

TwoButtonsAnchor.cs

  //-------------------------------------------------
  // TwoButtonsAnchor.cs (C) 2001 by Charles Petzold
  //-------------------------------------------------
  using System;
  using System.Drawing;
  using System.Windows.Forms;

  class TwoButtonsAnchor: Form
  {
      public static void Main()
      {
          Application.Run(new TwoButtonsAnchor());
      }
      public TwoButtonsAnchor()
      {
          Text = "Two Buttons with Anchor";
          ResizeRedraw = true;

          int cxBtn = 5 * Font.Height;
          int cyBtn = 2 * Font.Height;
          int dxBtn =     Font.Height;

          Button btn = new Button();
          btn.Parent   = this;
          btn.Text     = "&Larger";
          btn.Location = new Point(dxBtn, dxBtn);
          btn.Size     = new Size(cxBtn, cyBtn);
          btn.Click   += new EventHandler(ButtonLargerOnClick);

          btn = new Button();
          btn.Parent   = this;
          btn.Text     = "&Smaller";
          btn.Location = new Point(ClientSize.Width  - cxBtn - dxBtn,
                                   ClientSize.Height - cyBtn - dxBtn);
          btn.Size     = new Size(cxBtn, cyBtn);
          btn.Anchor   = AnchorStyles.Right | AnchorStyles.Bottom;
          btn.Click   += new EventHandler(ButtonSmallerOnClick);
      }
      void ButtonLargerOnClick(object obj, EventArgs ea)
      {
          Left   -= (int)(0.05 * Width);
          Top    -= (int)(0.05 * Height);
          Width  += (int)(0.10 * Width);
          Height += (int)(0.10 * Height);
      }
      void ButtonSmallerOnClick(object obj, EventArgs ea)
      {
          Left   += (int)(Width  / 22f);
          Top    += (int)(Height / 22f);
          Width  -= (int)(Width  / 11f);
          Height -= (int)(Height / 11f);
      }
  }

Важнейшее изменение — отсутствие метода OnResize. Но если вам нужен свой метод OnResize в программе, использующей свойство Anchor, не забудьте поместить в него вызов:

  base.OnResize(ea);

иначе «заякоривание» элементов не сработает. Отказавшись от метода OnResize, я смог сделать переменные cxBtn, cyBtn и dxBtn локальными в конструкторе. Кроме того, так как я использую два разных обработчика события Click, нет нужды хранить два объекта «кнопка» в полях. Для создания обеих кнопок служит одна и та же переменная btn.

Кнопка Larger размещается в левом верхнем углу формы, a Smaller — в правом нижнем углу:


Рис. 12.9.

Кнопки не прижимаются к краям. Я использую переменную dxBtn (равную высоте шрифта) для задания расстояния между кнопками и границами клиентской области. Кнопка Larger сохраняет свойство Anchor по умолчанию, а для кнопки Smaller ему присваивается:

  btn.Anchor = AnchorStyles.Right | AnchorStyles.Bottom;

Это означает, что Smaller будет оставаться на расстоянии dxBtn от правой и нижней границы клиентской области независимо от изменений ее размера. Если сделать клиентскую область очень маленькой, кнопки будут перекрываться.

Поэкспериментируем со стилями «якоря». Вот что мы обнаружим.

Если свойство Anchor содержит значения AnchorStyles, соответствующие противоположным сторонам, элемент управления изменяет свой размер при изменении размера формы. Так, если Anchor равно AnchorStyle.Top | AnchorStyle.Bottom, то ширина элемента управления не меняется, но его высота изменяется по мере изменения высоты формы. Так происходит оттого, что от края элемента управления до краев клиентской области сохраняется одинаковое расстояние. Если сделать форму слишком маленькой, элемент управления станет невидим.

Если установить Anchor так, чтобы оно соответствовало всем четырем сторонам, ширина и высота элемента управления будут изменяться по мере изменения размера формы.

Если Anchor равно одному из значений AnchorStyle, скажем, AnchorStyle.Right, расстояние между элементом управления и правой стороной клиентской области остается неизменным. Однако по мере изменения высоты формы, элемент управления сохраняет свое положение по вертикали приблизительно пропорционально изменению формы.

Если присвоить свойству Anchor значение AnchorStyle.None, элемент управления будет сохранять свое положение приблизительно пропорционально изменению формы. Так, если поместить элемент управления в центр клиентской области и установить его свойство Anchor в AnchorStyle.None, то по мере изменения размеров клиентской области размер элемента управления меняться не будет, при этом он будет оставаться примерно посредине клиентской области.


netlib.narod.ru< Назад | Оглавление | Далее >

Сайт управляется системой uCoz