Отключить подсказки фокуса на SplitContainer - PullRequest
5 голосов
/ 14 марта 2012

Как я могу отключить подсказки фокуса на SplitContainer? Я спрашиваю, потому что я бы лучше нарисовал их сам, используя OnPaint, чтобы он выглядел несколько более плавным.

Я пробовал это:

    protected override bool ShowFocusCues
    {
        get
        {
            return false;
        }
    }

И это мой контроль:

    public class cSplitContainer : SplitContainer
    {
        private bool IsDragging;

        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);
            if (!IsSplitterFixed) IsDragging = true;
            Invalidate();
        }
        protected override void OnMouseUp(MouseEventArgs e)
        {
            base.OnMouseUp(e);
            if (IsDragging)
            {
                IsDragging = false;
                IsSplitterFixed = false;
            }
        }
        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);
            if (IsDragging)
            {
                IsSplitterFixed = true;
                if (e.Button == MouseButtons.Left)
                {
                    if (Orientation == Orientation.Vertical)
                    {
                        if (e.X > 0 && e.X < Width) SplitterDistance = e.X;
                    }
                    else
                    {
                        if (e.Y > 0 && e.Y < Height) SplitterDistance = e.Y;
                    }
                }
                else
                {
                    IsDragging = false;
                    IsSplitterFixed = false;
                }
            }
        }
        protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        {
            base.OnPaint(e);
            if (IsDragging)
            {
                e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(127, 0, 0, 0)), Orientation == Orientation.Horizontal ? new Rectangle(0, SplitterDistance, Width, SplitterWidth) : new Rectangle(SplitterDistance, 0, SplitterWidth, Height));
            }
        }
    }

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

Ответы [ 5 ]

8 голосов
/ 14 марта 2012

Я не думаю , что вы видите, это FocusCue, а не плавающее окно, которое используется для перемещения ползунка.

Если доступ к клавиатуре не важен, выможет попытаться сделать его невыбираемым:

public class MySplit : SplitContainer {

  public MySplit() {
    this.SetStyle(ControlStyles.Selectable, false);
  }

  protected override void OnPaint(PaintEventArgs e) {
    e.Graphics.Clear(Color.Red);
  }
}

Это не дает SplitContainer получить фокус, но ваша мышь все равно может взаимодействовать с ним.

4 голосов
/ 18 мая 2013

Я гуглял по этой проблеме, и этот вопрос поднялся на вершину.

Существует решение и интересная дискуссия на форуме Microsoft относительно фокуса кражи сплиттера без веской причины . Следующий комментарий размещен на:


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


Это может быть "по замыслу", но это не очень хорошо. Какие сплиттеры вы когда-либо видели в любом производственном приложении Microsoft, которое даже временно отвлекается от разделенных панелей? Я также добавил код, который вы предлагаете, и он не позволяет мне окончательно потерять фокус на сплиттере, но мне все еще не нравится тот факт, что мои панели скрываются и показывают свои выделения во время манипуляции с сплиттером.

Эта отвлекающая вспышка выбора просто отсутствует в большинстве профессиональных приложений. Это просто достаточно хорошо, что, вероятно, не стоит тратить время на то, чтобы починить какое-то время, но не то, чего на самом деле хотят большинство людей. Если вы уважаете свойство TabStop или даже добавляете свойство AcceptsFocus, большинство людей захотят отключить его. Я думаю, вы должны добавить эту опцию к дизайну в будущей версии.

- Брендан

4 голосов
/ 14 марта 2012

Код SplitContainer имеет вид:

protected override void OnPaint(PaintEventArgs e) {
  base.OnPaint(e);
  if (Focused) {
    DrawFocus(e.Graphics,SplitterRectangle);
  }
}

DrawFocus не является виртуальным. Так что вы не можете переопределить это.
Сфокусированный является виртуальным. Возможно, вы можете установить его в false при вызове base.OnPaint(...) в вашем OnPaint переопределении.

Чтобы вы могли добавить следующий код (я не проверял, работает ли он):

private bool _painting;
public override bool Focused
{
  get { return _painting ? false : base.Focused; }
}

protected override void OnPaint(PaintEventArgs e)
{
  _painting = true;

  try
  {
    base.OnPaint(e);
  }
  finally
  {
    _painting = false;
  }
}

Это скорее взлом, чем чистое решение.

2 голосов
/ 17 июля 2012

Простое решение: отдать фокус сразу при получении!

Три шага:

  1. Создать обработчик GotFocus для SplitContainer
  2. Переместите фокус на другой элемент управления с помощью AnotherControl.Focus().
  3. Установите TabStop на False

Вот и все.Уродливая реплика фокуса никогда не отображается.

Теперь, одна тонкость: Какой другой элемент управления, чтобы сосредоточиться?Тебе решать.Просто возьмите первый элемент управления по порядку вкладок или верхний левый фокусируемый элемент управления в правой панели SplitContainer (TextBox на диаграмме ASCII ниже).Идеальным решением был бы предыдущий элемент управления с фокусом, но, к сожалению, это не так легко выяснить: Найти элемент управления с последним фокусом , но ИМХО верхний левый фокусируемый элемент управления - очень хороший отклик.

       left pane            right pane
------------------------------------------------
:                     ::                       :
:                     ::   [TextBox] [Button]  :
:                     ::                       :
:                     ::   [Combobox V]        :
:                     ::                       :
------------------------------------------------
0 голосов
/ 14 марта 2012

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

...