2015-04-30 2 views
1

У меня есть один Panel, и когда я нажимаю на добавление Button, я добавляю один Control под другие элементы управления. Когда я нажимаю на другой Button, я удаляю Control, который был добавлен как последний.
Это прекрасно работает. На этой панели у меня установлен AutoScroll набор настроек True, и когда я добавляю больше элементов управления, он отображается правильно, и я могу его использовать. Когда я удаляю некоторые элементы управления Panel правильно скрывает ScrollBarТОЛЬКО, если «анимация» на этом ScrollBar не запускается в это время.Режим AutoScroll не скрывает полосу прокрутки должным образом

  1. Если анимация не работает на этом ScrollBar, то она исчезает правильно - не имеет значения, есть ли у вас над ней надстройка или нет.
  2. Если у вас есть мышь над ScrollBar и быстро перемещаться по Вытащите Button и нажмите перед тем ScrollBar сек анимации закончила Control удаляется, но неактивный ScrollBar еще есть. В Button s обработчик щелчка Я попытался позвонить Invalidate, Update и Refresh методов по Panel, но ничего не работает.

Я проверил это только на Windows 7.

Если вы не знаете, что я имею в виду, пожалуйста, попробуйте посмотреть на это короткое видео (20s без звука): http://youtu.be/-0EfRXrGbuc

ответ

1

Вы забыли опубликовать mcve. Так вот один (добавить панель и две кнопки):

private void button1_Click(object sender, EventArgs e) 
    { 
     panel1.Controls.Add(new Button() { Top = panel1.Controls.Count * 30 }); 
    } 

    private void button2_Click(object sender, EventArgs e) 
    { 
     if (panel1.Controls.Count > 0) 
      panel1.Controls.RemoveAt(panel1.Controls.Count - 1); 
     panel1.Refresh(); 
    } 

Я могу воспроизвести проблему

это WinForms, ребенок (с).

Возможное обходное решение - позвонить по телефону Refresh(), используя, например, Timer или некоторые события мыши (это не предотвратит проблему, но использование будет легко исправить, например, перемещая мышь внутри panel1), или вы можете отложить возможность удаления самих кнопок в течение короткого времени после panel1.MouseLeave. Все это обходные пути.

0

Я надеялся, что есть какой-то лучший путь, но теперь я не вижу, так что на основе answer from Sinatr я решил использовать Timer и cobined его с проверкой пикселя Color, чтобы определить, является ли ScrollBar еще видна.

private Timer _timer = new Timer {Interval = 500}; 

public Form1() 
{ 
    InitializeComponent(); 
    _timer.Tick += TimerOnTick; 
} 

private void button2_Click(object sender, EventArgs e) 
{ 
    if (panel1.Controls.Count > 0) 
    { 
     var wasVisible = panel1.VerticalScroll.Visible; 
     panel1.Controls.RemoveAt(panel1.Controls.Count - 1); 
     buttons.RemoveAt(buttons.Count - 1); 

     if (wasVisible != panel1.VerticalScroll.Visible) 
     { 
      _timer.Start(); 
     } 
    } 
} 

private bool IsBackgroundColor() 
{ 
    var point = panel1.Location; 
    point.Offset(panel1.Width - 9, panel1.Height - 11); 
    point = PointToScreen(point); 

    Image imgScreen = new Bitmap(1, 1); 
    using (Bitmap bmp = new Bitmap(1, 1, PixelFormat.Format32bppArgb)) 
    using (Graphics g = Graphics.FromImage(bmp)) 
    using (Graphics gr = Graphics.FromImage(imgScreen)) 
    { 
     g.CopyFromScreen(point, new Point(0, 0), new Size(1, 1)); 
     gr.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; 
     gr.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; 
     gr.DrawImage(bmp, new Rectangle(0, 0, 1, 1)); 

     var color = bmp.GetPixel(0, 0); 
     return color.R == panel1.BackColor.R && color.G == panel1.BackColor.G && color.B == panel1.BackColor.B; 
    } 
} 

private void TimerOnTick(object sender, EventArgs eventArgs) 
{ 
    if (!IsBackgroundColor() && !panel1.VerticalScroll.Visible) 
    { 
     panel1.Refresh(); 
    } 
    else 
    { 
     _timer.Stop(); 
    } 
} 

Я не был в состоянии использовать Panel.DrawToBitmap, потому что он не рисует ScrollBars. Я также начинаю Timer только тогда, когда видна ScrollBar, и теперь этого не должно быть.
Важно отметить, что проверка пикселя Color возможна только в том случае, если вы знаете Color, который должен быть там, если скрыт ScrollBar. Не обязательно быть Panel.BackColor.

+0

'IsBackgroundColor' кажется излишним для меня.Возможно, вы можете определить, видима ли полоса прокрутки [каким-то образом] (http://stackoverflow.com/q/1591710/1997232) по-другому? – Sinatr

+0

Несчастливо нет, потому что 'Panel.VerticalScroll.Visible' установлен правильно, и я использую это поведение, чтобы проверить, должен ли' ScrollBar' быть или не должен быть видимым. – Artholl