C#仿QQ設置界面導航


效果預覽,選擇左邊標簽,右邊內容會自動滾動到適當位置

 

 

public class AnchorPanel
    {
        List<PanelMenu> lst = new List<PanelMenu>();

        Control MenuPan { get; set; }

        XtraScrollableControl XSControl;

        public AnchorPanel(Panel PanMenu, XtraScrollableControl xtraScrollableControl)
        {
            MenuPan = PanMenu;
            XSControl = xtraScrollableControl;
            XSControl.Scroll += XSControl_Scroll;
            XSControl.MouseWheel += XSControl_MouseWheel;
            XSControl.SizeChanged += XSControl_SizeChanged;
            XSControl.VerticalScroll.LargeChange = 20;
        }

        void XSControl_SizeChanged(object sender, EventArgs e)
        {
            if (LastAnchor != null && LastAnchorIniHeight < (sender as Control).Height)
            {
                LastAnchor.AnchorContainer.Height = (sender as Control).Height;
            }
        }


        #region 容器滾動條移動事件
        void XSControl_MouseWheel(object sender, MouseEventArgs e)
        {

            XSControl_Scroll(sender, null);

        }

        void XSControl_Scroll(object sender, XtraScrollEventArgs e)
        {
            CurrentLable = GetMenu((sender as XtraScrollableControl).VerticalScroll.Value);
        }
        #endregion

        #region 添加錨點

        PanelMenu LastAnchor;
        int LastAnchorIniHeight;

        /// <summary>
        /// 添加錨點
        /// </summary>
        /// <param name="col">默認為控件的Top,Height,Text屬性</param>
        /// <param name="LastControl">是否是最后一一個錨點,為了保證最后一個錨點定位在頂部,需要動態設置最后一個錨點的高度,如果最后一個錨點區域高度小於容器高度,則設置其高度為容器高度</param>
        public void AddAnchor(Control col, bool LastControl)
        {
            AddAnchor(col, col.Text, LastControl);
        }
        /// <summary>
        /// 添加錨點
        /// </summary>
        /// <param name="col">默認為控件的Top,Height屬性</param>
        /// <param name="Caption">如果Caption為空則取Col的Text屬性</param>
        /// <param name="LastControl">是否是最后一一個錨點,為了保證最后一個錨點定位在頂部,需要動態設置最后一個錨點的高度,如果最后一個錨點區域高度小於容器高度,則設置其高度為容器高度</param>
        public void AddAnchor(Control col, string Caption, bool LastControl)
        {

            Label lbl = new Label()
            {
                AutoSize = false,
                Dock = System.Windows.Forms.DockStyle.Top,
                Location = new System.Drawing.Point(0, 0),
                /*lbl.Size = new System.Drawing.Size(219, 37);*/
                Height = 37,
                TabIndex = 0,
                Text = Caption,
                TextAlign = System.Drawing.ContentAlignment.MiddleRight,
                Tag = col.Top.ToString()
            };

            IniEventLable(lbl);
            if (LastControl)
            {
                LastAnchor = new PanelMenu(lbl, col);
                LastAnchorIniHeight = col.Height;
                lst.Add(LastAnchor);
            }
            else
                lst.Add(new PanelMenu(lbl, col));

            MenuPan.Controls.Add(lbl);
            MenuPan.Controls.SetChildIndex(lbl, 0);

        }


        #endregion

        /// <summary>
        /// 根據滾動條位置獲得對應的錨點空間
        /// </summary>
        /// <param name="ScrollValue">滾動條的值</param>
        /// <returns></returns>
        public Label GetMenu(int ScrollValue)
        {
            Label lbl = null;
            foreach (PanelMenu menu in lst)
            {
                if (menu.Top <= ScrollValue && menu.Buttom > ScrollValue)
                    lbl = menu.Label;
            }
            if (lbl == null)
            {
                return null;
            }
            return lbl;
        }

        /// <summary>
        /// 初始化錨點的事件
        /// </summary>
        /// <param name="lbl"></param>
        void IniEventLable(Label lbl)
        {
            lbl.MouseEnter += lbl_MouseEnter;
            lbl.MouseLeave += lbl_MouseLeave;

            lbl.MouseClick += lbl_MouseClick;
        }

        #region 錨點單擊
        Label _CurrentLable;
        public Label CurrentLable
        {
            set
            {
                if (value == null) return;
                if (_CurrentLable == value) return;
                value.BackColor = Color.LightPink;
                if (_CurrentLable != null)
                    _CurrentLable.BackColor = Color.Transparent;
                _CurrentLable = value;
            }
            get { return _CurrentLable; } //{ return CurrentLable; }
        }

        /// <summary>
        /// 鼠標點擊
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void lbl_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {

                CurrentLable = sender as Label;

                XSControl.VerticalScroll.Value = int.Parse((sender as Label).Tag.ToString()) - CurrentLable.Top;
            }
        }

        /// <summary>
        /// 設置鼠標進入時背景色
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void lbl_MouseEnter(object sender, EventArgs e)
        {
            if ((sender as Label) != CurrentLable)
                (sender as Label).BackColor = Color.FromArgb(0xFF, 0xFF, 0x99);
        }

        /// <summary>
        /// 鼠標移出,還原背景色
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void lbl_MouseLeave(object sender, EventArgs e)
        {
            if ((sender as Label) != CurrentLable)
                (sender as Label).BackColor = Color.Transparent;
        }
        #endregion
    }

    public class PanelMenu
    {
        public PanelMenu(Label label, Control anchorContainer)
        {
            Label = label;
            AnchorContainer = anchorContainer;
            Top = anchorContainer.Top;
        }

        public PanelMenu(Label label, int top, int height)
        {
            Label = label;
            Top = top;
            Height = height;
        }

        /// <summary>
        /// 錨點定位的容器對象,通常是Panel
        /// </summary>
        public Control AnchorContainer { get; set; }
        /// <summary>
        /// 錨點,Lable
        /// </summary>
        public Label Label { get; set; }


        public int Top
        {
            get;
            set;
        }
        private int _height;
        public int Height
        {
            get
            {
                if (AnchorContainer != null)
                    return AnchorContainer.Height;
                else
                    return _height;
            }
            set { _height = value; }
        }

        public int Buttom { get { return Top + Height; } }
    }

PS:界面新建一個panel1,用於存放左邊的導航列表,右邊拖一個dev控件:xtraScrollableControl1
在Load里面新增如下代碼
使用:

AnchorPanel APanel;
       private void Form3_Load(object sender, EventArgs e)
       {
           APanel = new AnchorPanel(panel1, xtraScrollableControl1);

           labelControl1.Text = groupControl6.Height.ToString();
           if (groupControl6.Height < xtraScrollableControl1.Height)
               groupControl6.Height = xtraScrollableControl1.Height;
           panel1.Controls.Clear();

           APanel.AddAnchor(groupControl1, false);
           APanel.AddAnchor(groupControl2, false);
           APanel.AddAnchor(groupControl3, false);
           APanel.AddAnchor(groupControl4, false);
           APanel.AddAnchor(groupControl5, false);
           APanel.AddAnchor(groupControl6, true);
            
            
            
            
           

           APanel.CurrentLable = APanel.GetMenu(0);
            
            
            
            
            
       }

Demo下載地址:https://github.com/GarsonZhang/JumpPanel


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM