2015-07-27 7 views
1

У меня есть проблема с ToolStripStatusLabel, которая возникает, когда BorderSides установлен в All и я установить цвет фона другого к владеющему Цвет StatusStrip ФОН: ToolStripStatusLabels BackgroundColor кровоточит за пределами границы - который выглядит довольно уродливые. Я попытался установить свойство BorderStyle в другие настройки, кроме Flat без успеха.Howto исправить BackgroundColor кровотечение в граничила ToolStripStatusLabel

На скриншоте, приведенном ниже, вы видите проблему - пример в teal равен BorderStyle = Adjust, чтобы получить границу, нарисованную за пределами прямоугольника. Но, к сожалению, граница полностью исчезает.

Different BorderStyles won't help

То, что я хотел бы получить не кровотечение вообще, как в этой рисованной примере.

enter image description here

Возможно ли это сделать с помощью установки или наследованием или переопределение конкретный метод ToolStripStatusLabel? Я открыт для программных решений, но я не знаю, с чего начать, поэтому любые намеки приветствуются.


Реализовано решение путем объединения x4rf41 и TaW сек ответов ниже

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

Я пропустил класс ToolStripStatusLabel и переопределил метод OnPaint. Это дало мне возможность использовать свойства классов и нарисовать его так, как оно будет нарисовать себя нормально, но без кровотечения.

public partial class ToolStripStatusLabelWithoutColorBleeding : ToolStripStatusLabel 
{ 
    /// <summary> 
    /// Bugfix to prevent bleeding of background colors outside the borders. 
    /// </summary> 
    /// <param name="e"></param> 
    protected override void OnPaint(PaintEventArgs e) 
    { 
     Rectangle borderRectangle = new Rectangle(0, 0, Width - 1, Height - 1); 

     // Background 
     e.Graphics.FillRectangle(new SolidBrush(BackColor), borderRectangle); 

     // Border (if required) 
     if (BorderSides != ToolStripStatusLabelBorderSides.None) 
      ControlPaint.DrawBorder3D(e.Graphics, borderRectangle, BorderStyle, (Border3DSide)BorderSides); 

     // Draw Text if you need it 
     e.Graphics.DrawString(Text, Font, new SolidBrush(ForeColor), 0,0); 

    } 
} 

ответ

1

Я не думаю, что вашу проблему можно решить, установив свойства этикеток. Вы должны сделать какой-то пользовательский чертеж.

Я не знаю точно, что вы пытаетесь сделать с этикетками, но самый простым способом для пользовательского рисования является использование события рисования метки:

private void toolStripStatusLabel1_Paint(object sender, PaintEventArgs e) 
{ 
    // Use the sender, so that you can use the same event handler for every label 
    ToolStripStatusLabel label = (ToolStripStatusLabel)sender; 
    // Background 
    e.Graphics.FillRectangle(new SolidBrush(label.BackColor), e.ClipRectangle); 
    // Border 
    e.Graphics.DrawRectangle(
     new Pen(label.ForeColor), // use any Color here for the border 
     new Rectangle(e.ClipRectangle.Location,new Size(e.ClipRectangle.Width-1,e.ClipRectangle.Height-1)) 
    ); 
    // Draw Text if you need it 
    e.Graphics.DrawString(label.Text, label.Font, new SolidBrush(label.ForeColor), e.ClipRectangle.Location); 
} 

это даст вам ваши рамы если вы установили BackColor метки на пурпурный, а ForeColor на правый серый.

Вы также можете расширить класс ToolStripStatusLabel и переопределить метод onPaint. Код будет примерно таким же, но у вас есть дополнительные опции в пользовательском классе, например, добавление свойства BorderColor или что-то в этом роде.

+0

Я решил расширить класс и переопределить метод OnPaint, как предлагается, используя ControlPaint.DrawBorder3D, потому что он сохраняет тот же цвет, что и при отсутствии переопределения. Я добавил это к OP и принял ваш ответ, потому что это привело меня к правильному пути. – Marwie

+0

Просто хотел сообщить вам, что я исправил часть вашего решения, больше не полагаясь на e.ClipRectangle - поскольку размер ClipRectangle не всегда является размером клиентской области (например, если вы перемещаете окно за пределы экрана). Теперь я использую фактическую ширину и высоту элемента управления, и он работает отлично. Не могли бы вы также изменить свой ответ, чтобы исправить это? – Marwie

1

Я немного поиграл с помощью ControlPaint.DrawBorder3D и обнаружил, что у него тоже есть BackColor, показывающий нижнюю и правую линию.

Итак, как и в ответе xfr41, я попытался сделать чертеж владельца. Моя идея состояла в том, чтобы использовать подпрограммы системы, но для увеличения прямоугольника чертежа по области отсечения; таким образом, неправильные полосы вообще теряются ..

private void toolStripStatusLabel1_Paint(object sender, PaintEventArgs e) 
{ 
    Rectangle r = e.ClipRectangle; 
    Rectangle r2 = new Rectangle(r.X, r.Y, r.Width + 1, r.Height + 1); 
    ControlPaint.DrawBorder3D(e.Graphics, r2 , Border3DStyle.SunkenInner); 
} 
+1

Мне нравится ControlPaint, потому что он использует системные цвета по умолчанию, но это также означает, что вы не можете его изменить. что я хочу знать, почему вы вызываете base.OnPaint в обработчике событий, разве это не метод Form.OnPaint? – x4rf41

+0

Упс, он поскользнулся, исправил. - Да, он будет использовать цвета системы и, таким образом, останется в цветовой синхронизации с остальной частью цветовой схемы системы. Не так хорошо, если вы хотите полной свободы. Он также имеет полный диапазон 3DBorderstyles в каждой версии ОС. С надеждой. (Но если уловка всегда будет работать, это еще один вопрос ..) – TaW