“OutLookBar”工具条不支持皮肤/换肤的问题

 中,作者详细介绍了OutLookBar的使用,但在使用中发现,此控件不支持winform换肤功能,经过测试、跟踪,终于锁定了出错的位置,现在把完整支持换肤功能的OutLookBar控件代码贴出(红色部分为关键代码)

 

 

 

 

 

using System;
using System.Drawing;
using System.Windows.Forms;

namespace Pub.Controls.OutlookBar
{
    
internal class BandTagInfo
    {
        
public OutlookBar outlookBar;
        
public int index;

        
public BandTagInfo(OutlookBar ob, int index)
        {
            outlookBar 
= ob;
            
this.index = index;
        }
    }

    
/// <summary>
    
/// OutLook 工具栏
    
/// </summary>
    public class OutlookBar : Panel
    {
        
private int buttonHeight;
        
private int selectedBand;
        
private int selectedBandHeight;

        
public int ButtonHeight
        {
            
get
            {
                
return buttonHeight;
            }

            
set
            {
                buttonHeight 
= value;
                
// do recalc layout for entire bar
            }
        }

        
public int SelectedBand
        {
            
get
            {
                
return selectedBand;
            }
            
set
            {
                SelectBand(value);
            }
        }

        
public OutlookBar()
        {
            buttonHeight 
= 25;
            selectedBand 
= 0;
            selectedBandHeight 
= 0;
        }

        
public void Initialize()
        {
            
// parent must exist!
            Parent.SizeChanged += new EventHandler(SizeChangedEvent);
        }

        
public void AddBand(string caption, ContentPanel content)
        {
            content.outlookBar 
= this;
            
int index = Controls.Count;
            BandTagInfo bti 
= new BandTagInfo(this, index);
            BandPanel bandPanel 
= new BandPanel(caption, content, bti);
            Controls.Add(bandPanel);
            UpdateBarInfo();
            RecalcLayout(bandPanel, index);
        }

        
public void SelectBand(int index)
        {
            selectedBand 
= index;
            RedrawBands();
        }

        
private void RedrawBands()
        {
            
for (int i = 0; i < Controls.Count; i++)
            {
                BandPanel bp 
= Controls[i] as BandPanel;
                RecalcLayout(bp, i);
            }
        }

        
private void UpdateBarInfo()
        {
            selectedBandHeight 
= ClientRectangle.Height - (Controls.Count * buttonHeight);
        }

        
private void RecalcLayout(BandPanel bandPanel, int index)
        {
            
int vPos = (index <= selectedBand) ? buttonHeight * index : buttonHeight * index + selectedBandHeight;
            
int height = selectedBand == index ? selectedBandHeight + buttonHeight : buttonHeight;

            
// the band dimensions
            bandPanel.Location = new Point(0, vPos);
            bandPanel.Size 
= new Size(ClientRectangle.Width, height);


            
#region 此段代码换肤支持换肤
            
//// the contained button dimensions
            //bandPanel.Controls[0].Location = new Point(0, 0);
            
//bandPanel.Controls[0].Size = new Size(ClientRectangle.Width, buttonHeight);

            
//// the contained content panel dimensions

            
//bandPanel.Controls[1].Location = new Point(0, buttonHeight);
            
//bandPanel.Controls[1].Size = new Size(ClientRectangle.Width - 2, height - 8);


            foreach (Control c in bandPanel.Controls)
            {
                
if (c.GetType() == typeof(BandButton))
                {
                    ((BandButton)c).Location = new Point(00);
                    ((BandButton)c).Size = new Size(ClientRectangle.Width, buttonHeight);
                }
                
else if (c.GetType() == typeof(IconPanel))
                {
                    ((IconPanel)c).Location = new Point(0, buttonHeight);
                    ((IconPanel)c).Size = new Size(ClientRectangle.Width - 2, height - 8);
                }
            }
            
#endregion


        }

        
private void SizeChangedEvent(object sender, EventArgs e)
        {
            Size 
= new Size(Size.Width, ((Control)sender).ClientRectangle.Size.Height);
            UpdateBarInfo();
            RedrawBands();
        }
    }

    
internal class BandPanel : Panel
    {
        
public BandPanel(string caption, ContentPanel content, BandTagInfo bti)
        {
            BandButton bandButton 
= new BandButton(caption, bti);
            Controls.Add(bandButton);
            Controls.Add(content);
        }
    }

    
internal class BandButton : Button
    {
        
private BandTagInfo bti;

        
public BandButton(string caption, BandTagInfo bti)
        {
            Text 
= caption;
            FlatStyle 
= FlatStyle.Standard;
            Visible 
= true;
            
this.bti = bti;
            Click 
+= new EventHandler(SelectBand);
        }

        
private void SelectBand(object sender, EventArgs e)
        {
            bti.outlookBar.SelectBand(bti.index);
        }
    }

    
public abstract class ContentPanel : Panel
    {
        
public OutlookBar outlookBar;

        
public ContentPanel()
        {
            
// initial state
            Visible = true;
        }
    }

    
public class IconPanel : ContentPanel
    {
        
protected int iconSpacing;
        
protected int margin;

        
public int IconSpacing
        {
            
get
            {
                
return iconSpacing;
            }
        }

        
public int Margin
        {
            
get
            {
                
return margin;
            }
        }

        
public IconPanel()
        {
            margin 
= 10;
            iconSpacing 
= 32 + 15 + 10;    // icon height + text height + margin
            BackColor = Color.LightBlue;
            AutoScroll 
= true;
        }

        
public void AddIcon(string caption, Image image, EventHandler onClickEvent)
        {

            
if (image == null)
            {
                System.Drawing.Bitmap bmp 
= new Bitmap(3232);
                bmp.GetHbitmap(Color.Red);

                image 
= (Image)bmp;
            }

            
int index = Controls.Count / 2;    // two entries per icon
            PanelIcon panelIcon = new PanelIcon(this, image, index, onClickEvent);
            Controls.Add(panelIcon);

            Label label 
= new Label();
            label.Text 
= caption;
            label.Visible 
= true;
            label.Location 
= new Point(0, margin + image.Size.Height + index * iconSpacing);
            label.Size 
= new Size(Size.Width, 15);
            label.TextAlign 
= ContentAlignment.TopCenter;
            label.Click 
+= onClickEvent;
            label.Tag 
= panelIcon;
            Controls.Add(label);
        }
    }

    
public class PanelIcon : PictureBox
    {
        
public int index;
        
public IconPanel iconPanel;

        
private Color bckgColor;
        
private bool mouseEnter;

        
public int Index
        {
            
get
            {
                
return index;
            }
        }

        
public PanelIcon(IconPanel parent, Image image, int index, EventHandler onClickEvent)
        {

            
this.index = index;
            
this.iconPanel = parent;
            Image 
= image;
            Visible 
= true;

            
if (image != null)
            {
                Location 
= new Point(iconPanel.outlookBar.Size.Width / 2 - image.Size.Width / 2,
                                iconPanel.Margin 
+ index * iconPanel.IconSpacing);
            }
            
else
            {

                Location 
= new Point(iconPanel.outlookBar.Size.Width / 2 - 0,
                               iconPanel.Margin 
+ index * iconPanel.IconSpacing);
            }
            Size 
= image.Size;
            Click 
+= onClickEvent;
            Tag 
= this;

            MouseEnter 
+= new EventHandler(OnMouseEnter);
            MouseLeave 
+= new EventHandler(OnMouseLeave);
            MouseMove 
+= new MouseEventHandler(OnMouseMove);

            bckgColor 
= iconPanel.BackColor;
            mouseEnter 
= false;
        }

        
private void OnMouseMove(object sender, MouseEventArgs args)
        {
            
if ((args.X < Size.Width - 2&&
                (args.Y 
< Size.Width - 2&&
                (
!mouseEnter))
            {
                BackColor 
= Color.LightCyan;
                BorderStyle 
= BorderStyle.FixedSingle;
                Location 
= Location - new Size(11);
                mouseEnter 
= true;
            }
        }

        
private void OnMouseEnter(object sender, EventArgs e)
        {
        }

        
private void OnMouseLeave(object sender, EventArgs e)
        {
            
if (mouseEnter)
            {
                BackColor 
= bckgColor;
                BorderStyle 
= BorderStyle.None;
                Location 
= Location + new Size(11);
                mouseEnter 
= false;
            }
        }
    }
}


posted @ 2011-01-27 08:36  二月草  阅读(1927)  评论(7编辑  收藏  举报