[
  {
    "path": ".gitignore",
    "content": "bin\nobj\n.vs\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2008 曹旭升（sheng.c）\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# Sheng.Winform.Controls\n\n🙋‍♂️ https://me.shendesk.com\n📨 cao.silhouette@gmail.com\n\nPlease visit the original code repository for the latest updates: https://github.com/iccb1013/Sheng.Winform.Controls .\n\nSheng.Winform.Controls provides more than 15 WinForm controls. You can use this control library directly, and more importantly, you can learn the methods and concepts of WinForm control development through it.\n\nYou will learn:\n\nHow to implement a fully functional WinForm control from scratch based on the Control class.\nHow to use the GDI+ drawing interface and interact with user actions.\nHow different design patterns are applied in WinForm control development.\nMany people think that design patterns are only used to solve problems in large-scale solutions. However, here you will see that design patterns are not just for breaking down large projects— even for developing a single WinForm control, a well-structured design pattern can help you decompose and solve problems efficiently.\n\nFor example, the Prototype Pattern—although I could explain this pattern in detail, I struggled to find a practical application for it until I discovered that Microsoft used it in implementing DataGridView to solve several key issues. That was an eye-opener.\n\nOther design patterns, such as Factory Pattern, Builder Pattern, and Command Pattern, also have highly relevant use cases in complex WinForm control development.\n\nThe source code includes detailed comments, which I believe will help you in reading and utilizing it effectively.\n\nIf you use this control library in a commercial product, please provide proper attribution in the copyright notice and include this GitHub address. Thank you!\n\n> I'm sorry that I didn't prepare a multilingual version at the time. If you have any questions about the code, please feel free to contact me, and I will be happy to assist you.\n\n![3feff3f7-2a37-4e56-af32-713f21681119](https://github.com/user-attachments/assets/37acdfd0-614e-4d13-a39f-be91d7d91430)\n\n![04b5c6e9-a387-40ae-9a17-b8c2c3b42ead](https://github.com/user-attachments/assets/805d7754-285e-4616-9c63-b01b1d14564d)\n\n![11d0b296-fa12-4817-9855-5200625533ee](https://github.com/user-attachments/assets/1ca87d85-408b-4842-a1f2-3f065be9ffb9)\n\n![32db64c2-2dfa-4ad1-a86c-0f4183f6010c](https://github.com/user-attachments/assets/410537fb-e5e2-4f0a-bac3-c34893ee40f3)\n\n![b076e42d-bff1-49ca-acb4-eb2da79a2dc2](https://github.com/user-attachments/assets/71664a7f-c3a0-41a6-8138-2ee8f875bd91)\n\n![bf463f4b-60ef-4ec5-9db7-75a815ba667d](https://github.com/user-attachments/assets/70bc5c56-a21a-420d-8466-616fdc5e0c7e)\n"
  },
  {
    "path": "Sheng.Winform.Controls/BrowserDisplayBinding/BrowserPane.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\n\nnamespace Sheng.Winform.Controls\n{\n    public class BrowserPane : IDisposable\n    {\n        #region 公开属性\n\n        private HtmlViewPane _htmlViewPane;\n        public HtmlViewPane View\n        {\n            get\n            {\n                return _htmlViewPane;\n            }\n        }\n\n        public Uri Url\n        {\n            get\n            {\n                return _htmlViewPane.Url;\n            }\n        }\n\n         /// <summary>\n        /// URL框中显示的地址\n        /// 这个地址是可能不同于WebBrowse中的实际URL的\n        /// </summary>\n        public string DummyUrl\n        {\n            get { return _htmlViewPane.DummyUrl; }\n        }\n\n        #endregion\n\n        #region 构造\n\n        protected BrowserPane(bool showNavigation)\n        {\n            _htmlViewPane = new HtmlViewPane(showNavigation);\n            _htmlViewPane.Dock = DockStyle.Fill;\n            //htmlViewPane.WebBrowser.DocumentTitleChanged += new EventHandler(TitleChange);\n            ////    htmlViewPane.Closed += PaneClosed;\n            //TitleChange(null, null);\n        }\n\n        public BrowserPane()\n            : this(true)\n        {\n        }\n\n        #endregion\n\n        #region 公开方法\n\n        public void Dispose()\n        {\n            _htmlViewPane.Dispose();\n        }\n\n        public void Navigate(string url)\n        {\n            _htmlViewPane.Navigate(url);\n        }\n\n        #endregion\n\n        //void PaneClosed(object sender, EventArgs e)\n        //{\n        //    WorkbenchWindow.CloseWindow(true);\n        //}\n\n        //void TitleChange(object sender, EventArgs e)\n        //{\n        //    string title = htmlViewPane.WebBrowser.DocumentTitle;\n        //    if (title != null)\n        //        title = title.Trim();\n        //    if (title == null || title.Length == 0)\n        //        title = \"Browser\";\n\n        //    DockContent dockContent = this.Control.FindForm() as DockContent;\n        //    if (dockContent != null)\n        //    {\n        //        dockContent.TabText = title;\n        //    }\n        //}\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/BrowserDisplayBinding/DefaultHtmlViewSchemeExtension.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing System.Windows.Forms;\n\nnamespace Sheng.Winform.Controls\n{\n   public  class DefaultHtmlViewSchemeExtension : IHtmlViewSchemeExtension\n    {\n        public virtual void InterceptNavigate(HtmlViewPane pane, WebBrowserNavigatingEventArgs e) { }\n\n        public virtual void DocumentCompleted(HtmlViewPane pane, WebBrowserDocumentCompletedEventArgs e) { }\n\n        public virtual void GoHome(HtmlViewPane pane)\n        {\n            pane.Navigate(HtmlViewPane.DefaultHomepage);\n        }\n\n        public virtual void GoSearch(HtmlViewPane pane)\n        {\n            pane.Navigate(HtmlViewPane.DefaultSearchUrl);\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/BrowserDisplayBinding/ExtendedWebBrowser.cs",
    "content": "﻿using System;\nusing System.ComponentModel;\nusing System.Runtime.InteropServices;\nusing System.Windows.Forms;\n\nnamespace Sheng.Winform.Controls\n{\n    public delegate void NewWindowExtendedEventHandler(object sender, NewWindowExtendedEventArgs e);\n\n    public class NewWindowExtendedEventArgs : CancelEventArgs\n    {\n        Uri url;\n\n        public Uri Url\n        {\n            get\n            {\n                return url;\n            }\n        }\n\n        public NewWindowExtendedEventArgs(Uri url)\n        {\n            this.url = url;\n        }\n    }\n\n    /// <summary>\n    /// Microsoft didn't include the URL being surfed to in the NewWindow event args,\n    /// but here is the workaround:\n    /// </summary>\n    public class ExtendedWebBrowser : WebBrowser\n    {\n        class WebBrowserExtendedEvents : System.Runtime.InteropServices.StandardOleMarshalObject, DWebBrowserEvents2\n        {\n            private ExtendedWebBrowser browser;\n\n            public WebBrowserExtendedEvents(ExtendedWebBrowser browser)\n            {\n                this.browser = browser;\n            }\n\n            public void NewWindow3(object pDisp, ref bool cancel, ref object flags, ref string urlContext, ref string url)\n            {\n                NewWindowExtendedEventArgs e = new NewWindowExtendedEventArgs(new Uri(url));\n                browser.OnNewWindowExtended(e);\n                cancel = e.Cancel;\n            }\n        }\n\n\n        [ComImport()]\n        [Guid(\"34A715A0-6587-11D0-924A-0020AFC7AC4D\")]\n        [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]\n        [TypeLibType(TypeLibTypeFlags.FHidden)]\n        interface DWebBrowserEvents2\n        {\n            [DispId(273)]\n            void NewWindow3([InAttribute(), MarshalAs(UnmanagedType.IDispatch)] object pDisp,\n                            [InAttribute(), OutAttribute()]                 ref bool cancel,\n                            [InAttribute()]                                 ref object flags,\n                            [InAttribute(), MarshalAs(UnmanagedType.BStr)]  ref string urlContext,\n                            [InAttribute(), MarshalAs(UnmanagedType.BStr)]  ref string url);\n        }\n\n        public event NewWindowExtendedEventHandler NewWindowExtended;\n\n        private AxHost.ConnectionPointCookie cookie;\n        private WebBrowserExtendedEvents wevents;\n\n        protected override void CreateSink()\n        {\n            base.CreateSink();\n            wevents = new WebBrowserExtendedEvents(this);\n            cookie = new AxHost.ConnectionPointCookie(this.ActiveXInstance, wevents, typeof(DWebBrowserEvents2));\n        }\n\n        protected override void DetachSink()\n        {\n            if (cookie != null)\n            {\n                cookie.Disconnect();\n                cookie = null;\n            }\n            base.DetachSink();\n        }\n\n        protected virtual void OnNewWindowExtended(NewWindowExtendedEventArgs e)\n        {\n            if (NewWindowExtended != null)\n            {\n                NewWindowExtended(this, e);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/BrowserDisplayBinding/HtmlViewPane.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Drawing;\nusing System.Windows.Forms;\n\nnamespace Sheng.Winform.Controls\n{\n    public class HtmlViewPane : UserControl\n    {\n        public const string DefaultHomepage = \"http://www.shengxunwei.com/\";\n        public const string DefaultSearchUrl = \"http://www.google.com/\";\n\n        #region 私有成员\n\n        string dummyUrl;\n\n        private ExtendedWebBrowser webBrowser = null;\n\n        private ToolStrip toolStrip;\n        private ToolStripItem toolStripItemBack, toolStripItemForward;\n\n        private Control comboBoxUrl;\n\n        #endregion\n\n        #region 公开属性\n\n        private bool _showNavigation;\n        public bool ShowNavigation\n        {\n            get\n            {\n                return this._showNavigation;\n            }\n            set\n            {\n                this._showNavigation = value;\n\n                if (value)\n                {\n                    if (this.toolStrip == null)\n                    {\n                        #region 创建导航条\n\n                        toolStrip = new ToolStrip();\n                        toolStrip.RenderMode = ToolStripRenderMode.Professional;\n                        toolStrip.Renderer = ToolStripRenders.WhiteToSilverGray;\n                        toolStrip.GripStyle = ToolStripGripStyle.Hidden;\n\n                        //后退\n                        toolStripItemBack = new ToolStripButton();\n                        //toolStripItemBack.Text = \"Back\";\n                        toolStripItemBack.Image = IconResource.Browser_Back;\n                        toolStripItemBack.Click += delegate { this.webBrowser.GoBack(); };\n                        toolStrip.Items.Add(toolStripItemBack);\n\n                        //前进\n                        toolStripItemForward = new ToolStripButton();\n                        //toolStripItemForward.Text = \"Forward\";\n                        toolStripItemForward.Image = IconResource.Browser_Forward;\n                        toolStripItemForward.Click += delegate { this.webBrowser.GoForward(); };\n                        toolStrip.Items.Add(toolStripItemForward);\n\n                        ToolStripItem toolStripItem;\n\n                        //停止\n                        toolStripItem = new ToolStripButton();\n                        //toolStripItem.Text = \"Stop\";\n                        toolStripItem.Image = IconResource.Browser_Stop;\n                        toolStripItem.Click += delegate { this.webBrowser.Stop(); };\n                        toolStrip.Items.Add(toolStripItem);\n\n                        //刷新\n                        toolStripItem = new ToolStripButton();\n                        //toolStripItem.Text = \"Refresh\";\n                        toolStripItem.Image = IconResource.Browser_Refresh;\n                        toolStripItem.Click += delegate { this.webBrowser.Refresh(); };\n                        toolStrip.Items.Add(toolStripItem);\n\n                        toolStripItem = new ToolStripSeparator();\n                        toolStrip.Items.Add(toolStripItem);\n\n                        //主页\n                        toolStripItem = new ToolStripButton();\n                        //toolStripItem.Text = \"GoHome\";\n                        toolStripItem.Image = IconResource.Browser_Home;\n                        toolStripItem.Click += delegate { GoHome(); };\n                        toolStrip.Items.Add(toolStripItem);\n\n                        //搜索\n                        //toolStripItem = new ToolStripButton();\n                        //toolStripItem.Text = \"GoSearch\";\n                        //toolStripItem.Click += delegate { GoSearch(); };\n                        //toolStrip.Items.Add(toolStripItem);\n\n                        //地址栏\n                        ToolStripComboBox toolStripComboBox = new ToolStripComboBox();\n                        toolStripComboBox.ComboBox.Width *= 3;\n                        SetUrlComboBox(toolStripComboBox.ComboBox);\n                        toolStrip.Items.Add(toolStripComboBox);\n\n                        //新窗口\n                        //toolStripItem = new ToolStripButton();\n                        //toolStripItem.Text = \"NewWindow\";\n                        //toolStripItem.Click += delegate { NewWindow(null,null); };\n                        //toolStrip.Items.Add(toolStripItem);\n\n                        Controls.Add(toolStrip);\n\n                        #endregion\n                    }\n\n                    this.toolStrip.Visible = true;\n                }\n                else\n                {\n                    if (this.toolStrip != null)\n                    {\n                        this.toolStrip.Visible = false;\n                    }\n                }\n            }\n        }\n\n        public ExtendedWebBrowser WebBrowser\n        {\n            get\n            {\n                return webBrowser;\n            }\n        }\n\n        public Uri Url\n        {\n            get\n            {\n                if (webBrowser.Url == null)\n                    return new Uri(\"about:blank\");\n                if (dummyUrl != null && webBrowser.Url.ToString() == \"about:blank\")\n                {\n                    return new Uri(dummyUrl);\n                }\n                else\n                {\n                    return webBrowser.Url;\n                }\n            }\n        }\n\n        /*\n         * 点击最近打开项目历史记录列表打开项目后\n         *  WebBrowse.Url 会变成点的那个URL，如\"startpage://project/D:/Users/sheng/Desktop/zz.zip\"\n         *  而显示的页面和URL框里的地址还是一开始的 \"startpage://start/\"\n         */\n        /// <summary>\n        /// URL框中显示的地址\n        /// 这个地址是可能不同于WebBrowse中的实际URL的\n        /// </summary>\n        public string DummyUrl\n        {\n            get\n            {\n                if (this.comboBoxUrl != null)\n                    return this.comboBoxUrl.Text;\n                else\n                    return this.Url.ToString();\n            }\n        }\n\n        #endregion\n\n        #region 构造\n\n        public HtmlViewPane(bool showNavigation)\n        {\n            Dock = DockStyle.Fill;\n            Size = new Size(500, 500);\n\n            webBrowser = new ExtendedWebBrowser();\n            webBrowser.Dock = DockStyle.Fill;\n            webBrowser.Navigating += new WebBrowserNavigatingEventHandler(webBrowser_Navigating);\n            webBrowser.NewWindowExtended += new NewWindowExtendedEventHandler(webBrowser_NewWindowExtended);\n            webBrowser.Navigated += new WebBrowserNavigatedEventHandler(webBrowser_Navigated);\n            webBrowser.StatusTextChanged += new EventHandler(webBrowser_StatusTextChanged);\n            webBrowser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webBrowser_DocumentCompleted);\n            webBrowser.DocumentTitleChanged += new EventHandler(webBrowser_DocumentTitleChanged);\n            Controls.Add(webBrowser);\n\n            this.ShowNavigation = showNavigation;\n        }\n\n        #endregion\n\n        #region 事件处理\n\n        void webBrowser_DocumentTitleChanged(object sender, EventArgs e)\n        {\n            if (this.TitleChanged != null)\n            {\n                TitleChanged(webBrowser.DocumentTitle);\n            }\n        }\n\n        void webBrowser_StatusTextChanged(object sender, EventArgs e)\n        {\n            //览器状态栏文本改变，把文本显示到软件主状态栏中\n            //IWorkbenchWindow workbench = WorkbenchSingleton.Workbench.Instance.ActiveWorkbenchWindow;\n            //if (workbench == null) return;\n            //BrowserPane browser = Workbench.Instance.ActiveViewContent as BrowserPane;\n            //if (browser == null) return;\n            //if (browser.HtmlViewPane == this)\n            //{\n            //    StatusBarService.SetMessage(webBrowser.StatusText);\n            //}\n\n            //浏览器状态栏文本改变，把文本显示到软件主状态栏中\n            //Workbench.Instance.SetStatusBarMessage(webBrowser.StatusText);\n            if (this.StatusTextChanged != null)\n                StatusTextChanged(webBrowser.StatusText);\n        }\n\n        void webBrowser_Navigating(object sender, WebBrowserNavigatingEventArgs e)\n        {\n            try\n            {\n                IHtmlViewSchemeExtension extension = GetScheme(e.Url.Scheme);\n                if (extension != null)\n                {\n                    extension.InterceptNavigate(this, e);\n                    if (e.TargetFrameName.Length == 0)\n                    {\n                        if (e.Cancel == true)\n                        {\n                            dummyUrl = e.Url.ToString();\n                        }\n                        else if (e.Url.ToString() != \"about:blank\")\n                        {\n                            dummyUrl = null;\n                        }\n                    }\n                }\n            }\n            catch (Exception ex)\n            {\n                //MessageService.ShowError(ex);\n                MessageBox.Show(ex.Message);\n            }\n        }\n\n        void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)\n        {\n            try\n            {\n                if (dummyUrl != null && e.Url.ToString() == \"about:blank\")\n                {\n                    e = new WebBrowserDocumentCompletedEventArgs(new Uri(dummyUrl));\n                }\n                IHtmlViewSchemeExtension extension = GetScheme(e.Url.Scheme);\n                if (extension != null)\n                {\n                    extension.DocumentCompleted(this, e);\n                }\n            }\n            catch (Exception ex)\n            {\n                //MessageService.ShowError(ex);\n                MessageBox.Show(ex.Message);\n            }\n        }\n\n        void webBrowser_NewWindowExtended(object sender, NewWindowExtendedEventArgs e)\n        {\n            e.Cancel = true;\n            //显示在软件主界面的主选项卡文档中\n            //WorkbenchSingleton.Workbench.Instance.ShowView(new BrowserPane(e.Url));\n\n            //显示在软件主界面的主选项卡文档中\n            BrowserPane browserPane = new BrowserPane();\n            browserPane.View.Dock = DockStyle.Fill;\n\n            //FormBrowser dockContent = new FormBrowser();\n            //dockContent.HideOnClose = false;\n            //dockContent.TabText = \"Browser\";\n            //dockContent.Controls.Add(browserPane.Control);\n\n            //Workbench.Instance.ShowView(dockContent);\n\n            if (NewWindow != null)\n            {\n                NewWindow(this, new HtmlViewPaneNewWindowEventArgs(browserPane, e.Url));\n            }\n        }\n\n        void webBrowser_Navigated(object sender, WebBrowserNavigatedEventArgs e)\n        {\n            // do not use e.Url (frames!)\n            string url = webBrowser.Url.ToString();\n            if (dummyUrl != null && url == \"about:blank\")\n            {\n                comboBoxUrl.Text = dummyUrl;\n            }\n            else\n            {\n                comboBoxUrl.Text = url;\n            }\n            //// Update toolbar:\n            //foreach (object o in toolStrip.Items)\n            //{\n            //    IStatusUpdate up = o as IStatusUpdate;\n            //    if (up != null)\n            //        up.UpdateStatus();\n            //}\n\n            if (_showNavigation)\n            {\n                toolStripItemBack.Enabled = this.webBrowser.CanGoBack;\n                toolStripItemForward.Enabled = this.webBrowser.CanGoForward;\n            }\n        }\n\n\n        #endregion\n\n        #region 公开方法\n\n        //static List<SchemeExtensionDescriptor> descriptors;\n        public IHtmlViewSchemeExtension GetScheme(string name)\n        {\n            //if (descriptors == null)\n            //{\n            //    descriptors = AddInTree.BuildItems<SchemeExtensionDescriptor>(\"/SharpDevelop/Views/Browser/SchemeExtensions\", null, false);\n            //}\n            //foreach (SchemeExtensionDescriptor descriptor in descriptors)\n            //{\n            //    if (string.Equals(name, descriptor.SchemeName, StringComparison.OrdinalIgnoreCase))\n            //    {\n            //        return descriptor.Extension;\n            //    }\n            //}\n            //return null;\n\n            if (GetSchemeFunc != null)\n            {\n                return GetSchemeFunc(this, new HtmlViewPaneGetSchemeEventArgs(name));\n            }\n            else\n            {\n                return null;\n            }\n        }\n\n        /// <summary>\n        /// Closes the ViewContent that contains this HtmlViewPane.\n        /// </summary>\n        public void Close()\n        {\n            if (Closed != null)\n            {\n                Closed(this, EventArgs.Empty);\n            }\n        }\n\n        public void Navigate(string url)\n        {\n            Uri uri;\n            try\n            {\n                uri = new Uri(url);\n            }\n            catch (Exception ex)\n            {\n                MessageBox.Show(ex.Message, \"Error\", MessageBoxButtons.OK, MessageBoxIcon.Error);\n                return;\n            }\n\n            Navigate(new Uri(url));\n        }\n\n        public void Navigate(Uri url)\n        {\n            try\n            {\n                webBrowser.Navigate(url);\n            }\n            catch (Exception ex)\n            {\n                //LoggingService.Warn(\"Error navigating to \" + url.ToString(), ex);\n                MessageBox.Show(ex.Message, \"Error\", MessageBoxButtons.OK, MessageBoxIcon.Error);\n            }\n        }\n\n        public void GoHome()\n        {\n            IHtmlViewSchemeExtension extension = GetScheme(Url.Scheme);\n            if (extension != null)\n            {\n                extension.GoHome(this);\n            }\n            else\n            {\n                Navigate(DefaultHomepage);\n            }\n        }\n\n        public void GoSearch()\n        {\n            IHtmlViewSchemeExtension extension = GetScheme(Url.Scheme);\n            if (extension != null)\n            {\n                extension.GoSearch(this);\n            }\n            else\n            {\n                Navigate(DefaultSearchUrl);\n            }\n        }\n\n        public void SetUrlComboBox(ComboBox comboBox)\n        {\n            SetUrlBox(comboBox);\n            comboBox.DropDownStyle = ComboBoxStyle.DropDown;\n            comboBox.Items.Clear();\n            //comboBox.Items.AddRange(PropertyService.Get(\"Browser.URLBoxHistory\", new string[0]));\n            comboBox.AutoCompleteMode = AutoCompleteMode.Suggest;\n            comboBox.AutoCompleteSource = AutoCompleteSource.HistoryList;\n        }\n\n        public void SetUrlBox(Control urlBox)\n        {\n            this.comboBoxUrl = urlBox;\n            urlBox.KeyUp += UrlBoxKeyUp;\n        }\n\n        protected override void Dispose(bool disposing)\n        {\n            base.Dispose(disposing);\n            if (disposing)\n            {\n                webBrowser.Dispose();\n            }\n        }\n\n        #endregion\n\n        #region 私有方法\n\n        private void UrlBoxKeyUp(object sender, KeyEventArgs e)\n        {\n            Control ctl = (Control)sender;\n            if (e.KeyData == Keys.Return)\n            {\n                e.Handled = true;\n                UrlBoxNavigate(ctl);\n            }\n        }\n\n        private void UrlBoxNavigate(Control ctl)\n        {\n            string text = ctl.Text.Trim();\n            if (text.IndexOf(':') < 0)\n            {\n                text = \"http://\" + text;\n            }\n            Navigate(text);\n            //ComboBox comboBox = ctl as ComboBox;\n            //if (comboBox != null)\n            //{\n            //    comboBox.Items.Remove(text);\n            //    comboBox.Items.Insert(0, text);\n            //    // Add to URLBoxHistory:\n            //    string[] history = PropertyService.Get(\"Browser.URLBoxHistory\", new string[0]);\n            //    int pos = Array.IndexOf(history, text);\n            //    if (pos < 0 && history.Length >= 20)\n            //    {\n            //        pos = history.Length - 1; // remove last entry and insert new at the beginning\n            //    }\n            //    if (pos < 0)\n            //    {\n            //        // insert new item\n            //        string[] newHistory = new string[history.Length + 1];\n            //        history.CopyTo(newHistory, 1);\n            //        history = newHistory;\n            //    }\n            //    else\n            //    {\n            //        for (int i = pos; i > 0; i--)\n            //        {\n            //            history[i] = history[i - 1];\n            //        }\n            //    }\n            //    history[0] = text;\n            //    PropertyService.Set(\"Browser.URLBoxHistory\", history);\n            //}\n        }\n\n        #endregion\n\n        #region 事件\n\n        public event EventHandler Closed;\n\n        public event OnHtmlViewPaneNewWindowHandler NewWindow;\n\n        public Func<object, HtmlViewPaneGetSchemeEventArgs, IHtmlViewSchemeExtension> GetSchemeFunc;\n\n        public Action<string> StatusTextChanged;\n\n        public Action<string> TitleChanged;\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/BrowserDisplayBinding/HtmlViewPaneEvents.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nnamespace Sheng.Winform.Controls\n{\n    public delegate void OnHtmlViewPaneNewWindowHandler(object sender, HtmlViewPaneNewWindowEventArgs args);\n\n    public class HtmlViewPaneNewWindowEventArgs : EventArgs\n    {\n        public HtmlViewPaneNewWindowEventArgs(BrowserPane browserPane,Uri url)\n        {\n            Url = url;\n            BrowserPane = browserPane;\n        }\n\n        public Uri Url\n        {\n            get;\n            private set;\n        }\n\n        public BrowserPane BrowserPane\n        {\n            get;\n            private set;\n        }\n    }\n\n    public class HtmlViewPaneGetSchemeEventArgs : EventArgs\n    {\n        public HtmlViewPaneGetSchemeEventArgs(string schemeName)\n        {\n            SchemeName = schemeName;\n        }\n\n        public string SchemeName\n        {\n            get;\n            private set;\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/BrowserDisplayBinding/IHtmlViewSchemeExtension.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\n\nnamespace Sheng.Winform.Controls\n{\n    public interface IHtmlViewSchemeExtension\n    {\n        void InterceptNavigate(HtmlViewPane pane, WebBrowserNavigatingEventArgs e);\n        void DocumentCompleted(HtmlViewPane pane, WebBrowserDocumentCompletedEventArgs e);\n        void GoHome(HtmlViewPane pane);\n        void GoSearch(HtmlViewPane pane);\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/DragHelper.cs",
    "content": "﻿//用在SETreeView 的拖放操作时\n//http://www.codeproject.com/KB/tree/TreeViewDragDrop.aspx\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Runtime.InteropServices;\n\nnamespace Sheng.Winform.Controls\n{\n    public class DragHelper\n    {\n        [DllImport(\"comctl32.dll\")]\n        public static extern bool InitCommonControls();\n\n        [DllImport(\"comctl32.dll\", CharSet = CharSet.Auto)]\n        public static extern bool ImageList_BeginDrag(IntPtr himlTrack, int\n            iTrack, int dxHotspot, int dyHotspot);\n\n        [DllImport(\"comctl32.dll\", CharSet = CharSet.Auto)]\n        public static extern bool ImageList_DragMove(int x, int y);\n\n        [DllImport(\"comctl32.dll\", CharSet = CharSet.Auto)]\n        public static extern void ImageList_EndDrag();\n\n        [DllImport(\"comctl32.dll\", CharSet = CharSet.Auto)]\n        public static extern bool ImageList_DragEnter(IntPtr hwndLock, int x, int y);\n\n        [DllImport(\"comctl32.dll\", CharSet = CharSet.Auto)]\n        public static extern bool ImageList_DragLeave(IntPtr hwndLock);\n\n        [DllImport(\"comctl32.dll\", CharSet = CharSet.Auto)]\n        public static extern bool ImageList_DragShowNolock(bool fShow);\n\n        static DragHelper()\n        {\n            InitCommonControls();\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/IShengForm.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nnamespace Sheng.Winform.Controls\n{\n    interface IShengForm\n    {\n        bool DoValidate();\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/IShengValidate.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nnamespace Sheng.Winform.Controls\n{\n    public delegate bool CustomValidateMethod(object sender, out string msg);\n\n    interface IShengValidate\n    {\n        /// <summary>\n        /// 验证失败中显示错误信息时用的标题\n        /// </summary>\n        string Title { get; set; }\n\n        /// <summary>\n        /// 验证失败时是否需要高亮显示（改变背景色）\n        /// </summary>\n        bool HighLight { get; set; }\n\n        /// <summary>\n        /// 验证控件的输入\n        /// </summary>\n        /// <param name=\"msg\"></param>\n        /// <returns></returns>\n        bool SEValidate(out string msg);\n\n        /// <summary>\n        /// 自定义验证方法\n        /// 在基础验证都通过后，才会调用自定义验证方法（如果有）\n        /// </summary>\n        CustomValidateMethod CustomValidate { get; set; }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/IconResource.Designer.cs",
    "content": "﻿//------------------------------------------------------------------------------\r\n// <auto-generated>\r\n//     此代码由工具生成。\r\n//     运行时版本:4.0.30319.42000\r\n//\r\n//     对此文件的更改可能会导致不正确的行为，并且如果\r\n//     重新生成代码，这些更改将会丢失。\r\n// </auto-generated>\r\n//------------------------------------------------------------------------------\r\n\r\nnamespace Sheng.Winform.Controls {\r\n    using System;\r\n    \r\n    \r\n    /// <summary>\r\n    ///   一个强类型的资源类，用于查找本地化的字符串等。\r\n    /// </summary>\r\n    // 此类是由 StronglyTypedResourceBuilder\r\n    // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。\r\n    // 若要添加或移除成员，请编辑 .ResX 文件，然后重新运行 ResGen\r\n    // (以 /str 作为命令选项)，或重新生成 VS 项目。\r\n    [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Resources.Tools.StronglyTypedResourceBuilder\", \"4.0.0.0\")]\r\n    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\r\n    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]\r\n    internal class IconResource {\r\n        \r\n        private static global::System.Resources.ResourceManager resourceMan;\r\n        \r\n        private static global::System.Globalization.CultureInfo resourceCulture;\r\n        \r\n        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"Microsoft.Performance\", \"CA1811:AvoidUncalledPrivateCode\")]\r\n        internal IconResource() {\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   返回此类使用的缓存的 ResourceManager 实例。\r\n        /// </summary>\r\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\r\n        internal static global::System.Resources.ResourceManager ResourceManager {\r\n            get {\r\n                if (object.ReferenceEquals(resourceMan, null)) {\r\n                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager(\"Sheng.Winform.Controls.IconResource\", typeof(IconResource).Assembly);\r\n                    resourceMan = temp;\r\n                }\r\n                return resourceMan;\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   使用此强类型资源类，为所有资源查找\r\n        ///   重写当前线程的 CurrentUICulture 属性。\r\n        /// </summary>\r\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\r\n        internal static global::System.Globalization.CultureInfo Culture {\r\n            get {\r\n                return resourceCulture;\r\n            }\r\n            set {\r\n                resourceCulture = value;\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\r\n        /// </summary>\r\n        internal static System.Drawing.Bitmap Arrow_right_green {\r\n            get {\r\n                object obj = ResourceManager.GetObject(\"Arrow_right_green\", resourceCulture);\r\n                return ((System.Drawing.Bitmap)(obj));\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\r\n        /// </summary>\r\n        internal static System.Drawing.Bitmap Browser {\r\n            get {\r\n                object obj = ResourceManager.GetObject(\"Browser\", resourceCulture);\r\n                return ((System.Drawing.Bitmap)(obj));\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\r\n        /// </summary>\r\n        internal static System.Drawing.Bitmap Browser_Back {\r\n            get {\r\n                object obj = ResourceManager.GetObject(\"Browser_Back\", resourceCulture);\r\n                return ((System.Drawing.Bitmap)(obj));\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\r\n        /// </summary>\r\n        internal static System.Drawing.Bitmap Browser_Forward {\r\n            get {\r\n                object obj = ResourceManager.GetObject(\"Browser_Forward\", resourceCulture);\r\n                return ((System.Drawing.Bitmap)(obj));\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\r\n        /// </summary>\r\n        internal static System.Drawing.Bitmap Browser_Home {\r\n            get {\r\n                object obj = ResourceManager.GetObject(\"Browser_Home\", resourceCulture);\r\n                return ((System.Drawing.Bitmap)(obj));\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\r\n        /// </summary>\r\n        internal static System.Drawing.Bitmap Browser_Refresh {\r\n            get {\r\n                object obj = ResourceManager.GetObject(\"Browser_Refresh\", resourceCulture);\r\n                return ((System.Drawing.Bitmap)(obj));\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\r\n        /// </summary>\r\n        internal static System.Drawing.Bitmap Browser_Stop {\r\n            get {\r\n                object obj = ResourceManager.GetObject(\"Browser_Stop\", resourceCulture);\r\n                return ((System.Drawing.Bitmap)(obj));\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "Sheng.Winform.Controls/IconResource.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <assembly alias=\"System.Windows.Forms\" name=\"System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\" />\n  <data name=\"Arrow_right_green\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>Resources\\Arrow_right_green.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <assembly alias=\"System.Windows.Forms\" name=\"System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\" />\n  <data name=\"Browser\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>Resources\\Browser.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"Browser_Back\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>Resources\\Browser_Back.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"Browser_Forward\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>Resources\\Browser_Forward.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"Browser_Home\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>Resources\\Browser_Home.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"Browser_Refresh\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>Resources\\Browser_Refresh.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"Browser_Stop\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>Resources\\Browser_Stop.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n</root>"
  },
  {
    "path": "Sheng.Winform.Controls/License/SEControlLicense.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.ComponentModel;\n\nnamespace Sheng.Winform.Controls\n{\n    class SEControlLicense : License\n    {\n        private Type _Type;\n\n        public SEControlLicense(Type type)\n        {\n            if (type == null)\n            {\n                throw (new NullReferenceException());\n            }\n\n            _Type = type;\n        }\n\n        public override void Dispose()\n        {\n            // 根据需要插入垃圾回收的代码 \n        }\n\n        /// <summary>\n        /// 获取授予该组件的许可证密钥\n        /// </summary>\n        public override string LicenseKey\n        {\n            get { return (_Type.GUID.ToString()); }\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/License/SEControlLicenseProvider.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.ComponentModel;\nusing Microsoft.Win32;\n\nnamespace Sheng.Winform.Controls\n{\n    class SEControlLicenseProvider : LicenseProvider\n    {\n        /// <summary>\n        /// 0:未验证\n        /// 1:验证失败\n        /// 2:验证通过\n        /// </summary>\n        //private static ushort _isValid = 0;\n        public bool IsValid\n        {\n            get\n            {\n                //TODO:SEControlLicenseProvider\n                return true;\n                //    using (RegistryKey registryKey =\n                //        Registry.LocalMachine.CreateSubKey(@\"SOFTWARE\\Sheng.SIMBE\\SEControl\"))\n                //    {\n                //        object license = registryKey.GetValue(\"License\");\n                //        if (license == null)\n                //        {\n                //            _isValid = 1;\n                //        }\n                //        else\n                //        {\n                //            if (license.ToString() == \"sheng\")\n                //                _isValid = 2;\n                //            else\n                //                _isValid = 1;\n                //        }\n                //    }\n\n                //return _isValid == 2 ? true : false;\n            }\n        }\n\n        /// <summary>\n        /// 获取组件的实例或类型的许可证（如果已给定上下文并确定拒绝许可证是否引发异常）。\n        /// </summary>\n        /// <param name=\"context\"></param>\n        /// <param name=\"type\"></param>\n        /// <param name=\"instance\"></param>\n        /// <param name=\"allowExceptions\"></param>\n        /// <returns></returns>\n        public override License GetLicense(LicenseContext context, Type type, object instance, bool allowExceptions)\n        {\n            if (context.UsageMode == LicenseUsageMode.Runtime)\n            {\n                return new SEControlLicense(type);\n            }\n\n            else if (context.UsageMode == LicenseUsageMode.Designtime)\n            {\n                // 限制编辑模式下的许可证（所谓的开发许可证），在这里添加相应的逻辑\n\n                if (!IsValid)\n                    throw new LicenseException(type);\n                else\n                    return new SEControlLicense(type);\n            }\n\n            return (null);\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/License/TextFile1.txt",
    "content": "﻿在注册表的\nLocalMachine:SOFTWARE\\Sheng.SIMBE\\SEControl\n下，以一个 License 属性保存 sheng ，则允许使用"
  },
  {
    "path": "Sheng.Winform.Controls/LocalizedDescription.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.ComponentModel;\nusing Sheng.Winform.Controls.Localisation;\n\nnamespace Sheng.Winform.Controls\n{\n    [AttributeUsage(AttributeTargets.All)]\n    sealed class LocalizedDescriptionAttribute : DescriptionAttribute\n    {\n        private bool m_initialized = false;\n\n        public LocalizedDescriptionAttribute(string key)\n            : base(key)\n        {\n        }\n\n        public override string Description\n        {\n            get\n            {\n                if (!m_initialized)\n                {\n                    string key = base.Description;\n                    DescriptionValue = Language.GetString(key);\n                    if (DescriptionValue == null)\n                        DescriptionValue = String.Empty;\n\n                    m_initialized = true;\n                }\n\n                return DescriptionValue;\n            }\n        }\n    }\n\n    [AttributeUsage(AttributeTargets.All)]\n    sealed class LocalizedCategoryAttribute : CategoryAttribute\n    {\n        public LocalizedCategoryAttribute(string key)\n            : base(key)\n        {\n        }\n\n        protected override string GetLocalizedString(string key)\n        {\n            return Language.GetString(key);\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/PopupControl/GripBounds.cs",
    "content": "﻿using System;\nusing System.Drawing;\n\nnamespace Sheng.Winform.Controls.PopupControl\n{\n    internal struct GripBounds\n    {\n        private const int GripSize = 6;\n        private const int CornerGripSize = GripSize << 1;\n\n        public GripBounds(Rectangle clientRectangle)\n        {\n            this.clientRectangle = clientRectangle;\n        }\n\n        private Rectangle clientRectangle;\n        public Rectangle ClientRectangle\n        {\n            get { return clientRectangle; }\n            //set { clientRectangle = value; }\n        }\n\n        public Rectangle Bottom\n        {\n            get\n            {\n                Rectangle rect = ClientRectangle;\n                rect.Y = rect.Bottom - GripSize + 1;\n                rect.Height = GripSize;\n                return rect;\n            }\n        }\n\n        public Rectangle BottomRight\n        {\n            get\n            {\n                Rectangle rect = ClientRectangle;\n                rect.Y = rect.Bottom - CornerGripSize + 1;\n                rect.Height = CornerGripSize;\n                rect.X = rect.Width - CornerGripSize + 1;\n                rect.Width = CornerGripSize;\n                return rect;\n            }\n        }\n\n        public Rectangle Top\n        {\n            get\n            {\n                Rectangle rect = ClientRectangle;\n                rect.Height = GripSize;\n                return rect;\n            }\n        }\n\n        public Rectangle TopRight\n        {\n            get\n            {\n                Rectangle rect = ClientRectangle;\n                rect.Height = CornerGripSize;\n                rect.X = rect.Width - CornerGripSize + 1;\n                rect.Width = CornerGripSize;\n                return rect;\n            }\n        }\n\n        public Rectangle Left\n        {\n            get\n            {\n                Rectangle rect = ClientRectangle;\n                rect.Width = GripSize;\n                return rect;\n            }\n        }\n\n        public Rectangle BottomLeft\n        {\n            get\n            {\n                Rectangle rect = ClientRectangle;\n                rect.Width = CornerGripSize;\n                rect.Y = rect.Height - CornerGripSize + 1;\n                rect.Height = CornerGripSize;\n                return rect;\n            }\n        }\n\n        public Rectangle Right\n        {\n            get\n            {\n                Rectangle rect = ClientRectangle;\n                rect.X = rect.Right - GripSize + 1;\n                rect.Width = GripSize;\n                return rect;\n            }\n        }\n\n        public Rectangle TopLeft\n        {\n            get\n            {\n                Rectangle rect = ClientRectangle;\n                rect.Width = CornerGripSize;\n                rect.Height = CornerGripSize;\n                return rect;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/PopupControl/NativeMethods.cs",
    "content": "using System;\nusing System.Drawing;\nusing System.Runtime.InteropServices;\nusing System.Windows.Forms;\nusing System.Security;\nusing System.Security.Permissions;\n\nnamespace Sheng.Winform.Controls.PopupControl\n{\n    internal static class NativeMethods\n    {\n        internal const int WM_NCHITTEST = 0x0084,\n                           WM_NCACTIVATE = 0x0086,\n                           WS_EX_NOACTIVATE = 0x08000000,\n                           HTTRANSPARENT = -1,\n                           HTLEFT = 10,\n                           HTRIGHT = 11,\n                           HTTOP = 12,\n                           HTTOPLEFT = 13,\n                           HTTOPRIGHT = 14,\n                           HTBOTTOM = 15,\n                           HTBOTTOMLEFT = 16,\n                           HTBOTTOMRIGHT = 17,\n                           WM_PRINT = 0x0317,\n                           WM_USER = 0x0400,\n                           WM_REFLECT = WM_USER + 0x1C00,\n                           WM_COMMAND = 0x0111,\n                           CBN_DROPDOWN = 7,\n                           WM_GETMINMAXINFO = 0x0024;\n\n\n        [Flags]\n        internal enum AnimationFlags : int\n        {\n            Roll = 0x0000, // Uses a roll animation.\n            HorizontalPositive = 0x00001, // Animates the window from left to right. This flag can be used with roll or slide animation.\n            HorizontalNegative = 0x00002, // Animates the window from right to left. This flag can be used with roll or slide animation.\n            VerticalPositive = 0x00004, // Animates the window from top to bottom. This flag can be used with roll or slide animation.\n            VerticalNegative = 0x00008, // Animates the window from bottom to top. This flag can be used with roll or slide animation.\n            Center = 0x00010, // Makes the window appear to collapse inward if <c>Hide</c> is used or expand outward if the <c>Hide</c> is not used.\n            Hide = 0x10000, // Hides the window. By default, the window is shown.\n            Activate = 0x20000, // Activates the window.\n            Slide = 0x40000, // Uses a slide animation. By default, roll animation is used.\n            Blend = 0x80000, // Uses a fade effect. This flag can be used only with a top-level window.\n            Mask = 0xfffff,\n        }\n\n        [SuppressUnmanagedCodeSecurity]\n        [DllImport(\"user32.dll\", CharSet = CharSet.Auto)]\n        private static extern int AnimateWindow(HandleRef windowHandle, int time, AnimationFlags flags);\n\n        internal static void AnimateWindow(Control control, int time, AnimationFlags flags)\n        {\n            try\n            {\n                SecurityPermission sp = new SecurityPermission(SecurityPermissionFlag.UnmanagedCode);\n                sp.Demand();\n                AnimateWindow(new HandleRef(control, control.Handle), time, flags);\n            }\n            catch (SecurityException) { }\n        }\n\n        internal static int HIWORD(int n)\n        {\n            return (n >> 16) & 0xffff;\n        }\n\n        internal static int HIWORD(IntPtr n)\n        {\n            return HIWORD(unchecked((int)(long)n));\n        }\n\n        internal static int LOWORD(int n)\n        {\n            return n & 0xffff;\n        }\n\n        internal static int LOWORD(IntPtr n)\n        {\n            return LOWORD(unchecked((int)(long)n));\n        }\n\n        [StructLayout(LayoutKind.Sequential)]\n        internal struct MINMAXINFO\n        {\n            public Point reserved;\n            public Size maxSize;\n            public Point maxPosition;\n            public Size minTrackSize;\n            public Size maxTrackSize;\n        }\n    }\n}"
  },
  {
    "path": "Sheng.Winform.Controls/PopupControl/Popup.Designer.cs",
    "content": "﻿namespace Sheng.Winform.Controls.PopupControl\n{\n    partial class Popup\n    {\n        /// <summary>\n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing)\n            {\n                if (components != null)\n                {\n                    components.Dispose();\n                }\n                if (content != null)\n                {\n                    System.Windows.Forms.Control _content = content;\n                    content = null;\n                    _content.Dispose();\n                }\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Component Designer generated code\n\n        /// <summary>\n        /// Required method for Designer support - do not modify \n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            components = new System.ComponentModel.Container();\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/PopupControl/Popup.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Data;\nusing System.Drawing;\nusing System.Drawing.Drawing2D;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Security.Permissions;\nusing System.Runtime.InteropServices;\nusing VS = System.Windows.Forms.VisualStyles;\n\n/*\n<li>Base class for custom tooltips.</li>\n<li>Office-2007-like tooltip class.</li>\n*/\nnamespace Sheng.Winform.Controls.PopupControl\n{\n    /// <summary>\n    /// Represents a pop-up window.\n    /// </summary>\n    //[CLSCompliant(true), ToolboxItem(false)]\n    public partial class Popup : ToolStripDropDown\n    {\n        #region \" Fields & Properties \"\n\n        private Control content;\n        /// <summary>\n        /// Gets the content of the pop-up.\n        /// </summary>\n        public Control Content\n        {\n            get { return content; }\n        }\n\n        private PopupAnimations showingAnimation;\n        /// <summary>\n        /// Determines which animation to use while showing the pop-up window.\n        /// </summary>\n        public PopupAnimations ShowingAnimation\n        {\n            get { return showingAnimation; }\n            set { if (showingAnimation != value) showingAnimation = value; }\n        }\n\n        private PopupAnimations hidingAnimation;\n        /// <summary>\n        /// Determines which animation to use while hiding the pop-up window.\n        /// </summary>\n        public PopupAnimations HidingAnimation\n        {\n            get { return hidingAnimation; }\n            set { if (hidingAnimation != value) hidingAnimation = value; }\n        }\n\n        private int animationDuration;\n        /// <summary>\n        /// Determines the duration of the animation.\n        /// </summary>\n        public int AnimationDuration\n        {\n            get { return animationDuration; }\n            set { if (animationDuration != value) animationDuration = value; }\n        }\n\n        private bool focusOnOpen = true;\n        /// <summary>\n        /// Gets or sets a value indicating whether the content should receive the focus after the pop-up has been opened.\n        /// </summary>\n        /// <value><c>true</c> if the content should be focused after the pop-up has been opened; otherwise, <c>false</c>.</value>\n        /// <remarks>If the FocusOnOpen property is set to <c>false</c>, then pop-up cannot use the fade effect.</remarks>\n        public bool FocusOnOpen\n        {\n            get { return focusOnOpen; }\n            set { focusOnOpen = value; }\n        }\n\n        private bool acceptAlt = true;\n        /// <summary>\n        /// Gets or sets a value indicating whether presing the alt key should close the pop-up.\n        /// </summary>\n        /// <value><c>true</c> if presing the alt key does not close the pop-up; otherwise, <c>false</c>.</value>\n        public bool AcceptAlt\n        {\n            get { return acceptAlt; }\n            set { acceptAlt = value; }\n        }\n\n        private Control opener;\n        private Popup ownerPopup;\n        private Popup childPopup;\n        private bool resizableTop;\n        private bool resizableLeft;\n\n        private bool isChildPopupOpened;\n        private bool resizable;\n        /// <summary>\n        /// Gets or sets a value indicating whether the <see cref=\"PopupControl.Popup\" /> is resizable.\n        /// </summary>\n        /// <value><c>true</c> if resizable; otherwise, <c>false</c>.</value>\n        public bool Resizable\n        {\n            get { return resizable && !isChildPopupOpened; }\n            set { resizable = value; }\n        }\n\n        private ToolStripControlHost host;\n\n        private Size minSize;\n        /// <summary>\n        /// Gets or sets a minimum size of the pop-up.\n        /// </summary>\n        /// <returns>An ordered pair of type <see cref=\"T:System.Drawing.Size\" /> representing the width and height of a rectangle.</returns>\n        public new Size MinimumSize\n        {\n            get { return minSize; }\n            set { minSize = value; }\n        }\n\n        private Size maxSize;\n        /// <summary>\n        /// Gets or sets a maximum size of the pop-up.\n        /// </summary>\n        /// <returns>An ordered pair of type <see cref=\"T:System.Drawing.Size\" /> representing the width and height of a rectangle.</returns>\n        public new Size MaximumSize\n        {\n            get { return maxSize; }\n            set { maxSize = value; }\n        }\n\n        /// <summary>\n        /// Gets parameters of a new window.\n        /// </summary>\n        /// <returns>An object of type <see cref=\"T:System.Windows.Forms.CreateParams\" /> used when creating a new window.</returns>\n        protected override CreateParams CreateParams\n        {\n            [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]\n            get\n            {\n                CreateParams cp = base.CreateParams;\n                cp.ExStyle |= NativeMethods.WS_EX_NOACTIVATE;\n                return cp;\n            }\n        }\n\n        #endregion\n\n        #region \" Constructors \"\n\n        /// <summary>\n        /// Initializes a new instance of the <see cref=\"PopupControl.Popup\"/> class.\n        /// </summary>\n        /// <param name=\"content\">The content of the pop-up.</param>\n        /// <remarks>\n        /// Pop-up will be disposed immediately after disposion of the content control.\n        /// </remarks>\n        /// <exception cref=\"T:System.ArgumentNullException\"><paramref name=\"content\" /> is <code>null</code>.</exception>\n        public Popup(Control content)\n        {\n            if (content == null)\n            {\n                throw new ArgumentNullException(\"content\");\n            }\n            this.content = content;\n            this.showingAnimation = PopupAnimations.SystemDefault;\n            this.hidingAnimation = PopupAnimations.None;\n            this.animationDuration = 100;\n            this.isChildPopupOpened = false;\n            InitializeComponent();\n            AutoSize = false;\n            DoubleBuffered = true;\n            ResizeRedraw = true;\n            host = new ToolStripControlHost(content);\n            Padding = Margin = host.Padding = host.Margin = Padding.Empty;\n            MinimumSize = content.MinimumSize;\n            content.MinimumSize = content.Size;\n            MaximumSize = content.MaximumSize;\n            content.MaximumSize = content.Size;\n            Size = content.Size;\n            TabStop = content.TabStop = true;\n            content.Location = Point.Empty;\n            Items.Add(host);\n            content.Disposed += delegate(object sender, EventArgs e)\n            {\n                content = null;\n                Dispose(true);\n            };\n            content.RegionChanged += delegate(object sender, EventArgs e)\n            {\n                UpdateRegion();\n            };\n            content.Paint += delegate(object sender, PaintEventArgs e)\n            {\n                PaintSizeGrip(e);\n            };\n            UpdateRegion();\n        }\n\n        #endregion\n\n        #region \" Methods \"\n\n        /// <summary>\n        /// Raises the <see cref=\"E:System.Windows.Forms.ToolStripItem.VisibleChanged\"/> event.\n        /// </summary>\n        /// <param name=\"e\">An <see cref=\"T:System.EventArgs\"/> that contains the event data.</param>\n        protected override void OnVisibleChanged(EventArgs e)\n        {\n            base.OnVisibleChanged(e);\n            if ((Visible && ShowingAnimation == PopupAnimations.None) || (!Visible && HidingAnimation == PopupAnimations.None))\n            {\n                return;\n            }\n            NativeMethods.AnimationFlags flags = Visible ? NativeMethods.AnimationFlags.Roll : NativeMethods.AnimationFlags.Hide;\n            PopupAnimations _flags = Visible ? ShowingAnimation : HidingAnimation;\n            if (_flags == PopupAnimations.SystemDefault)\n            {\n                if (SystemInformation.IsMenuAnimationEnabled)\n                {\n                    if (SystemInformation.IsMenuFadeEnabled)\n                    {\n                        _flags = PopupAnimations.Blend;\n                    }\n                    else\n                    {\n                        _flags = PopupAnimations.Slide | (Visible ? PopupAnimations.TopToBottom : PopupAnimations.BottomToTop);\n                    }\n                }\n                else\n                {\n                    _flags = PopupAnimations.None;\n                }\n            }\n            if ((_flags & (PopupAnimations.Blend | PopupAnimations.Center | PopupAnimations.Roll | PopupAnimations.Slide)) == PopupAnimations.None)\n            {\n                return;\n            }\n            if (resizableTop) // popup is “inverted”, so the animation must be\n            {\n                if ((_flags & PopupAnimations.BottomToTop) != PopupAnimations.None)\n                {\n                    _flags = (_flags & ~PopupAnimations.BottomToTop) | PopupAnimations.TopToBottom;\n                }\n                else if ((_flags & PopupAnimations.TopToBottom) != PopupAnimations.None)\n                {\n                    _flags = (_flags & ~PopupAnimations.TopToBottom) | PopupAnimations.BottomToTop;\n                }\n            }\n            if (resizableLeft) // popup is “inverted”, so the animation must be\n            {\n                if ((_flags & PopupAnimations.RightToLeft) != PopupAnimations.None)\n                {\n                    _flags = (_flags & ~PopupAnimations.RightToLeft) | PopupAnimations.LeftToRight;\n                }\n                else if ((_flags & PopupAnimations.LeftToRight) != PopupAnimations.None)\n                {\n                    _flags = (_flags & ~PopupAnimations.LeftToRight) | PopupAnimations.RightToLeft;\n                }\n            }\n            flags = flags | (NativeMethods.AnimationFlags.Mask & (NativeMethods.AnimationFlags)(int)_flags);\n            NativeMethods.AnimateWindow(this, AnimationDuration, flags);\n        }\n\n        /// <summary>\n        /// Processes a dialog box key.\n        /// </summary>\n        /// <param name=\"keyData\">One of the <see cref=\"T:System.Windows.Forms.Keys\" /> values that represents the key to process.</param>\n        /// <returns>\n        /// true if the key was processed by the control; otherwise, false.\n        /// </returns>\n        [UIPermission(SecurityAction.LinkDemand, Window = UIPermissionWindow.AllWindows)]\n        protected override bool ProcessDialogKey(Keys keyData)\n        {\n            if (acceptAlt && ((keyData & Keys.Alt) == Keys.Alt))\n            {\n                if ((keyData & Keys.F4) != Keys.F4)\n                {\n                    return false;\n                }\n                else\n                {\n                    this.Close();\n                }\n            }\n            bool processed = base.ProcessDialogKey(keyData);\n            if (!processed && (keyData == Keys.Tab || keyData == (Keys.Tab | Keys.Shift)))\n            {\n                bool backward = (keyData & Keys.Shift) == Keys.Shift;\n                this.Content.SelectNextControl(null, !backward, true, true, true);\n            }\n            return processed;\n        }\n\n        /// <summary>\n        /// Updates the pop-up region.\n        /// </summary>\n        protected void UpdateRegion()\n        {\n            if (this.Region != null)\n            {\n                this.Region.Dispose();\n                this.Region = null;\n            }\n            if (content.Region != null)\n            {\n                this.Region = content.Region.Clone();\n            }\n        }\n\n        /// <summary>\n        /// Shows the pop-up window below the specified control.\n        /// </summary>\n        /// <param name=\"control\">The control below which the pop-up will be shown.</param>\n        /// <remarks>\n        /// When there is no space below the specified control, the pop-up control is shown above it.\n        /// </remarks>\n        /// <exception cref=\"T:System.ArgumentNullException\"><paramref name=\"control\"/> is <code>null</code>.</exception>\n        public void Show(Control control)\n        {\n            if (control == null)\n            {\n                throw new ArgumentNullException(\"control\");\n            }\n            Show(control, control.ClientRectangle);\n        }\n\n        /// <summary>\n        /// Shows the pop-up window below the specified area of the specified control.\n        /// </summary>\n        /// <param name=\"control\">The control used to compute screen location of specified area.</param>\n        /// <param name=\"area\">The area of control below which the pop-up will be shown.</param>\n        /// <remarks>\n        /// When there is no space below specified area, the pop-up control is shown above it.\n        /// </remarks>\n        /// <exception cref=\"T:System.ArgumentNullException\"><paramref name=\"control\"/> is <code>null</code>.</exception>\n        public void Show(Control control, Rectangle area)\n        {\n            if (control == null)\n            {\n                throw new ArgumentNullException(\"control\");\n            }\n            SetOwnerItem(control);\n\n                resizableTop = resizableLeft = false;\n                Point location = control.PointToScreen(new Point(area.Left, area.Top + area.Height));\n                Rectangle screen = Screen.FromControl(control).WorkingArea;\n                if (location.X + Size.Width > (screen.Left + screen.Width))\n                {\n                    resizableLeft = true;\n                    location.X = (screen.Left + screen.Width) - Size.Width;\n                }\n                if (location.Y + Size.Height > (screen.Top + screen.Height))\n                {\n                    resizableTop = true;\n                    location.Y -= Size.Height + area.Height;\n                }\n                location = control.PointToClient(location);\n                Show(control, location, ToolStripDropDownDirection.BelowRight);\n        }\n\n        private void SetOwnerItem(Control control)\n        {\n            if (control == null)\n            {\n                return;\n            }\n            if (control is Popup)\n            {\n                Popup popupControl = control as Popup;\n                ownerPopup = popupControl;\n                ownerPopup.childPopup = this;\n                OwnerItem = popupControl.Items[0];\n                return;\n            }\n            else if (opener == null)\n            {\n                opener = control;\n            }\n            if (control.Parent != null)\n            {\n                SetOwnerItem(control.Parent);\n            }\n        }\n\n        /// <summary>\n        /// Raises the <see cref=\"E:System.Windows.Forms.Control.SizeChanged\" /> event.\n        /// </summary>\n        /// <param name=\"e\">An <see cref=\"T:System.EventArgs\" /> that contains the event data.</param>\n        protected override void OnSizeChanged(EventArgs e)\n        {\n            content.MinimumSize = Size;\n            content.MaximumSize = Size;\n            content.Size = Size;\n            content.Location = Point.Empty;\n            base.OnSizeChanged(e);\n        }\n\n        /// <summary>\n        /// Raises the <see cref=\"E:System.Windows.Forms.ToolStripDropDown.Opening\" /> event.\n        /// </summary>\n        /// <param name=\"e\">A <see cref=\"T:System.ComponentModel.CancelEventArgs\" /> that contains the event data.</param>\n        protected override void OnOpening(CancelEventArgs e)\n        {\n            if (content.IsDisposed || content.Disposing)\n            {\n                e.Cancel = true;\n                return;\n            }\n            UpdateRegion();\n            base.OnOpening(e);\n        }\n\n        /// <summary>\n        /// Raises the <see cref=\"E:System.Windows.Forms.ToolStripDropDown.Opened\" /> event.\n        /// </summary>\n        /// <param name=\"e\">An <see cref=\"T:System.EventArgs\" /> that contains the event data.</param>\n        protected override void OnOpened(EventArgs e)\n        {\n            if (ownerPopup != null)\n            {\n                ownerPopup.isChildPopupOpened = true;\n            }\n            if (focusOnOpen)\n            {\n                content.Focus();\n            }\n            base.OnOpened(e);\n        }\n\n        /// <summary>\n        /// Raises the <see cref=\"E:System.Windows.Forms.ToolStripDropDown.Closed\"/> event.\n        /// </summary>\n        /// <param name=\"e\">A <see cref=\"T:System.Windows.Forms.ToolStripDropDownClosedEventArgs\"/> that contains the event data.</param>\n        protected override void OnClosed(ToolStripDropDownClosedEventArgs e)\n        {\n            opener = null;\n            if (ownerPopup != null)\n            {\n                ownerPopup.isChildPopupOpened = false;\n            }\n            base.OnClosed(e);\n        }\n\n        #endregion\n\n        #region \" Resizing Support \"\n\n        /// <summary>\n        /// Processes Windows messages.\n        /// </summary>\n        /// <param name=\"m\">The Windows <see cref=\"T:System.Windows.Forms.Message\" /> to process.</param>\n        [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]\n        protected override void WndProc(ref Message m)\n        {\n            //if (m.Msg == NativeMethods.WM_PRINT && !Visible)\n            //{\n            //    Visible = true;\n            //}\n            if (InternalProcessResizing(ref m, false))\n            {\n                return;\n            }\n            base.WndProc(ref m);\n        }\n\n        /// <summary>\n        /// Processes the resizing messages.\n        /// </summary>\n        /// <param name=\"m\">The message.</param>\n        /// <returns>true, if the WndProc method from the base class shouldn't be invoked.</returns>\n        [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]\n        public bool ProcessResizing(ref Message m)\n        {\n            return InternalProcessResizing(ref m, true);\n        }\n\n        [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]\n        private bool InternalProcessResizing(ref Message m, bool contentControl)\n        {\n            if (m.Msg == NativeMethods.WM_NCACTIVATE && m.WParam != IntPtr.Zero && childPopup != null && childPopup.Visible)\n            {\n                childPopup.Hide();\n            }\n            if (!Resizable)\n            {\n                return false;\n            }\n            if (m.Msg == NativeMethods.WM_NCHITTEST)\n            {\n                return OnNcHitTest(ref m, contentControl);\n            }\n            else if (m.Msg == NativeMethods.WM_GETMINMAXINFO)\n            {\n                return OnGetMinMaxInfo(ref m);\n            }\n            return false;\n        }\n\n        [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]\n        private bool OnGetMinMaxInfo(ref Message m)\n        {\n            NativeMethods.MINMAXINFO minmax = (NativeMethods.MINMAXINFO)Marshal.PtrToStructure(m.LParam, typeof(NativeMethods.MINMAXINFO));\n            if (!this.MaximumSize.IsEmpty)\n            {\n                minmax.maxTrackSize = this.MaximumSize;\n            }\n            minmax.minTrackSize = this.MinimumSize;\n            Marshal.StructureToPtr(minmax, m.LParam, false);\n            return true;\n        }\n\n        private bool OnNcHitTest(ref Message m, bool contentControl)\n        {\n            int x = NativeMethods.LOWORD(m.LParam);\n            int y = NativeMethods.HIWORD(m.LParam);\n            Point clientLocation = PointToClient(new Point(x, y));\n\n            GripBounds gripBouns = new GripBounds(contentControl ? content.ClientRectangle : ClientRectangle);\n            IntPtr transparent = new IntPtr(NativeMethods.HTTRANSPARENT);\n\n            if (resizableTop)\n            {\n                if (resizableLeft && gripBouns.TopLeft.Contains(clientLocation))\n                {\n                    m.Result = contentControl ? transparent : (IntPtr)NativeMethods.HTTOPLEFT;\n                    return true;\n                }\n                if (!resizableLeft && gripBouns.TopRight.Contains(clientLocation))\n                {\n                    m.Result = contentControl ? transparent : (IntPtr)NativeMethods.HTTOPRIGHT;\n                    return true;\n                }\n                if (gripBouns.Top.Contains(clientLocation))\n                {\n                    m.Result = contentControl ? transparent : (IntPtr)NativeMethods.HTTOP;\n                    return true;\n                }\n            }\n            else\n            {\n                if (resizableLeft && gripBouns.BottomLeft.Contains(clientLocation))\n                {\n                    m.Result = contentControl ? transparent : (IntPtr)NativeMethods.HTBOTTOMLEFT;\n                    return true;\n                }\n                if (!resizableLeft && gripBouns.BottomRight.Contains(clientLocation))\n                {\n                    m.Result = contentControl ? transparent : (IntPtr)NativeMethods.HTBOTTOMRIGHT;\n                    return true;\n                }\n                if (gripBouns.Bottom.Contains(clientLocation))\n                {\n                    m.Result = contentControl ? transparent : (IntPtr)NativeMethods.HTBOTTOM;\n                    return true;\n                }\n            }\n            if (resizableLeft && gripBouns.Left.Contains(clientLocation))\n            {\n                m.Result = contentControl ? transparent : (IntPtr)NativeMethods.HTLEFT;\n                return true;\n            }\n            if (!resizableLeft && gripBouns.Right.Contains(clientLocation))\n            {\n                m.Result = contentControl ? transparent : (IntPtr)NativeMethods.HTRIGHT;\n                return true;\n            }\n            return false;\n        }\n\n        private VS.VisualStyleRenderer sizeGripRenderer;\n        /// <summary>\n        /// Paints the sizing grip.\n        /// </summary>\n        /// <param name=\"e\">The <see cref=\"System.Windows.Forms.PaintEventArgs\" /> instance containing the event data.</param>\n        public void PaintSizeGrip(PaintEventArgs e)\n        {\n            if (e == null || e.Graphics == null || !resizable)\n            {\n                return;\n            }\n            Size clientSize = content.ClientSize;\n            using (Bitmap gripImage = new Bitmap(0x10, 0x10))\n            {\n                using (Graphics g = Graphics.FromImage(gripImage))\n                {\n                    if (Application.RenderWithVisualStyles)\n                    {\n                        if (this.sizeGripRenderer == null)\n                        {\n                            this.sizeGripRenderer = new VS.VisualStyleRenderer(VS.VisualStyleElement.Status.Gripper.Normal);\n                        }\n                        this.sizeGripRenderer.DrawBackground(g, new Rectangle(0, 0, 0x10, 0x10));\n                    }\n                    else\n                    {\n                        ControlPaint.DrawSizeGrip(g, content.BackColor, 0, 0, 0x10, 0x10);\n                    }\n                }\n                GraphicsState gs = e.Graphics.Save();\n                e.Graphics.ResetTransform();\n                if (resizableTop)\n                {\n                    if (resizableLeft)\n                    {\n                        e.Graphics.RotateTransform(180);\n                        e.Graphics.TranslateTransform(-clientSize.Width, -clientSize.Height);\n                    }\n                    else\n                    {\n                        e.Graphics.ScaleTransform(1, -1);\n                        e.Graphics.TranslateTransform(0, -clientSize.Height);\n                    }\n                }\n                else if (resizableLeft)\n                {\n                    e.Graphics.ScaleTransform(-1, 1);\n                    e.Graphics.TranslateTransform(-clientSize.Width, 0);\n                }\n                e.Graphics.DrawImage(gripImage, clientSize.Width - 0x10, clientSize.Height - 0x10 + 1, 0x10, 0x10);\n                e.Graphics.Restore(gs);\n            }\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/PopupControl/PopupAnimation.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Text;\n\nnamespace Sheng.Winform.Controls.PopupControl\n{\n    /// <summary>\n    /// Types of animation of the pop-up window.\n    /// </summary>\n    [Flags]\n    public enum PopupAnimations : int\n    {\n        /// <summary>\n        /// Uses no animation.\n        /// </summary>\n        None = 0,\n        /// <summary>\n        /// Animates the window from left to right. This flag can be used with roll or slide animation.\n        /// </summary>\n        LeftToRight = 0x00001,\n        /// <summary>\n        /// Animates the window from right to left. This flag can be used with roll or slide animation.\n        /// </summary>\n        RightToLeft = 0x00002,\n        /// <summary>\n        /// Animates the window from top to bottom. This flag can be used with roll or slide animation.\n        /// </summary>\n        TopToBottom = 0x00004,\n        /// <summary>\n        /// Animates the window from bottom to top. This flag can be used with roll or slide animation.\n        /// </summary>\n        BottomToTop = 0x00008,\n        /// <summary>\n        /// Makes the window appear to collapse inward if it is hiding or expand outward if the window is showing.\n        /// </summary>\n        Center = 0x00010,\n        /// <summary>\n        /// Uses a slide animation.\n        /// </summary>\n        Slide = 0x40000,\n        /// <summary>\n        /// Uses a fade effect.\n        /// </summary>\n        Blend = 0x80000,\n        /// <summary>\n        /// Uses a roll animation.\n        /// </summary>\n        Roll = 0x100000,\n        /// <summary>\n        /// Uses a default animation.\n        /// </summary>\n        SystemDefault = 0x200000,\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/PopupControl/PopupComboBox.Designer.cs",
    "content": "﻿namespace Sheng.Winform.Controls.PopupControl\n{\n    partial class PopupComboBox\n    {\n        /// <summary>\n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing)\n            {\n                if (components != null)\n                {\n                    components.Dispose();\n                }\n                if (dropDown != null)\n                {\n                    dropDown.Dispose();\n                }\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Component Designer generated code\n\n        /// <summary>\n        /// Required method for Designer support - do not modify \n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.SuspendLayout();\n            // \n            // PopupComboBox\n            // \n            this.ResumeLayout(false);\n\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/PopupControl/PopupComboBox.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Data;\nusing System.Drawing;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Security.Permissions;\n\nnamespace Sheng.Winform.Controls.PopupControl\n{\n    /// <summary>\n    /// Represents a Windows combo box control with a custom popup control attached.\n    /// </summary>\n    [ToolboxBitmap(typeof(System.Windows.Forms.ComboBox)), ToolboxItem(true), ToolboxItemFilter(\"System.Windows.Forms\"), Description(\"Displays an editable text box with a drop-down list of permitted values.\")]\n    public partial class PopupComboBox : PopupControlComboBoxBase\n    {\n        /// <summary>\n        /// Initializes a new instance of the <see cref=\"PopupControl.PopupComboBox\" /> class.\n        /// </summary>\n        public PopupComboBox()\n        {\n            this.dropDownHideTime = DateTime.UtcNow;\n            InitializeComponent();\n            base.DropDownHeight = base.DropDownWidth = 1;\n            base.IntegralHeight = false;\n        }\n\n        private Popup dropDown;\n\n        private Control dropDownControl;\n        /// <summary>\n        /// Gets or sets the drop down control.\n        /// </summary>\n        /// <value>The drop down control.</value>\n        public Control DropDownControl\n        {\n            get\n            {\n                return dropDownControl;\n            }\n            set\n            {\n                if (dropDownControl == value)\n                {\n                    return;\n                }\n                dropDownControl = value;\n                if (dropDown != null)\n                {\n                    dropDown.Closed -= dropDown_Closed;\n                    dropDown.Dispose();\n                }\n                dropDown = new Popup(value);\n                dropDown.Closed += dropDown_Closed;\n            }\n        }\n\n        private DateTime dropDownHideTime;\n        private void dropDown_Closed(object sender, ToolStripDropDownClosedEventArgs e)\n        {\n            dropDownHideTime = DateTime.UtcNow;\n        }\n\n        /// <summary>\n        /// Gets or sets a value indicating whether the combo box is displaying its drop-down portion.\n        /// </summary>\n        /// <value></value>\n        /// <returns>true if the drop-down portion is displayed; otherwise, false. The default is false.\n        /// </returns>\n        public new bool DroppedDown\n        {\n            get\n            {\n                return dropDown.Visible;\n            }\n            set\n            {\n                if (DroppedDown)\n                {\n                    HideDropDown();\n                }\n                else\n                {\n                    ShowDropDown();\n                }\n            }\n        }\n\n        /// <summary>\n        /// Occurs when the drop-down portion of a <see cref=\"T:System.Windows.Forms.ComboBox\"/> is shown.\n        /// </summary>\n        public new event EventHandler DropDown;\n\n        /// <summary>\n        /// Shows the drop down.\n        /// </summary>\n        public void ShowDropDown()\n        {\n            if (dropDown != null)\n            {\n                if ((DateTime.UtcNow - dropDownHideTime).TotalSeconds > 0.5)\n                {\n                    if (DropDown != null)\n                    {\n                        DropDown(this, EventArgs.Empty);\n                    }\n                    dropDown.Show(this);\n                }\n                else\n                {\n                    dropDownHideTime = DateTime.UtcNow.Subtract(new TimeSpan(0, 0, 1));\n                    Focus();\n                }\n            }\n        }\n\n        /// <summary>\n        /// Occurs when the drop-down portion of the <see cref=\"T:System.Windows.Forms.ComboBox\"/> is no longer visible.\n        /// </summary>\n        public new event EventHandler DropDownClosed;\n\n        /// <summary>\n        /// Hides the drop down.\n        /// </summary>\n        public void HideDropDown()\n        {\n            if (dropDown != null)\n            {\n                dropDown.Hide();\n                if (DropDownClosed != null)\n                {\n                    DropDownClosed(this, EventArgs.Empty);\n                }\n            }\n        }\n\n        /// <summary>\n        /// Processes Windows messages.\n        /// </summary>\n        /// <param name=\"m\">The Windows <see cref=\"T:System.Windows.Forms.Message\" /> to process.</param>\n        [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]\n        protected override void WndProc(ref Message m)\n        {\n            if (m.Msg == (NativeMethods.WM_COMMAND + NativeMethods.WM_REFLECT) && NativeMethods.HIWORD(m.WParam) == NativeMethods.CBN_DROPDOWN)\n            {\n                ShowDropDown();\n                return;\n            }\n            base.WndProc(ref m);\n        }\n\n        #region \" Unused Properties \"\n\n        /// <summary>This property is not relevant for this class.</summary>\n        /// <returns>This property is not relevant for this class.</returns>\n        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never)]\n        public new int DropDownWidth\n        {\n            get { return base.DropDownWidth; }\n            set { base.DropDownWidth = value; }\n        }\n\n        /// <summary>This property is not relevant for this class.</summary>\n        /// <returns>This property is not relevant for this class.</returns>\n        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never)]\n        public new int DropDownHeight\n        {\n            get { return base.DropDownHeight; }\n            set { base.DropDownHeight = value; }\n        }\n\n        /// <summary>This property is not relevant for this class.</summary>\n        /// <returns>This property is not relevant for this class.</returns>\n        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never)]\n        public new bool IntegralHeight\n        {\n            get { return base.IntegralHeight; }\n            set { base.IntegralHeight = value; }\n        }\n\n        /// <summary>This property is not relevant for this class.</summary>\n        /// <returns>This property is not relevant for this class.</returns>\n        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never)]\n        public new ObjectCollection Items\n        {\n            get { return base.Items; }\n        }\n\n        /// <summary>This property is not relevant for this class.</summary>\n        /// <returns>This property is not relevant for this class.</returns>\n        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never)]\n        public new int ItemHeight\n        {\n            get { return base.ItemHeight; }\n            set { base.ItemHeight = value; }\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/PopupControl/PopupControlComboBoxBase.Designer.cs",
    "content": "﻿namespace Sheng.Winform.Controls.PopupControl\n{\n    partial class PopupControlComboBoxBase\n    {\n        /// <summary>\n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing)\n            {\n                if (components != null)\n                {\n                    components.Dispose();\n                }\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Component Designer generated code\n\n        /// <summary>\n        /// Required method for Designer support - do not modify \n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.SuspendLayout();\n            // \n            // ComboBox\n            // \n            this.ResumeLayout(false);\n\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/PopupControl/PopupControlComboBoxBase.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Data;\nusing System.Drawing;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Reflection;\n\nnamespace Sheng.Winform.Controls.PopupControl\n{\n    /// <summary>\n    /// Represents a Windows combo box control which can be used in a popup's content control.\n    /// </summary>\n    [ToolboxBitmap(typeof(System.Windows.Forms.ComboBox)), ToolboxItem(true), ToolboxItemFilter(\"System.Windows.Forms\"), Description(\"Displays an editable text box with a drop-down list of permitted values.\")]\n    public partial class PopupControlComboBoxBase : System.Windows.Forms.ComboBox\n    {\n        /// <summary>\n        /// Initializes a new instance of the <see cref=\"PopupControl.ComboBox\" /> class.\n        /// </summary>\n        public PopupControlComboBoxBase()\n        {\n            InitializeComponent();\n        }\n\n        private static Type _modalMenuFilter;\n        private static Type modalMenuFilter\n        {\n            get\n            {\n                if (_modalMenuFilter == null)\n                {\n                    _modalMenuFilter = Type.GetType(\"System.Windows.Forms.ToolStripManager+ModalMenuFilter\");\n                }\n                if (_modalMenuFilter == null)\n                {\n                    _modalMenuFilter = new List<Type>(typeof(ToolStripManager).Assembly.GetTypes()).Find(\n                    delegate(Type type)\n                    {\n                        return type.FullName == \"System.Windows.Forms.ToolStripManager+ModalMenuFilter\";\n                    });\n                }\n                return _modalMenuFilter;\n            }\n        }\n\n        private static MethodInfo _suspendMenuMode;\n        private static MethodInfo suspendMenuMode\n        {\n            get\n            {\n                if (_suspendMenuMode == null)\n                {\n                    Type t = modalMenuFilter;\n                    if (t != null)\n                    {\n                        _suspendMenuMode = t.GetMethod(\"SuspendMenuMode\", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);\n                    }\n                }\n                return _suspendMenuMode;\n            }\n        }\n\n        private static void SuspendMenuMode()\n        {\n            MethodInfo suspendMenuMode = PopupControlComboBoxBase.suspendMenuMode;\n            if (suspendMenuMode != null)\n            {\n                suspendMenuMode.Invoke(null, null);\n            }\n        }\n\n        private static MethodInfo _resumeMenuMode;\n        private static MethodInfo resumeMenuMode\n        {\n            get\n            {\n                if (_resumeMenuMode == null)\n                {\n                    Type t = modalMenuFilter;\n                    if (t != null)\n                    {\n                        _resumeMenuMode = t.GetMethod(\"ResumeMenuMode\", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);\n                    }\n                }\n                return _resumeMenuMode;\n            }\n        }\n\n        private static void ResumeMenuMode()\n        {\n            MethodInfo resumeMenuMode = PopupControlComboBoxBase.resumeMenuMode;\n            if (resumeMenuMode != null)\n            {\n                resumeMenuMode.Invoke(null, null);\n            }\n        }\n\n        /// <summary>\n        /// Raises the <see cref=\"E:System.Windows.Forms.ComboBox.DropDown\" /> event.\n        /// </summary>\n        /// <param name=\"e\">An <see cref=\"T:System.EventArgs\" /> that contains the event data.</param>\n        protected override void OnDropDown(EventArgs e)\n        {\n            base.OnDropDown(e);\n            SuspendMenuMode();\n        }\n\n        /// <summary>\n        /// Raises the <see cref=\"E:System.Windows.Forms.ComboBox.DropDownClosed\" /> event.\n        /// </summary>\n        /// <param name=\"e\">An <see cref=\"T:System.EventArgs\" /> that contains the event data.</param>\n        protected override void OnDropDownClosed(EventArgs e)\n        {\n            ResumeMenuMode();\n            base.OnDropDownClosed(e);\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// 有关程序集的常规信息通过下列属性集\n// 控制。更改这些属性值可修改\n// 与程序集关联的信息。\n[assembly: AssemblyTitle(\"SEControl\")]\n[assembly: AssemblyDescription(\"\")]\n\n// 将 ComVisible 设置为 false 使此程序集中的类型\n// 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型，\n// 则将该类型上的 ComVisible 属性设置为 true。\n[assembly: ComVisible(false)]\n\n// 如果此项目向 COM 公开，则下列 GUID 用于类型库的 ID\n[assembly: Guid(\"0e6ad4d2-2f6b-4055-bd0a-608c2d25c756\")]\n\n// 程序集的版本信息由下面四个值组成:\n//\n//      主版本\n//      次版本 \n//      内部版本号\n//      修订号\n//\n// 可以指定所有这些值，也可以使用“修订号”和“内部版本号”的默认值，\n// 方法是按如下所示使用“*”:\n[assembly: AssemblyVersion(\"1.0.*\")]\n"
  },
  {
    "path": "Sheng.Winform.Controls/Properties/Resources.Designer.cs",
    "content": "﻿//------------------------------------------------------------------------------\r\n// <auto-generated>\r\n//     此代码由工具生成。\r\n//     运行时版本:4.0.30319.42000\r\n//\r\n//     对此文件的更改可能会导致不正确的行为，并且如果\r\n//     重新生成代码，这些更改将会丢失。\r\n// </auto-generated>\r\n//------------------------------------------------------------------------------\r\n\r\nnamespace Sheng.Winform.Controls.Properties {\r\n    using System;\r\n    \r\n    \r\n    /// <summary>\r\n    ///   一个强类型的资源类，用于查找本地化的字符串等。\r\n    /// </summary>\r\n    // 此类是由 StronglyTypedResourceBuilder\r\n    // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。\r\n    // 若要添加或移除成员，请编辑 .ResX 文件，然后重新运行 ResGen\r\n    // (以 /str 作为命令选项)，或重新生成 VS 项目。\r\n    [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Resources.Tools.StronglyTypedResourceBuilder\", \"4.0.0.0\")]\r\n    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\r\n    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]\r\n    internal class Resources {\r\n        \r\n        private static global::System.Resources.ResourceManager resourceMan;\r\n        \r\n        private static global::System.Globalization.CultureInfo resourceCulture;\r\n        \r\n        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"Microsoft.Performance\", \"CA1811:AvoidUncalledPrivateCode\")]\r\n        internal Resources() {\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   返回此类使用的缓存的 ResourceManager 实例。\r\n        /// </summary>\r\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\r\n        internal static global::System.Resources.ResourceManager ResourceManager {\r\n            get {\r\n                if (object.ReferenceEquals(resourceMan, null)) {\r\n                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager(\"Sheng.Winform.Controls.Properties.Resources\", typeof(Resources).Assembly);\r\n                    resourceMan = temp;\r\n                }\r\n                return resourceMan;\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   使用此强类型资源类，为所有资源查找\r\n        ///   重写当前线程的 CurrentUICulture 属性。\r\n        /// </summary>\r\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\r\n        internal static global::System.Globalization.CultureInfo Culture {\r\n            get {\r\n                return resourceCulture;\r\n            }\r\n            set {\r\n                resourceCulture = value;\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\r\n        /// </summary>\r\n        internal static System.Drawing.Bitmap Check {\r\n            get {\r\n                object obj = ResourceManager.GetObject(\"Check\", resourceCulture);\r\n                return ((System.Drawing.Bitmap)(obj));\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\r\n        /// </summary>\r\n        internal static System.Drawing.Bitmap Folder {\r\n            get {\r\n                object obj = ResourceManager.GetObject(\"Folder\", resourceCulture);\r\n                return ((System.Drawing.Bitmap)(obj));\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\r\n        /// </summary>\r\n        internal static System.Drawing.Bitmap FolderClosed {\r\n            get {\r\n                object obj = ResourceManager.GetObject(\"FolderClosed\", resourceCulture);\r\n                return ((System.Drawing.Bitmap)(obj));\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\r\n        /// </summary>\r\n        internal static System.Drawing.Bitmap Leaf {\r\n            get {\r\n                object obj = ResourceManager.GetObject(\"Leaf\", resourceCulture);\r\n                return ((System.Drawing.Bitmap)(obj));\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\r\n        /// </summary>\r\n        internal static System.Drawing.Bitmap Minus2 {\r\n            get {\r\n                object obj = ResourceManager.GetObject(\"Minus2\", resourceCulture);\r\n                return ((System.Drawing.Bitmap)(obj));\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\r\n        /// </summary>\r\n        internal static System.Drawing.Bitmap Plus2 {\r\n            get {\r\n                object obj = ResourceManager.GetObject(\"Plus2\", resourceCulture);\r\n                return ((System.Drawing.Bitmap)(obj));\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\r\n        /// </summary>\r\n        internal static System.Drawing.Bitmap Uncheck {\r\n            get {\r\n                object obj = ResourceManager.GetObject(\"Uncheck\", resourceCulture);\r\n                return ((System.Drawing.Bitmap)(obj));\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\r\n        /// </summary>\r\n        internal static System.Drawing.Bitmap Unknown {\r\n            get {\r\n                object obj = ResourceManager.GetObject(\"Unknown\", resourceCulture);\r\n                return ((System.Drawing.Bitmap)(obj));\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "Sheng.Winform.Controls/Properties/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <assembly alias=\"System.Windows.Forms\" name=\"System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\" />\n  <data name=\"Check\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>..\\Resources\\Check.bmp;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"Folder\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>..\\Resources\\Folder.bmp;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"FolderClosed\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>..\\Resources\\FolderClosed.bmp;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"Leaf\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>..\\Resources\\Leaf.bmp;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"Minus2\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>..\\Resources\\Minus2.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"Plus2\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>..\\Resources\\Plus2.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"Uncheck\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>..\\Resources\\Uncheck.bmp;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"Unknown\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>..\\Resources\\Unknown.bmp;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n</root>"
  },
  {
    "path": "Sheng.Winform.Controls/Renderer/Office2010Renderer.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Drawing;\nusing System.Drawing.Drawing2D;\n\nnamespace Sheng.Winform.Controls\n{\n    public static class Office2010Renderer\n    {\n        public static Brush CreateDisabledBackgroundBrush(Rectangle bounds, Color baseColor)\n        {\n            Color color = Color.FromArgb(75, baseColor);\n            SolidBrush brush = new SolidBrush(color);\n            return brush;\n        }\n\n        public static Brush CreateBackgroundBrush(Rectangle bounds, Color baseColor)\n        {\n            Color color = baseColor;\n\n            Color[] colors = new Color[3];\n            colors[0] = Color.Transparent;\n            colors[1] = Color.Transparent;\n            colors[2] = Color.FromArgb(60, color);\n\n            //要向上移一个像素，否则上面会多出一个像素的空白，原因不明\n            //bounds.X -= 1;\n            //bounds.Y -= 1;\n\n            LinearGradientBrush brush = new LinearGradientBrush(bounds, Color.Empty, Color.Empty,\n                LinearGradientMode.Vertical);\n\n            //渐变位置百分比\n            float[] relativePositions = { 0f, 0.75f, 1f, };\n\n            ColorBlend colorBlend = new ColorBlend();\n            colorBlend.Colors = colors;\n            colorBlend.Positions = relativePositions;\n            brush.InterpolationColors = colorBlend;\n\n            return brush;\n        }\n\n        public static Brush CreateBorderBrush(Rectangle bounds, Color baseColor)\n        {\n            Color color = baseColor;\n            Color colorStart = Color.FromArgb(125, color);\n\n            LinearGradientBrush brush = new LinearGradientBrush(bounds, colorStart, color,\n                LinearGradientMode.Vertical);\n\n            return brush;\n        }\n\n        public static Brush CreateHoveredBackgroundBrush(Rectangle bounds, Color baseColor)\n        {\n            //过渡色的路径点和配色参见png设计图\n            //需要五个过度色点，就是分成四段，分别占34%,33%,16%,17%\n\n            Color color = baseColor;\n\n            Color[] colors = new Color[5];\n            colors[0] = Color.FromArgb(125, color);\n            colors[1] = color;\n            colors[2] = color;\n            colors[3] = Color.FromArgb(221, color);\n            colors[4] = Color.Transparent;\n\n            //要向上移一个像素，否则上面会多出一个像素的空白，原因不明\n            bounds.X -= 1;\n            bounds.Y -= 1;\n\n            LinearGradientBrush brush = new LinearGradientBrush(bounds, Color.Empty, Color.Empty,\n                LinearGradientMode.Vertical);\n\n            //渐变位置百分比\n            float[] relativePositions = { 0f, 0.20f, 0.67f, 0.75f, 1f, };\n\n            ColorBlend colorBlend = new ColorBlend();\n            colorBlend.Colors = colors;\n            colorBlend.Positions = relativePositions;\n            brush.InterpolationColors = colorBlend;\n\n            return brush;\n        }\n\n        public static Brush CreateHoveredBorderBrush(Rectangle bounds, Color baseColor)\n        {\n            Color color = baseColor;\n\n            Color colorEnd = Color.FromArgb(125, color);\n\n            LinearGradientBrush brush = new LinearGradientBrush(bounds, color, colorEnd,\n                LinearGradientMode.Vertical);\n\n            return brush;\n        }\n\n        public static Brush CreateSelectedBackgroundBrush(Rectangle bounds, Color baseColor)\n        {\n            //过渡色的路径点和配色参见png设计图\n            //需要五个过度色点，就是分成四段，分别占34%,33%,16%,17%\n\n            Color color = baseColor;\n\n            Color[] colors = new Color[5];\n            colors[0] = color;\n            colors[1] = color;\n            colors[2] = color;\n            colors[3] = Color.FromArgb(221, color);\n            colors[4] = Color.Transparent;\n\n            //要向上移一个像素，否则上面会多出一个像素的空白，原因不明\n            //bounds.X -= 1;\n            //bounds.Y -= 1;\n\n            LinearGradientBrush brush = new LinearGradientBrush(bounds, Color.Empty, Color.Empty,\n                LinearGradientMode.Vertical);\n\n            //渐变位置百分比\n            float[] relativePositions = { 0f, 0.30f, 0.67f, 0.75f, 1f };\n\n            ColorBlend colorBlend = new ColorBlend();\n            colorBlend.Colors = colors;\n            colorBlend.Positions = relativePositions;\n            brush.InterpolationColors = colorBlend;\n\n            return brush;\n        }\n\n        public static Brush CreateSelectedBorderBrush(Rectangle bounds, Color baseColor)\n        {\n            Color color = baseColor;\n\n            Color colorEnd = Color.FromArgb(125, color);\n\n            LinearGradientBrush brush = new LinearGradientBrush(bounds, color, colorEnd,\n                LinearGradientMode.Vertical);\n\n            return brush;\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/Renderer/SEToolStripProfessionalRenderer_Gary.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Drawing;\nusing System.Drawing.Drawing2D;\nusing System.Windows.Forms;\n\nnamespace Sheng.Winform.Controls\n{\n    /// <summary>\n    /// 白色到灰色的垂直渐变\n    /// </summary>\n    public class SEToolStripProfessionalRenderer_Gary : ToolStripProfessionalRenderer\n    {\n        static SEToolStripProfessionalRenderer_Gary()\n        {\n\n        }\n\n        public SEToolStripProfessionalRenderer_Gary()\n        {\n        }\n\n        //// This method handles the RenderGrip event.\n        //protected override void OnRenderGrip(ToolStripGripRenderEventArgs e)\n        //{\n        //    DrawTitleBar(\n        //        e.Graphics,\n        //        new Rectangle(0, 0, e.ToolStrip.Width, 7));\n        //}\n\n        //// This method handles the RenderToolStripBorder event.\n        protected override void OnRenderToolStripBorder(ToolStripRenderEventArgs e)\n        {\n            e.Graphics.DrawLine(new Pen(Color.FromArgb(163, 163, 124)), 0, e.ToolStrip.Height, e.ToolStrip.Width, e.ToolStrip.Height);\n        }\n\n        protected override void OnRenderToolStripBackground(ToolStripRenderEventArgs e)\n        {\n            //DrawTitleBar(\n            //    e.Graphics,\n            //    new Rectangle(0, 0, e.ToolStrip.Width, e.ToolStrip.Height));\n\n            if (e.ToolStrip.GetType().Name == \"ToolStrip\")\n            {\n                LinearGradientBrush brush = new LinearGradientBrush\n                    (new Point(0, 0), new Point(0, e.ToolStrip.Height), Color.White, Color.FromArgb(230, 225, 202));\n\n                e.Graphics.FillRectangle(brush, new Rectangle(0, 0, e.ToolStrip.Width, e.ToolStrip.Height));\n\n                brush.Dispose();\n            }\n            else\n            {\n                //如果不是工具栏本身,比如下拉菜单什么的,就调默认的绘制背景\n                base.OnRenderToolStripBackground(e);\n            }\n        }\n\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/Renderer/SEToolStripRender.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Collections;\nusing System.ComponentModel;\nusing System.Drawing;\nusing System.Drawing.Drawing2D;\nusing System.Drawing.Imaging;\nusing System.Data;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Threading;\n\nnamespace Sheng.Winform.Controls\n{\n    #region \"EasyRender based renderer class\"\n    /// <summary>\n    /// A ToolstripManager rendering class with advanced control features\n    /// </summary>\n    public class SEToolStripRender : ToolStripProfessionalRenderer\n    {\n        #region \"Initialization and Setup\"\n\n        /// <summary>\n        /// Creates a new EasyRender class for modifications\n        /// </summary>\n        public SEToolStripRender()\n        {\n            _tsManager = new IToolstrip();\n            _btnManager = new IButton();\n            _dBtnManager = new IDropDownButton();\n            _tsCtrlManager = new IToolstripControls();\n            _pManager = new IPanel();\n            _sBtnManager = new ISplitButton();\n            _sBarManager = new IStatusBar();\n            _mnuManager = new IMenustrip();\n        }\n\n        #endregion\n\n        #region \"Private variables\"\n\n        private IToolstrip _tsManager = null;\n        private IButton _btnManager = null;\n        private IToolstripControls _tsCtrlManager = null;\n        private IPanel _pManager = null;\n        private ISplitButton _sBtnManager = null;\n        private IStatusBar _sBarManager = null;\n        private IMenustrip _mnuManager = null;\n        private IDropDownButton _dBtnManager = null;\n\n        protected Boolean _smoothText = true;\n        protected Color _overrideColor = Color.FromArgb(47, 92, 150);\n        protected Boolean _overrideText = true;\n\n        #endregion\n\n        #region \"Properties\"\n\n        /// <summary>\n        /// Gets the manager to edit and change the appearance of the Toolstrip\n        /// </summary>\n        [ReadOnly(true)]\n        public IToolstrip Toolstrip\n        {\n            get\n            {\n                return _tsManager;\n            }\n        }\n\n        /// <summary>\n        /// Gets the manager to edit and change the appearance of Toolstrip buttons\n        /// </summary>\n        [ReadOnly(true)]\n        public IButton ToolstripButton\n        {\n            get\n            {\n                return _btnManager;\n            }\n        }\n\n        /// <summary>\n        /// Gets the manager to edit and change the appearance of other Toolstrip controls\n        /// </summary>\n        [ReadOnly(true)]\n        public IToolstripControls ToolstripControls\n        {\n            get { return _tsCtrlManager; }\n        }\n\n        /// <summary>\n        /// Gets the manager to edit and change the appearance of the Panels\n        /// </summary>\n        [ReadOnly(true)]\n        public IPanel Panels\n        {\n            get { return _pManager; }\n        }\n\n        /// <summary>\n        /// Gets the manager to edit and change the appearance of the Toolstrip split buttons\n        /// </summary>\n        [ReadOnly(true)]\n        public ISplitButton SplitButton\n        {\n            get { return _sBtnManager; }\n        }\n\n        /// <summary>\n        /// Gets the manager to edit and change the appearance of the Status-bar\n        /// </summary>\n        [ReadOnly(true)]\n        public IStatusBar StatusBar\n        {\n            get { return _sBarManager; }\n        }\n\n        /// <summary>\n        /// Gets or sets whether to smooth the font text on all controls\n        /// </summary>\n        public Boolean SmoothText\n        {\n            get { return _smoothText; }\n            set { _smoothText = value; }\n        }\n\n        /// <summary>\n        /// Gets or sets the color of the text if the AlterColor is set to true\n        /// </summary>\n        public Color OverrideColor\n        {\n            get { return _overrideColor; }\n            set { _overrideColor = value; }\n        }\n\n        /// <summary>\n        /// Gets or sets whether to override the font-color on all controls\n        /// </summary>\n        public Boolean AlterColor\n        {\n            get { return _overrideText; }\n            set { _overrideText = value; }\n        }\n\n        #endregion\n\n        #region \"Important -- Functions for getting drawing pointers\"\n\n        #region \"CreatePanelBrush -- Gets a brush based on the docking position of a panel\"\n        /*\n\t\t/// <summary>\n\t\t/// Gets a brush dependent on the dock style of a panel\n\t\t/// </summary>\n\t\t/// <param name=\"Panel\">The panel which is docked</param>\n\t\t/// <returns></returns>\n\t\tprivate Brush CreatePanelBrush(ToolStripPanel Panel)\n\t\t{\n\t\t\tswitch (Panel.Dock)\n\t\t\t{\n\t\t\t\tcase DockStyle.Top: return new SolidBrush(ContentPanelTop);\n\t\t\t\tcase DockStyle.Bottom: return new SolidBrush(ContentPanelBottom);\n\t\t\t\tcase DockStyle.Left:\n\t\t\t\tcase DockStyle.Right:\n\t\t\t\t\treturn new LinearGradientBrush(Panel.ClientRectangle, ContentPanelTop, ContentPanelBottom, 90f);\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\t\t */\n        #endregion\n\n        #region \"CreateDrawingPath -- Gets a path based on a rectangular area and a provided curve value\"\n        /// <summary>\n        /// Creates a GraphicsPath that appreciates an area where things can be drawn\n        /// </summary>\n        /// <param name=\"Area\">The rectangular area which will serve as the base</param>\n        /// <param name=\"Curve\">The curve amount of the corners</param>\n        /// <returns></returns>\n        private GraphicsPath CreateDrawingPath(Rectangle Area, float Curve)\n        {\n            GraphicsPath Result = new GraphicsPath();\n\n            Result.AddLine(Area.Left + Curve, Area.Top, Area.Right - Curve, Area.Top); // Top\n            Result.AddLine(Area.Right - Curve, Area.Top, Area.Right, Area.Top + Curve); // Top-right\n            Result.AddLine(Area.Right, Area.Top + Curve, Area.Right, Area.Bottom - Curve); // Right\n            Result.AddLine(Area.Right, Area.Bottom - Curve, Area.Right - Curve, Area.Bottom); // Bottom-right\n            Result.AddLine(Area.Right - Curve, Area.Bottom, Area.Left + Curve, Area.Bottom); // Bottom\n            Result.AddLine(Area.Left + Curve, Area.Bottom, Area.Left, Area.Bottom - Curve); // Bottom-left\n            Result.AddLine(Area.Left, Area.Bottom - Curve, Area.Left, Area.Top + Curve); // Left\n            Result.AddLine(Area.Left, Area.Top + Curve, Area.Left + Curve, Area.Top); // Top-left\n\n            return Result;\n        }\n        #endregion\n\n        #region \"CreateTrianglePath -- Gets a path based on a rectangle boundary as a triangle shape\"\n        /// <summary>\n        /// Creates a triangle based on the size and bounds sectors\n        /// </summary>\n        /// <param name=\"Bounds\">The area which the triangle is confined to</param>\n        /// <param name=\"Size\">The size of the triangle</param>\n        /// <param name=\"Direction\">The direction which the triangle is pointing</param>\n        /// <returns></returns>\n        private GraphicsPath CreateTrianglePath(Rectangle Bounds, Int32 Size, ArrowDirection Direction)\n        {\n            GraphicsPath Result = new GraphicsPath();\n            int x, y, c, j;\n\n            if (Direction == ArrowDirection.Left || Direction == ArrowDirection.Right)\n            {\n                x = Bounds.Right - (Bounds.Width - Size) / 2;\n                y = Bounds.Y + Bounds.Height / 2;\n                c = Size;\n                j = 0;\n            }\n            else\n            {\n                x = Bounds.X + Bounds.Width / 2;\n                y = Bounds.Bottom - ((Bounds.Height - (Size - 1)) / 2);\n                c = Size - 1;\n                j = Size - 2;\n            }\n\n            switch (Direction)\n            {\n                case ArrowDirection.Right:\n                    Result.AddLine(x, y, x - c, y - c);\n                    Result.AddLine(x - c, y - c, x - c, y + c);\n                    Result.AddLine(x - c, y + c, x, y);\n                    break;\n                case ArrowDirection.Down:\n                    Result.AddLine(x + j, y - j, x - j, y - j);\n                    Result.AddLine(x - j, y - j, x, y);\n                    Result.AddLine(x, y, x + j, y - j);\n                    break;\n                case ArrowDirection.Left:\n                    Result.AddLine(x - c, y, x, y - c);\n                    Result.AddLine(x, y - c, x, y + c);\n                    Result.AddLine(x, y + c, x - c, y);\n                    break;\n            }\n\n            return Result;\n        }\n        #endregion\n\n        #region \"GetButtonBackColor -- Returns different background gradient colors for a normal button state\"\n        /// <summary>\n        /// Gets a color array based on the state of a normal button\n        /// </summary>\n        /// <param name=\"Item\">The button to check the state of</param>\n        /// <returns></returns>\n        private Color[] GetButtonBackColor(ToolStripButton Item, ButtonType Type)\n        {\n            Color[] Return = new Color[2];\n\n            if (\n                (!Item.Selected) &&\n                (!Item.Pressed && !Item.Checked)\n                )\n            {\n                Return[0] = Color.Transparent;\n                Return[1] = Color.Transparent;\n            }\n            else if (\n                (Item.Selected) &&\n                (!Item.Pressed && !Item.Checked)\n                )\n            {\n                Return[0] = _btnManager.HoverBackgroundTop;\n                Return[1] = _btnManager.HoverBackgroundBottom;\n            }\n            else\n            {\n                Return[0] = _btnManager.ClickBackgroundTop;\n                Return[1] = _btnManager.ClickBackgroundBottom;\n            }\n\n            return Return;\n        }\n        #endregion\n\n        #region \"GetButtonBackColor -- Returns different background gradient colors for a split-button state\"\n        /// <summary>\n        /// Gets a color array based on the state of a split-button\n        /// </summary>\n        /// <param name=\"Item\">The button to check the state of</param>\n        /// <returns></returns>\n        private Color[] GetButtonBackColor(ToolStripSplitButton Item, ButtonType Type)\n        {\n            Color[] Return = new Color[2];\n\n            if (\n                (!Item.Selected) &&\n                (!Item.ButtonPressed && !Item.DropDownButtonPressed)\n                )\n            {\n                Return[0] = Color.Transparent;\n                Return[1] = Color.Transparent;\n            }\n            else if (\n                (Item.Selected) &&\n                (!Item.ButtonPressed && !Item.DropDownButtonPressed)\n                )\n            {\n                Return[0] = _sBtnManager.HoverBackgroundTop;\n                Return[1] = _sBtnManager.HoverBackgroundBottom;\n            }\n            else\n            {\n                if (Item.ButtonPressed)\n                {\n                    Return[0] = _sBtnManager.ClickBackgroundTop;\n                    Return[1] = _sBtnManager.ClickBackgroundBottom;\n                }\n                else if (Item.DropDownButtonPressed)\n                {\n                    Return[0] = _mnuManager.MenustripButtonBackground;\n                    Return[1] = _mnuManager.MenustripButtonBackground;\n                }\n            }\n\n            return Return;\n        }\n        #endregion\n\n        #region \"GetButtonBackColor -- Returns different background gradient colors for a menu-item state\"\n        /// <summary>\n        /// Gets a color array based on the state of a menu-item\n        /// </summary>\n        /// <param name=\"Item\">The button to check the state of</param>\n        /// <returns></returns>\n        private Color[] GetButtonBackColor(ToolStripMenuItem Item, ButtonType Type)\n        {\n            Color[] Return = new Color[2];\n\n            if (\n                (!Item.Selected) &&\n                (!Item.Pressed && !Item.Checked)\n                )\n            {\n                Return[0] = Color.Transparent;\n                Return[1] = Color.Transparent;\n            }\n            else if (\n                (Item.Selected || Item.Pressed) &&\n                (!Item.Checked)\n                )\n            {\n                if (Item.Pressed && Item.OwnerItem == null)\n                {\n                    Return[0] = _mnuManager.MenustripButtonBackground;\n                    Return[1] = _mnuManager.MenustripButtonBackground;\n                }\n                else\n                {\n                    Return[0] = _mnuManager.Items.HoverBackgroundTop;\n                    Return[1] = _mnuManager.Items.HoverBackgroundBottom;\n                }\n            }\n            else\n            {\n                Return[0] = _mnuManager.Items.ClickBackgroundTop;\n                Return[1] = _mnuManager.Items.ClickBackgroundBottom;\n            }\n\n            return Return;\n        }\n        #endregion\n\n        #region \"GetButtonBackColor -- Returns different background gradient colors for a dropdownbutton state\"\n        /// <summary>\n        /// Gets a color array based on the state of a drop-down button\n        /// </summary>\n        /// <param name=\"Item\">The button to check the state of</param>\n        /// <returns></returns>\n        private Color[] GetButtonBackColor(ToolStripDropDownButton Item, ButtonType Type)\n        {\n            Color[] Return = new Color[2];\n\n            if (\n                (!Item.Selected) &&\n                (!Item.Pressed)\n                )\n            {\n                Return[0] = Color.Transparent;\n                Return[1] = Color.Transparent;\n            }\n            else if (\n                (Item.Selected) &&\n                (!Item.Pressed)\n                )\n            {\n                Return[0] = _dBtnManager.HoverBackgroundTop;\n                Return[1] = _dBtnManager.HoverBackgroundBottom;\n            }\n            else\n            {\n                Return[0] = _mnuManager.MenustripButtonBackground;\n                Return[1] = _mnuManager.MenustripButtonBackground;\n            }\n\n            return Return;\n        }\n        #endregion\n\n        #region \"GetBlend -- Gets a blend property based on the blending options and current state\"\n        /// <summary>\n        /// Gets a blending property for a specified type of Toolstrip item\n        /// </summary>\n        /// <param name=\"TSItem\">The Toolstrip item</param>\n        /// <param name=\"Type\">The type of item this is</param>\n        /// <returns></returns>\n        private Blend GetBlend(ToolStripItem TSItem, ButtonType Type)\n        {\n            Blend BackBlend = null;\n\n            if (Type == ButtonType.NormalButton)\n            {\n                ToolStripButton Item = (ToolStripButton)TSItem;\n\n                if (Item.Selected &&\n                    (!Item.Checked && !Item.Pressed) &&\n                    (_btnManager.BlendOptions & BlendRender.Hover) == BlendRender.Hover)\n                {\n                    BackBlend = _btnManager.BackgroundBlend;\n                }\n                else if (Item.Pressed &&\n                        (!Item.Checked) &&\n                        (_btnManager.BlendOptions & BlendRender.Click) == BlendRender.Click)\n                {\n                    BackBlend = _btnManager.BackgroundBlend;\n                }\n                else if (Item.Checked &&\n                        (_btnManager.BlendOptions & BlendRender.Check) == BlendRender.Check)\n                {\n                    BackBlend = _btnManager.BackgroundBlend;\n                }\n            }\n            if (Type == ButtonType.DropDownButton)\n            {\n                ToolStripDropDownButton Item = (ToolStripDropDownButton)TSItem;\n\n                if (Item.Selected &&\n                    (!Item.Pressed) &&\n                    (_btnManager.BlendOptions & BlendRender.Hover) == BlendRender.Hover)\n                {\n                    BackBlend = _btnManager.BackgroundBlend;\n                }\n            }\n            else if (Type == ButtonType.MenuItem)\n            {\n                ToolStripMenuItem Item = (ToolStripMenuItem)TSItem;\n\n                if (Item.Selected &&\n                    (!Item.Checked && !Item.Pressed) &&\n                    (_btnManager.BlendOptions & BlendRender.Hover) == BlendRender.Hover)\n                {\n                    BackBlend = _mnuManager.Items.BackgroundBlend;\n                }\n                else if (Item.Pressed &&\n                        (!Item.Checked) &&\n                        (_btnManager.BlendOptions & BlendRender.Click) == BlendRender.Click)\n                {\n                    BackBlend = _mnuManager.Items.BackgroundBlend;\n                }\n                else if (Item.Checked &&\n                        (_btnManager.BlendOptions & BlendRender.Check) == BlendRender.Check)\n                {\n                    BackBlend = _mnuManager.Items.BackgroundBlend;\n                }\n            }\n            else if (Type == ButtonType.SplitButton)\n            {\n                ToolStripSplitButton Item = (ToolStripSplitButton)TSItem;\n\n                if (Item.Selected &&\n                    (!Item.ButtonPressed && !Item.DropDownButtonPressed) &&\n                    (_sBtnManager.BlendOptions & BlendRender.Hover) == BlendRender.Hover)\n                {\n                    BackBlend = _sBtnManager.BackgroundBlend;\n                }\n                else if (Item.ButtonPressed &&\n                        (!Item.DropDownButtonPressed) &&\n                        (_sBtnManager.BlendOptions & BlendRender.Click) == BlendRender.Click)\n                {\n                    BackBlend = _sBtnManager.BackgroundBlend;\n                }\n            }\n\n            return BackBlend;\n        }\n        #endregion\n\n        #endregion\n\n        #region \"Important -- Functions for drawing\"\n\n        #region \"PaintBackground -- Simply fills a rectangle with a color\"\n        /// <summary>\n        /// Fills a specified boundary with color\n        /// </summary>\n        /// <param name=\"Link\">The Graphics object to draw onto</param>\n        /// <param name=\"Boundary\">The boundaries to draw the color</param>\n        /// <param name=\"Brush\">The brush to fill the color</param>\n        public void PaintBackground(Graphics Link, Rectangle Boundary, Brush Brush)\n        {\n            Link.FillRectangle(Brush, Boundary);\n        }\n        #endregion\n\n        #region \"PaintBackground -- Fills a rectangle with Top and Bottom colors\"\n        /// <summary>\n        /// Fills a specified boundary with a gradient with specified colors\n        /// </summary>\n        /// <param name=\"Link\">The Graphics object to draw onto</param>\n        /// <param name=\"Boundary\">The boundaries to draw the color</param>\n        /// <param name=\"Top\">The color of the gradient at the top</param>\n        /// <param name=\"Bottom\">The color of the gradient at the bottom</param>\n        public void PaintBackground(Graphics Link, Rectangle Boundary, Color Top, Color Bottom)\n        {\n            PaintBackground(Link, Boundary, Top, Bottom, 90f, null);\n        }\n        #endregion\n\n        #region \"PaintBackground -- Fills a rectangle with Top and Bottom colors at a given angle\"\n        /// <summary>\n        /// Fills a specified boundary with a gradient with specified colors at a given angle\n        /// </summary>\n        /// <param name=\"Link\">The Graphics object to draw onto</param>\n        /// <param name=\"Boundary\">The boundaries to draw the color</param>\n        /// <param name=\"Top\">The color of the gradient at the top</param>\n        /// <param name=\"Bottom\">The color of the gradient at the bottom</param>\n        /// <param name=\"Angle\">The angle which the gradient is drawn (null defaults to 90f)</param>\n        public void PaintBackground(Graphics Link, Rectangle Boundary, Color Top, Color Bottom, float Angle)\n        {\n            PaintBackground(Link, Boundary, Top, Bottom, Angle, null);\n        }\n        #endregion\n\n        #region \"PaintBackground -- Fills a rectangle with Top and Bottom colors at a given angle with blending\"\n        /// <summary>\n        /// Fills a specified boundary with a gradient with specified colors at a given angle and with blending properties\n        /// </summary>\n        /// <param name=\"Link\">The Graphics object to draw onto</param>\n        /// <param name=\"Boundary\">The boundaries to draw the color</param>\n        /// <param name=\"Top\">The color of the gradient at the top</param>\n        /// <param name=\"Bottom\">The color of the gradient at the bottom</param>\n        /// <param name=\"Angle\">The angle which the gradient is drawn (null defaults to 90f)</param>\n        /// <param name=\"Blend\">The blending options to draw the gradient</param>\n        public void PaintBackground(Graphics Link, Rectangle Boundary, Color Top, Color Bottom, float Angle, Blend Blend)\n        {\n            if ( float.IsNaN(Angle))\n            {\n                Angle = 90f;\n            }\n\n            using (LinearGradientBrush Fill = new LinearGradientBrush(Boundary, Top, Bottom, Angle))\n            {\n                if (Blend != null)\n                {\n                    Fill.Blend = Blend;\n                }\n\n                Link.FillRectangle(Fill, Boundary);\n                Fill.Dispose();\n            }\n        }\n        #endregion\n\n        #region \"PaintBorder -- Draws a border along a set path\"\n        /// <summary>\n        /// Draws a set path with a defined brush\n        /// </summary>\n        /// <param name=\"Link\">The Graphics object to draw onto</param>\n        /// <param name=\"Path\">The path to draw along</param>\n        /// <param name=\"Brush\">The brush to fill the color</param>\n        public void PaintBorder(Graphics Link, GraphicsPath Path, Brush Brush)\n        {\n            Link.DrawPath(new Pen(Brush), Path);\n        }\n        #endregion\n\n        #region \"PaintBorder -- Draws a border along a set path with Top and Bottom colors\"\n        /// <summary>\n        /// Draws a set path with specified colors\n        /// </summary>\n        /// <param name=\"Link\">The Graphics object to draw onto</param>\n        /// <param name=\"Path\">The path to draw along</param>\n        /// <param name=\"Area\">The area of span the border gradient covers</param>\n        /// <param name=\"Top\">The color of the gradient at the top</param>\n        /// <param name=\"Bottom\">The color of the gradient at the bottom</param>\n        public void PaintBorder(Graphics Link, GraphicsPath Path, Rectangle Area, Color Top, Color Bottom)\n        {\n            PaintBorder(Link, Path, Area, Top, Bottom, 90f, null);\n        }\n        #endregion\n\n        #region \"PaintBorder -- Draws a border along a set path with Top and Bottom colors at a given angle\"\n        /// <summary>\n        /// Draws a set path with specified colors at a given angle\n        /// </summary>\n        /// <param name=\"Link\">The Graphics object to draw onto</param>\n        /// <param name=\"Path\">The path to draw along</param>\n        /// <param name=\"Area\">The area of span the border gradient covers</param>\n        /// <param name=\"Top\">The color of the gradient at the top</param>\n        /// <param name=\"Bottom\">The color of the gradient at the bottom</param>\n        /// <param name=\"Angle\">The angle which the gradient is drawn (null defaults to 90f)</param>\n        public void PaintBorder(Graphics Link, GraphicsPath Path, Rectangle Area, Color Top, Color Bottom, float Angle)\n        {\n            PaintBorder(Link, Path, Area, Top, Bottom, Angle, null);\n        }\n        #endregion\n\n        #region \"PaintBorder -- Draws a border along a set path with Top and Bottom colors at a given angle with blending\"\n        /// <summary>\n        /// Draws a set path with specified colors at a given angle with blending properties\n        /// </summary>\n        /// <param name=\"Link\">The Graphics object to draw onto</param>\n        /// <param name=\"Path\">The path to draw along</param>\n        /// <param name=\"Top\">The color of the gradient at the top</param>\n        /// <param name=\"Bottom\">The color of the gradient at the bottom</param>\n        /// <param name=\"Angle\">The angle which the gradient is drawn (null defaults to 90f)</param>\n        /// <param name=\"Blend\">The blending options to draw the gradient</param>\n        public void PaintBorder(Graphics Link, GraphicsPath Path, Rectangle Area, Color Top, Color Bottom, float Angle, Blend Blend)\n        {\n\n            if (float.IsNaN(Angle))\n            {\n                Angle = 90f;\n            }\n\n            using (LinearGradientBrush Fill = new LinearGradientBrush(Area, Top, Bottom, Angle))\n            {\n                if (Blend != null)\n                {\n                    Fill.Blend = Blend;\n                }\n\n                Link.DrawPath(new Pen(Fill), Path);\n                Fill.Dispose();\n            }\n        }\n        #endregion\n\n        #endregion\n\n        #region \"Important -- Functions handling the OnRender delegations\"\n\n        #region \"IDrawToolstripButton -- Draws a Toolstrip button applying the backround and border\"\n        /// <summary>\n        /// Draws a Toolstrip button\n        /// </summary>\n        /// <param name=\"Item\">The Toolstrip button</param>\n        /// <param name=\"Link\">The Graphics object to handle</param>\n        /// <param name=\"Parent\">The parent Toolstrip</param>\n        public void IDrawToolstripButton(ToolStripButton Item, Graphics Link, ToolStrip Parent)\n        {\n            Rectangle Area = new Rectangle(\n                                new Point(0, 0),\n                                new Size(Item.Bounds.Size.Width - 1, Item.Bounds.Size.Height - 1)\n                            );\n\n            Blend BackBlend = GetBlend(Item, ButtonType.NormalButton);\n            Color[] Render = GetButtonBackColor(Item, ButtonType.NormalButton);\n\n            using (GraphicsPath Path = CreateDrawingPath(Area, _btnManager.Curve))\n            {\n                Link.SetClip(Path);\n\n                PaintBackground(\n                            Link,\n                            Area,\n                            Render[0],\n                            Render[1],\n                            _btnManager.BackgroundAngle,\n                            BackBlend\n                            );\n\n                Link.ResetClip();\n\n                Link.SmoothingMode = SmoothingMode.AntiAlias;\n\n                using (GraphicsPath OBPath = CreateDrawingPath(Area, _btnManager.Curve))\n                {\n                    PaintBorder(\n                                Link,\n                                OBPath,\n                                Area,\n                                _btnManager.BorderTop,\n                                _btnManager.BorderBottom,\n                                _btnManager.BorderAngle,\n                                _btnManager.BorderBlend\n                                );\n\n                    OBPath.Dispose();\n                }\n\n                Area.Inflate(-1, -1);\n\n                using (GraphicsPath IBPath = CreateDrawingPath(Area, _btnManager.Curve))\n                {\n                    using (SolidBrush InnerBorder = new SolidBrush(_btnManager.InnerBorder))\n                    {\n                        PaintBorder(\n                                    Link,\n                                    IBPath,\n                                    InnerBorder\n                                    );\n\n                        InnerBorder.Dispose();\n                    }\n                }\n\n                Link.SmoothingMode = SmoothingMode.Default;\n            }\n        }\n        #endregion\n\n        #region \"IDrawDropDownButton -- Draws a Toolstrip dropdownbutton applying the backround and border\"\n        /// <summary>\n        /// Draws a Toolstrip button\n        /// </summary>\n        /// <param name=\"Item\">The Toolstrip button</param>\n        /// <param name=\"Link\">The Graphics object to handle</param>\n        /// <param name=\"Parent\">The parent Toolstrip</param>\n        public void IDrawDropDownButton(ToolStripDropDownButton Item, Graphics Link, ToolStrip Parent)\n        {\n            Rectangle Area = new Rectangle(\n                                new Point(0, 0),\n                                new Size(Item.Bounds.Size.Width - 1, Item.Bounds.Size.Height - 1)\n                            );\n\n            Blend BackBlend = GetBlend(Item, ButtonType.DropDownButton);\n            Color[] Render = GetButtonBackColor(Item, ButtonType.DropDownButton);\n\n            using (GraphicsPath Path = CreateDrawingPath(Area, _btnManager.Curve))\n            {\n                Link.SetClip(Path);\n\n                PaintBackground(\n                            Link,\n                            Area,\n                            Render[0],\n                            Render[1],\n                            _btnManager.BackgroundAngle,\n                            BackBlend\n                            );\n\n                Link.ResetClip();\n\n                Link.SmoothingMode = SmoothingMode.AntiAlias;\n\n                using (GraphicsPath OBPath = CreateDrawingPath(Area, _btnManager.Curve))\n                {\n                    PaintBorder(\n                                Link,\n                                OBPath,\n                                Area,\n                                _btnManager.BorderTop,\n                                _btnManager.BorderBottom,\n                                _btnManager.BorderAngle,\n                                _btnManager.BorderBlend\n                                );\n\n                    OBPath.Dispose();\n                }\n\n                if (!Item.Pressed)\n                {\n                    Area.Inflate(-1, -1);\n\n                    using (GraphicsPath IBPath = CreateDrawingPath(Area, _dBtnManager.Curve))\n                    {\n                        using (SolidBrush InnerBorder = new SolidBrush(_dBtnManager.InnerBorder))\n                        {\n                            PaintBorder(\n                                        Link,\n                                        IBPath,\n                                        InnerBorder\n                                        );\n\n                            InnerBorder.Dispose();\n                        }\n                    }\n                }\n\n                Link.SmoothingMode = SmoothingMode.Default;\n            }\n        }\n        #endregion\n\n        #region \"IDrawToolstripBackground -- Draws a Toolstrip background\"\n        /// <summary>\n        /// Draws the Toolstrip background\n        /// </summary>\n        /// <param name=\"Item\">The Toolstrip being drawn</param>\n        /// <param name=\"Link\">The Graphics object to handle</param>\n        /// <param name=\"Bounds\">The affected bounds</param>\n        public void IDrawToolstripBackground(ToolStrip Item, Graphics Link, Rectangle Bounds)\n        {\n            Rectangle Area = new Rectangle(\n                                0,\n                                0,\n                                Bounds.Width - 1,\n                                Bounds.Height - 1\n                                );\n\n            Link.SmoothingMode = SmoothingMode.None;\n\n            using (GraphicsPath Path = CreateDrawingPath(Area, _tsManager.Curve))\n            {\n                Link.SetClip(Path);\n\n                PaintBackground(\n                                Link,\n                                Area,\n                                _tsManager.BackgroundTop,\n                                _tsManager.BackgroundBottom,\n                                _tsManager.BackgroundAngle,\n                                _tsManager.BackgroundBlend\n                                );\n\n                Link.ResetClip();\n\n                Path.Dispose();\n            }\n        }\n        #endregion\n\n        #region \"IDrawToolstripSplitButton -- Draws a Toolstrip split-button with the arrow\"\n        /// <summary>\n        /// Draws a Toolstrip split-button\n        /// </summary>\n        /// <param name=\"Item\">The Toolstrip split-button</param>\n        /// <param name=\"Link\">The Graphics object to handle</param>\n        /// <param name=\"Parent\">The parent Toolstrip</param>\n        public void IDrawToolstripSplitButton(ToolStripSplitButton Item, Graphics Link, ToolStrip Parent)\n        {\n            if (Item.Selected || Item.DropDownButtonPressed || Item.ButtonPressed)\n            {\n                Rectangle Area = new Rectangle(\n                                        new Point(0, 0),\n                                        new Size(Item.Bounds.Size.Width - 1, Item.Bounds.Size.Height - 1)\n                                        );\n\n                Blend BackBlend = GetBlend(Item, ButtonType.SplitButton);\n                Color[] NormalRender = new Color[] { _sBtnManager.HoverBackgroundTop, _sBtnManager.HoverBackgroundBottom };\n                Color[] Render = GetButtonBackColor(Item, ButtonType.SplitButton);\n\n                using (GraphicsPath Path = CreateDrawingPath(Area, _sBtnManager.Curve))\n                {\n                    Link.SetClip(Path);\n\n                    if (!Item.DropDownButtonPressed)\n                    {\n                        PaintBackground(\n                                        Link,\n                                        Area,\n                                        NormalRender[0],\n                                        NormalRender[1],\n                                        _sBtnManager.BackgroundAngle,\n                                        BackBlend\n                                        );\n                    }\n                    else\n                    {\n                        PaintBackground(\n                                        Link,\n                                        Area,\n                                        Render[0],\n                                        Render[1]\n                                        );\n                    }\n\n                    if (Item.ButtonPressed)\n                    {\n                        Rectangle ButtonArea = new Rectangle(\n                                                    new Point(0, 0),\n                                                    new Size(Item.ButtonBounds.Width, Item.ButtonBounds.Height - 1)\n                                                    );\n\n                        PaintBackground(\n                                        Link,\n                                        ButtonArea,\n                                        Render[0],\n                                        Render[1],\n                                        _sBtnManager.BackgroundAngle,\n                                        _sBtnManager.BackgroundBlend\n                                        );\n                    }\n\n                    Link.ResetClip();\n\n                    Link.SmoothingMode = SmoothingMode.AntiAlias;\n\n                    using (GraphicsPath OBPath = CreateDrawingPath(Area, _sBtnManager.Curve))\n                    {\n                        Color TopColor = (Item.DropDownButtonPressed ? _mnuManager.MenustripButtonBorder : _sBtnManager.BorderTop);\n                        Color BottomColor = (Item.DropDownButtonPressed ? _mnuManager.MenustripButtonBorder : _sBtnManager.BorderBottom);\n\n                        PaintBorder(\n                                    Link,\n                                    OBPath,\n                                    Area,\n                                    TopColor,\n                                    BottomColor,\n                                    _sBtnManager.BorderAngle,\n                                    _sBtnManager.BorderBlend\n                                    );\n\n                        OBPath.Dispose();\n                    }\n\n                    if (!Item.DropDownButtonPressed)\n                    {\n                        Area.Inflate(-1, -1);\n\n                        using (GraphicsPath IBPath = CreateDrawingPath(Area, _sBtnManager.Curve))\n                        {\n                            using (SolidBrush InnerBorder = new SolidBrush(_sBtnManager.InnerBorder))\n                            {\n                                PaintBorder(\n                                            Link,\n                                            IBPath,\n                                            InnerBorder\n                                            );\n\n\n                                Link.DrawRectangle(\n                                                new Pen(_sBtnManager.InnerBorder),\n                                                new Rectangle(\n                                                            Item.ButtonBounds.Width,\n                                                            1,\n                                                            2,\n                                                            Item.ButtonBounds.Height - 3\n                                                            )\n                                                    );\n\n                                InnerBorder.Dispose();\n                            }\n                        }\n\n                        using (LinearGradientBrush SplitLine = new LinearGradientBrush(\n                                                                            new Rectangle(0, 0, 1, Item.Height),\n                                                                            _sBtnManager.BorderTop,\n                                                                            _sBtnManager.BorderBottom,\n                                                                            _sBtnManager.BackgroundAngle\n                                                                            ))\n                        {\n                            if (_sBtnManager.BackgroundBlend != null)\n                            {\n                                SplitLine.Blend = _sBtnManager.BackgroundBlend;\n                            }\n\n                            Link.DrawLine(\n                                        new Pen(SplitLine),\n                                        Item.ButtonBounds.Width + 1,\n                                        0,\n                                        Item.ButtonBounds.Width + 1,\n                                        Item.Height - 1\n                                        );\n\n                            SplitLine.Dispose();\n                        }\n                    }\n\n                    Link.SmoothingMode = SmoothingMode.Default;\n                }\n            }\n\n            Int32 ArrowSize = 5;\n\n            if (\n                (_sBtnManager.ArrowDisplay == ArrowDisplay.Always) ||\n                (_sBtnManager.ArrowDisplay == ArrowDisplay.Hover && Item.Selected)\n                )\n            {\n                using (GraphicsPath TrianglePath = CreateTrianglePath(\n                                                new Rectangle(\n                                                        Item.DropDownButtonBounds.Left + (ArrowSize / 2) - 1,\n                                                        (Item.DropDownButtonBounds.Height / 2) - (ArrowSize / 2) - 3,\n                                                        ArrowSize * 2,\n                                                        ArrowSize * 2\n                                                        ),\n                                                ArrowSize,\n                                                ArrowDirection.Down\n                                                ))\n                {\n                    Link.FillPath(new SolidBrush(_sBtnManager.ArrowColor), TrianglePath);\n\n                    TrianglePath.Dispose();\n                }\n\n            }\n        }\n        #endregion\n\n        #region \"IDrawStatusbarBackground -- Draws the statusbar background\"\n        /// <summary>\n        /// Draws the Statusbar background\n        /// </summary>\n        /// <param name=\"Item\">The Statusbar being drawn</param>\n        /// <param name=\"Link\">The Graphics object to handle</param>\n        /// <param name=\"Bounds\">The affected bounds</param>\n        public void IDrawStatusbarBackground(StatusStrip Item, Graphics Link, Rectangle Bounds)\n        {\n            PaintBackground(\n                        Link,\n                        Bounds,\n                        _sBarManager.BackgroundTop,\n                        _sBarManager.BackgroundBottom,\n                        _sBarManager.BackgroundAngle,\n                        _sBarManager.BackgroundBlend\n                        );\n\n            Link.DrawLine(\n                        new Pen(_sBarManager.DarkBorder),\n                        0, 0, Bounds.Width, 0\n                        );\n\n            Link.DrawLine(\n                        new Pen(_sBarManager.LightBorder),\n                        0, 1, Bounds.Width, 1\n                        );\n        }\n        #endregion\n\n        #region \"IDrawMenustripItem -- Draws a Menustrip item applying the background and border\"\n        /// <summary>\n        /// Draws a Menustrip item\n        /// </summary>\n        /// <param name=\"Item\">The Menustrip item</param>\n        /// <param name=\"Link\">The Graphics object to handle</param>\n        /// <param name=\"Parent\">The parent Toolstrip</param>\n        public void IDrawMenustripItem(ToolStripMenuItem Item, Graphics Link, ToolStrip Parent)\n        {\n            Rectangle Area = new Rectangle(\n                                new Point(0, 0),\n                                new Size(Item.Bounds.Size.Width - 1, Item.Bounds.Size.Height - 1)\n                            );\n\n            if (Item.OwnerItem != null)\n            {\n                Area.X += 2;\n                Area.Width -= 3;\n            }\n\n            Blend BackBlend = GetBlend(Item, ButtonType.MenuItem);\n            Color[] Render = GetButtonBackColor(Item, ButtonType.MenuItem);\n\n            using (GraphicsPath Path = CreateDrawingPath(Area, _btnManager.Curve))\n            {\n                Link.SetClip(Path);\n\n                PaintBackground(\n                            Link,\n                            Area,\n                            Render[0],\n                            Render[1],\n                            _btnManager.BackgroundAngle,\n                            BackBlend\n                            );\n\n                Link.ResetClip();\n\n                Link.SmoothingMode = SmoothingMode.AntiAlias;\n\n                using (GraphicsPath OBPath = CreateDrawingPath(Area, _btnManager.Curve))\n                {\n                    PaintBorder(\n                                Link,\n                                OBPath,\n                                Area,\n                                _mnuManager.MenustripButtonBorder,\n                                _mnuManager.MenustripButtonBorder,\n                                _btnManager.BorderAngle,\n                                _btnManager.BorderBlend\n                                );\n\n                    OBPath.Dispose();\n                }\n\n                if (!Item.Pressed)\n                {\n                    Area.Inflate(-1, -1);\n\n                    using (GraphicsPath IBPath = CreateDrawingPath(Area, _btnManager.Curve))\n                    {\n                        using (SolidBrush InnerBorder = new SolidBrush(_btnManager.InnerBorder))\n                        {\n                            PaintBorder(\n                                        Link,\n                                        IBPath,\n                                        InnerBorder\n                                        );\n\n                            InnerBorder.Dispose();\n                        }\n                    }\n                }\n\n                Link.SmoothingMode = SmoothingMode.Default;\n            }\n        }\n        #endregion\n\n        #endregion\n\n        #region \"Important* -- The OnRender protected overrides\"\n\n        #region \"Render Button Background -- Handles drawing toolstrip/menu/status-strip buttons\"\n        /// <summary>\n        /// Covers the button background rendering\n        /// </summary>\n        /// <param name=\"e\"></param>\n        protected override void OnRenderButtonBackground(ToolStripItemRenderEventArgs e)\n        {\n            if (\n                e.ToolStrip is ContextMenuStrip ||\n                e.ToolStrip is ToolStripDropDownMenu ||\n                e.ToolStrip is MenuStrip\n                )\n            {\n                ToolStripMenuItem Item = (ToolStripMenuItem)e.Item;\n\n                if (Item.Selected || Item.Checked || Item.Pressed)\n                    IDrawMenustripItem(Item, e.Graphics, e.ToolStrip);\n            }\n            else if (\n                e.ToolStrip is StatusStrip\n                )\n            {\n            }\n            else\n            {\n                ToolStripButton Item = (ToolStripButton)e.Item;\n\n                if (Item.Selected || Item.Checked || Item.Pressed)\n                    IDrawToolstripButton(Item, e.Graphics, e.ToolStrip);\n            }\n        }\n        #endregion\n\n        #region \"Render Dropdown Button Background\"\n        protected override void OnRenderDropDownButtonBackground(ToolStripItemRenderEventArgs e)\n        {\n            if (e.Item.Selected || e.Item.Pressed)\n                IDrawDropDownButton((ToolStripDropDownButton)e.Item, e.Graphics, e.ToolStrip);\n        }\n        #endregion\n\n        #region \"Render Image Margin -- Handles drawing the image margin on drop-down menus\"\n        protected override void OnRenderImageMargin(ToolStripRenderEventArgs e)\n        {\n            Rectangle Area = new Rectangle(\n                                        2,\n                                        2,\n                                        e.AffectedBounds.Width,\n                                        e.AffectedBounds.Height - 4\n                                        );\n\n            PaintBackground(e.Graphics, Area, _mnuManager.MarginLeft, _mnuManager.MarginRight, 0f);\n\n            e.Graphics.DrawLine(\n                            new Pen(_mnuManager.MenuBorderDark),\n                            e.AffectedBounds.Width + 1,\n                            2,\n                            e.AffectedBounds.Width + 1,\n                            e.AffectedBounds.Height - 3\n                            );\n        }\n        #endregion\n\n        #region \"Render Item Text -- Allows smoothing of text and changing the color\"\n        protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e)\n        {\n            if (_smoothText)\n                e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;\n\n            if (_overrideText)\n                e.TextColor = _overrideColor;\n\n            base.OnRenderItemText(e);\n        }\n        #endregion\n\n        #region \"Render Menuitem Background -- Handles drawing menu-item backgrounds\"\n        protected override void OnRenderMenuItemBackground(ToolStripItemRenderEventArgs e)\n        {\n            ToolStripMenuItem Item = (ToolStripMenuItem)e.Item;\n\n            if ((!Item.Selected && !Item.Checked && !Item.Pressed) || Item.Enabled == false)\n            {\n                return;\n            }\n\n            if (\n                e.ToolStrip is MenuStrip ||\n                e.ToolStrip is ToolStripDropDownMenu ||\n                e.ToolStrip is ContextMenuStrip\n                )\n            {\n                IDrawMenustripItem(Item, e.Graphics, e.ToolStrip);\n            }\n        }\n        #endregion\n\n        #region \"Render Seperator -- Handles drawing the seperator for the toolstrip and contextmenu controls\"\n        protected override void OnRenderSeparator(ToolStripSeparatorRenderEventArgs e)\n        {\n            if (\n                e.ToolStrip is ContextMenuStrip ||\n                e.ToolStrip is ToolStripDropDownMenu\n                )\n            {\n                // Draw it\n\n                e.Graphics.DrawLine(new Pen(_mnuManager.SeperatorDark), _mnuManager.SeperatorInset, 3, e.Item.Width + 1, 3);\n                e.Graphics.DrawLine(new Pen(_mnuManager.SeperatorLight), _mnuManager.SeperatorInset, 4, e.Item.Width + 1, 4);\n            }\n            else\n            {\n                if (e.Vertical)\n                {\n                    e.Graphics.DrawLine(new Pen(_tsCtrlManager.SeperatorDark), 3, 5, 3, e.Item.Height - 6);\n                    e.Graphics.DrawLine(new Pen(_tsCtrlManager.SeperatorLight), 4, 6, 4, e.Item.Height - 6);\n                }\n                else\n                {\n                    e.Graphics.DrawLine(new Pen(_tsCtrlManager.SeperatorDark), 8, 0, e.Item.Width - 6, 0);\n                    e.Graphics.DrawLine(new Pen(_tsCtrlManager.SeperatorLight), 9, 1, e.Item.Width - 6, 1);\n                }\n            }\n        }\n        #endregion\n\n        #region \"Render SplitButton Background -- Handles drawing the split button\"\n        protected override void OnRenderSplitButtonBackground(ToolStripItemRenderEventArgs e)\n        {\n            ToolStripSplitButton Item = (ToolStripSplitButton)e.Item;\n\n            IDrawToolstripSplitButton(Item, e.Graphics, e.ToolStrip);\n        }\n        #endregion\n\n        #region \"Render Statusstrip Sizing Grip\"\n        protected override void OnRenderStatusStripSizingGrip(ToolStripRenderEventArgs e)\n        {\n            using (SolidBrush Top = new SolidBrush(_sBarManager.GripTop),\n                              Bottom = new SolidBrush(_sBarManager.GripBottom))\n            {\n                Int32 d = _sBarManager.GripSpacing;\n                Int32 y = e.AffectedBounds.Bottom - (d * 4);\n\n                for (int a = 1; a < 4; a++)\n                {\n                    y = y + d;\n\n                    for (int b = 1; a >= b; b++)\n                    {\n                        Int32 x = e.AffectedBounds.Right - (d * b);\n\n                        e.Graphics.FillRectangle(Bottom, x + 1, y + 1, 2, 2);\n                        e.Graphics.FillRectangle(Top, x, y, 2, 2);\n                    }\n                }\n            }\n        }\n        #endregion\n\n        #region \"Render Toolstrip Background -- Handles drawing toolstrip/menu/status-strip backgrounds\"\n        protected override void OnRenderToolStripBackground(ToolStripRenderEventArgs e)\n        {\n            if (\n                e.ToolStrip is ContextMenuStrip ||\n                e.ToolStrip is ToolStripDropDownMenu\n                )\n            {\n                PaintBackground(e.Graphics, e.AffectedBounds, _mnuManager.BackgroundTop, _mnuManager.BackgroundBottom, 90f, _mnuManager.BackgroundBlend);\n\n                Rectangle Border = new Rectangle(\n                                            0,\n                                            0,\n                                            e.AffectedBounds.Width - 1,\n                                            e.AffectedBounds.Height - 1\n                                            );\n\n                using (GraphicsPath Path = CreateDrawingPath(Border, 0))\n                {\n                    e.Graphics.ExcludeClip(new Rectangle(\n                                                    1,\n                                                    0,\n                                                    e.ConnectedArea.Width,\n                                                    e.ConnectedArea.Height - 1\n                                                    ));\n\n                    PaintBorder(e.Graphics, Path, new SolidBrush(_mnuManager.MenuBorderDark));\n\n                    e.Graphics.ResetClip();\n\n                    Path.Dispose();\n                }\n            }\n            else if (\n                e.ToolStrip is MenuStrip)\n            {\n                Rectangle Area = e.AffectedBounds;\n\n                PaintBackground(e.Graphics, Area, new SolidBrush(_pManager.ContentPanelTop));\n            }\n            else if (\n                e.ToolStrip is StatusStrip\n                )\n            {\n                IDrawStatusbarBackground((StatusStrip)e.ToolStrip, e.Graphics, e.AffectedBounds);\n            }\n            else\n            {\n                e.ToolStrip.BackColor = Color.Transparent;\n\n                IDrawToolstripBackground(e.ToolStrip, e.Graphics, e.AffectedBounds);\n            }\n        }\n        #endregion\n\n        #region \"Render Toolstrip Border -- Handles drawing the border for toolstrip/menu/status-strip controls\"\n        protected override void OnRenderToolStripBorder(ToolStripRenderEventArgs e)\n        {\n            if (\n                e.ToolStrip is ContextMenuStrip ||\n                e.ToolStrip is ToolStripDropDownMenu\n                )\n            {\n            }\n            else if (\n                e.ToolStrip is StatusStrip\n                )\n            {\n            }\n            else if (\n                e.ToolStrip is MenuStrip\n                )\n            {\n            }\n            else\n            {\n                Rectangle Area = new Rectangle(\n                                        0,\n                                        -2,\n                                        e.AffectedBounds.Width - 2,\n                                        e.AffectedBounds.Height + 1\n                                        );\n                using (GraphicsPath Path = CreateDrawingPath(Area, _tsManager.Curve))\n                {\n                    PaintBorder(\n                                e.Graphics,\n                                Path,\n                                e.AffectedBounds,\n                                _tsManager.BorderTop,\n                                _tsManager.BorderBottom,\n                                _tsManager.BorderAngle,\n                                _tsManager.BorderBlend\n                                );\n\n                    Path.Dispose();\n                }\n            }\n        }\n        #endregion\n\n        #region \"Render Toolstrip Content Panel Background -- Handles drawing the content panel background\"\n        protected override void OnRenderToolStripContentPanelBackground(ToolStripContentPanelRenderEventArgs e)\n        {\n            if (e.ToolStripContentPanel.ClientRectangle.Width < 3 || e.ToolStripContentPanel.ClientRectangle.Height < 3)\n            {\n                return;\n            }\n\n            e.Handled = true;\n\n            e.Graphics.SmoothingMode = _pManager.Mode;\n\n            PaintBackground(\n                        e.Graphics,\n                        e.ToolStripContentPanel.ClientRectangle,\n                        _pManager.ContentPanelTop,\n                        _pManager.ContentPanelBottom,\n                        _pManager.BackgroundAngle,\n                        _pManager.BackgroundBlend\n                        );\n        }\n        #endregion\n\n        #region \"Render Toolstrip Panel Background -- Handles drawing the backgrounds for each panel\"\n        protected override void OnRenderToolStripPanelBackground(ToolStripPanelRenderEventArgs e)\n        {\n            if (e.ToolStripPanel.ClientRectangle.Width < 3 || e.ToolStripPanel.ClientRectangle.Height < 3)\n                return;\n\n            e.Handled = true;\n\n            switch (e.ToolStripPanel.Dock)\n            {\n                case DockStyle.Top:\n                    PaintBackground(\n                                    e.Graphics,\n                                    e.ToolStripPanel.ClientRectangle,\n                                    new SolidBrush(_pManager.ContentPanelTop)\n                                    );\n                    break;\n\n                case DockStyle.Bottom:\n                    PaintBackground(\n                                    e.Graphics,\n                                    e.ToolStripPanel.ClientRectangle,\n                                    new SolidBrush(_pManager.ContentPanelBottom)\n                                    );\n                    break;\n\n                case DockStyle.Left:\n                case DockStyle.Right:\n                    PaintBackground(\n                                    e.Graphics,\n                                    e.ToolStripPanel.ClientRectangle,\n                                    _pManager.ContentPanelTop,\n                                    _pManager.ContentPanelBottom,\n                                    _pManager.BackgroundAngle,\n                                    _pManager.BackgroundBlend\n                                    );\n                    break;\n            }\n        }\n        #endregion\n\n        #endregion\n\n        #region \"Other functions\"\n\n        #region \"Apply -- Applies any recent changes to the renderer\"\n        /// <summary>\n        /// Applies any and all changes made to the Renderer\n        /// </summary>\n        public void Apply()\n        {\n            ToolStripManager.Renderer = this;\n        }\n        #endregion\n\n        #endregion\n    }\n    #endregion\n\n    #region \"EasyRender -- Toolstrip controlling class\"\n    /// <summary>\n    /// A class designed to be used in the EasyRender master control to customize the look and feel of the base Toolstrip\n    /// </summary>\n    public class IToolstrip : IDisposable\n    {\n        #region \"Initialization and Setup\"\n\n        /// <summary>\n        /// Creates a new IToolstrip class for customization\n        /// </summary>\n        public IToolstrip()\n        {\n            DefaultBlending();\n        }\n\n        /// <summary>\n        /// Creates a new IToolstrip class for customization\n        /// </summary>\n        /// <param name=\"Import\">The IToolstrip to import the settings from</param>\n        public IToolstrip(IToolstrip Import)\n        {\n            DefaultBlending();\n\n            Apply(Import);\n        }\n\n        /// <summary>\n        /// Disposes of the IToolstrip class and clears all resources related to it\n        /// </summary>\n        public void Dispose()\n        {\n            GC.SuppressFinalize(this);\n        }\n\n        #endregion\n\n        #region \"Private variables\"\n\n        private int _curve = 2;\n\n        private Color _borderTop = Color.Transparent;\n        private Color _borderBottom = Color.FromArgb(71, 117, 177);\n        private Blend _borderBlend = null;\n        private float _borderAngle = 90;\n\n        private Color _backTop = Color.FromArgb(227, 239, 255);\n        private Color _backBottom = Color.FromArgb(163, 193, 234);\n        private Blend _backBlend = null;\n        private float _backAngle = 90;\n\n        #endregion\n\n        #region \"Properties\"\n\n        /// <summary>\n        /// Gets or sets the color of the Toolstrip background gradient from the top\n        /// </summary>\n        public Color BackgroundTop\n        {\n            get\n            {\n                return _backTop;\n            }\n\n            set\n            {\n                _backTop = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the color of the Toolstrip background gradient from the bottom\n        /// </summary>\n        public Color BackgroundBottom\n        {\n            get\n            {\n                return _backBottom;\n            }\n\n            set\n            {\n                _backBottom = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the blending that will occur when rendering the Toolstrip background\n        /// If set to null, the Toolstrip will simply draw the gradient\n        /// </summary>\n        public Blend BackgroundBlend\n        {\n            get\n            {\n                return _backBlend;\n            }\n\n            set\n            {\n                _backBlend = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the angle which the Toolstrip background will be drawn\n        /// </summary>\n        public float BackgroundAngle\n        {\n            get\n            {\n                return _backAngle;\n            }\n\n            set\n            {\n                _backAngle = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the color of the Toolstrip border gradient from the top\n        /// </summary>\n        public Color BorderTop\n        {\n            get\n            {\n                return _borderTop;\n            }\n\n            set\n            {\n                _borderTop = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the color of the Toolstrip border gradient from the bottom\n        /// </summary>\n        public Color BorderBottom\n        {\n            get\n            {\n                return _borderBottom;\n            }\n\n            set\n            {\n                _borderBottom = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the blending that will occur when rendering the Toolstrip border\n        /// If set to null, the Toolstrip will simply draw the border\n        /// </summary>\n        public Blend BorderBlend\n        {\n            get\n            {\n                return _borderBlend;\n            }\n\n            set\n            {\n                _borderBlend = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the angle which the Toolstrip border will be drawn\n        /// </summary>\n        public float BorderAngle\n        {\n            get\n            {\n                return _borderAngle;\n            }\n\n            set\n            {\n                _borderAngle = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the curve of the border of the Toolstrip\n        /// </summary>\n        public int Curve\n        {\n            get\n            {\n                return _curve;\n            }\n\n            set\n            {\n                _curve = value;\n            }\n        }\n\n        #endregion\n\n        #region \"Methods\"\n\n        /// <summary>\n        /// Imports the settings from a previous or pre-defined IToolstrip and applies it to the current\n        /// </summary>\n        /// <param name=\"Import\">The IToolstrip to import the settings from</param>\n        public void Apply(IToolstrip Import)\n        {\n            _backTop = Import._borderTop;\n            _backBottom = Import._borderBottom;\n            _backAngle = Import._borderAngle;\n            _backBlend = Import._backBlend;\n\n            _borderTop = Import._borderTop;\n            _borderBottom = Import._borderBottom;\n            _borderAngle = Import._borderAngle;\n            _borderBlend = Import._borderBlend;\n\n            _curve = Import._curve;\n        }\n\n        /// <summary>\n        /// Sets the blending for both border and background to their defaults\n        /// </summary>\n        public void DefaultBlending()\n        {\n            _borderBlend = new Blend();\n            _borderBlend.Positions = new float[] { 0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1f };\n            _borderBlend.Factors = new float[] { 0.1f, 0.2f, 0.3f, 0.3f, 0.3f, 0.4f, 0.4f, 0.4f, 0.5f, 0.7f, 0.7f };\n\n            _backBlend = new Blend();\n            _backBlend.Positions = new float[] { 0f, 0.3f, 0.5f, 0.8f, 1f };\n            _backBlend.Factors = new float[] { 0f, 0f, 0f, 0.5f, 1f };\n        }\n\n        #endregion\n    }\n    #endregion\n\n    #region \"EasyRender -- Toolstrip extended controls\"\n    public class IToolstripControls : IDisposable\n    {\n        #region \"Initialization and Setup\"\n\n        /// <summary>\n        /// Creates a new IToolstripControls class for customization\n        /// </summary>\n        public IToolstripControls()\n        {\n        }\n\n        /// <summary>\n        /// Disposes of the IToolstripControls class and clears all resources related to it\n        /// </summary>\n        public void Dispose()\n        {\n            GC.SuppressFinalize(this);\n        }\n\n        #endregion\n\n        #region \"Private variables\"\n\n        private Color _sepDark = Color.FromArgb(154, 198, 255);\n        private Color _sepLight = Color.White;\n        private int _sepHeight = 8;\n\n        private Color _gripTop = Color.FromArgb(111, 157, 217);\n        private Color _gripBottom = Color.White;\n        private GripType _gripStyle = GripType.Dotted;\n        private int _gripDistance = 4;\n        private Size _gripSize = new Size(2, 2);\n\n        #endregion\n\n        #region \"Properties\"\n\n        /// <summary>\n        /// Gets or sets the color of the Toolstrip seperator on the dark side\n        /// </summary>\n        public Color SeperatorDark\n        {\n            get\n            {\n                return _sepDark;\n            }\n\n            set\n            {\n                _sepDark = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the color of the Toolstrip seperator on the light side\n        /// </summary>\n        public Color SeperatorLight\n        {\n            get\n            {\n                return _sepLight;\n            }\n\n            set\n            {\n                _sepLight = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the height of the Toolstrip seperator control\n        /// </summary>\n        public int SeperatorHeight\n        {\n            get\n            {\n                return _sepHeight;\n            }\n\n            set\n            {\n                _sepHeight = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the color of the grip dots/line at the top\n        /// </summary>\n        public Color GripTop\n        {\n            get\n            {\n                return _gripTop;\n            }\n\n            set\n            {\n                _gripTop = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the color of the grip shadow\n        /// </summary>\n        public Color GripShadow\n        {\n            get\n            {\n                return _gripBottom;\n            }\n\n            set\n            {\n                _gripBottom = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets in what mode the grip will be drawn\n        /// </summary>\n        public GripType GripStyle\n        {\n            get { return _gripStyle; }\n            set { _gripStyle = value; }\n        }\n\n        /// <summary>\n        /// Gets or sets the distance, in pixels, between each grip dot\n        /// </summary>\n        public int GripDistance\n        {\n            get { return _gripDistance; }\n            set { _gripDistance = value; }\n        }\n\n        /// <summary>\n        /// Gets or sets the size of the dots or lines for the grip\n        /// </summary>\n        public Size GripSize\n        {\n            get { return _gripSize; }\n            set { _gripSize = value; }\n        }\n\n        #endregion\n\n        #region \"Methods\"\n\n        /// <summary>\n        /// Imports the settings from a previous or pre-defined IToolstripControls and applies it to the current\n        /// </summary>\n        /// <param name=\"Import\">The IToolstripControls to import the settings from</param>\n        public void Apply(IToolstripControls Import)\n        {\n            _sepDark = Import._sepDark;\n            _sepLight = Import._sepLight;\n            _sepHeight = Import._sepHeight;\n\n            _gripTop = Import._gripTop;\n            _gripBottom = Import._gripBottom;\n            _gripDistance = Import._gripDistance;\n            _gripStyle = Import._gripStyle;\n            _gripSize = Import._gripSize;\n        }\n\n        #endregion\n    }\n    #endregion\n\n    #region \"EasyRender -- Button controlling class\"\n    public class IButton : IDisposable\n    {\n        #region \"Initialization and Setup\"\n\n        /// <summary>\n        /// Creates a new IButton class for customization\n        /// </summary>\n        public IButton()\n        {\n            DefaultBlending();\n        }\n\n        /// <summary>\n        /// Creates a new IButton class for customization\n        /// </summary>\n        /// <param name=\"Import\">The IButton to import the settings from</param>\n        public IButton(IButton Import)\n        {\n            DefaultBlending();\n\n            Apply(Import);\n        }\n\n        /// <summary>\n        /// Disposes of the IButton class and clears all resources related to it\n        /// </summary>\n        public void Dispose()\n        {\n            GC.SuppressFinalize(this);\n        }\n\n        #endregion\n\n        #region \"Private variables\"\n\n        private Color _borderTop = Color.FromArgb(157, 183, 217);\n        private Color _borderBottom = Color.FromArgb(157, 183, 217);\n        private Color _borderInner = Color.FromArgb(255, 247, 185);\n        private Blend _borderBlend = null;\n        private float _borderAngle = 90f;\n\n        private Color _hoverBackTop = Color.FromArgb(255, 249, 218);\n        private Color _hoverBackBottom = Color.FromArgb(237, 189, 62);\n\n        private Color _clickBackTop = Color.FromArgb(245, 207, 57);\n        private Color _clickBackBottom = Color.FromArgb(245, 225, 124);\n\n        private float _backAngle = 90f;\n        private Blend _backBlend = null;\n\n        private BlendRender _blendRender = BlendRender.Hover | BlendRender.Click | BlendRender.Check;\n        private int _curve = 1;\n\n        #endregion\n\n        #region \"Properties\"\n\n        /// <summary>\n        /// Gets or sets the color of the Button background at the top, when hovered over\n        /// </summary>\n        public Color HoverBackgroundTop\n        {\n            get\n            {\n                return _hoverBackTop;\n            }\n\n            set\n            {\n                _hoverBackTop = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the color of the Button background at the bottom, when hovered over\n        /// </summary>\n        public Color HoverBackgroundBottom\n        {\n            get\n            {\n                return _hoverBackBottom;\n            }\n\n            set\n            {\n                _hoverBackBottom = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the color of the Button background at the top, when clicked\n        /// </summary>\n        public Color ClickBackgroundTop\n        {\n            get\n            {\n                return _clickBackTop;\n            }\n\n            set\n            {\n                _clickBackTop = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the color of the Button background at the bottom, when clicked\n        /// </summary>\n        public Color ClickBackgroundBottom\n        {\n            get\n            {\n                return _clickBackBottom;\n            }\n\n            set\n            {\n                _clickBackBottom = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the blending that will occur when rendering the Button background\n        /// If set to null, the Button will simply draw the gradient\n        /// </summary>\n        public Blend BackgroundBlend\n        {\n            get\n            {\n                return _backBlend;\n            }\n\n            set\n            {\n                _backBlend = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the angle which the Button background will be drawn\n        /// </summary>\n        public float BackgroundAngle\n        {\n            get\n            {\n                return _backAngle;\n            }\n\n            set\n            {\n                _backAngle = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the color of the Button border gradient from the top\n        /// </summary>\n        public Color BorderTop\n        {\n            get\n            {\n                return _borderTop;\n            }\n\n            set\n            {\n                _borderTop = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the color of the Button border gradient from the bottom\n        /// </summary>\n        public Color BorderBottom\n        {\n            get\n            {\n                return _borderBottom;\n            }\n\n            set\n            {\n                _borderBottom = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the blending that will occur when rendering the Button border\n        /// If set to null, the Button will simply draw the border\n        /// </summary>\n        public Blend BorderBlend\n        {\n            get\n            {\n                return _borderBlend;\n            }\n\n            set\n            {\n                _borderBlend = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the angle which the Button border will be drawn\n        /// </summary>\n        public float BorderAngle\n        {\n            get\n            {\n                return _borderAngle;\n            }\n\n            set\n            {\n                _borderAngle = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the color of the inside border\n        /// </summary>\n        public Color InnerBorder\n        {\n            get { return _borderInner; }\n            set { _borderInner = value; }\n        }\n\n        /// <summary>\n        /// Gets or sets when to apply the rendering (\"Normal\" does not apply here)\n        /// </summary>\n        public BlendRender BlendOptions\n        {\n            get\n            {\n                return _blendRender;\n            }\n\n            set\n            {\n                _blendRender = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the curve of the border of the Button\n        /// </summary>\n        public int Curve\n        {\n            get\n            {\n                return _curve;\n            }\n\n            set\n            {\n                _curve = value;\n            }\n        }\n\n        #endregion\n\n        #region \"Methods\"\n\n        /// <summary>\n        /// Imports the settings from a previous or pre-defined IButton and applies it to the current\n        /// </summary>\n        /// <param name=\"Import\">The IButton to import the settings from</param>\n        public void Apply(IButton Import)\n        {\n            _borderTop = Import._borderTop;\n            _borderBottom = Import._borderBottom;\n            _borderAngle = Import._borderAngle;\n            _borderBlend = Import._borderBlend;\n\n            _hoverBackTop = Import._hoverBackTop;\n            _hoverBackBottom = Import._hoverBackBottom;\n            _clickBackTop = Import._clickBackTop;\n            _clickBackBottom = Import._clickBackBottom;\n\n            _backAngle = Import._backAngle;\n            _backBlend = Import._backBlend;\n\n            _blendRender = Import._blendRender;\n            _curve = Import._curve;\n        }\n\n        /// <summary>\n        /// Sets the blending for both border and background to their defaults\n        /// </summary>\n        public void DefaultBlending()\n        {\n            _borderBlend = null;\n\n            _backBlend = new Blend();\n            _backBlend.Positions = new float[] { 0f, 0.5f, 0.5f, 1f };\n            _backBlend.Factors = new float[] { 0f, 0.2f, 1f, 0.3f };\n        }\n\n        #endregion\n    }\n\n    #endregion\n\n    #region \"EasyRender -- Dropdown Button controlling class\"\n    public class IDropDownButton : IDisposable\n    {\n        #region \"Initialization and Setup\"\n\n        /// <summary>\n        /// Creates a new IButton class for customization\n        /// </summary>\n        public IDropDownButton()\n        {\n            DefaultBlending();\n        }\n\n        /// <summary>\n        /// Creates a new IButton class for customization\n        /// </summary>\n        /// <param name=\"Import\">The IButton to import the settings from</param>\n        public IDropDownButton(IDropDownButton Import)\n        {\n            DefaultBlending();\n\n            Apply(Import);\n        }\n\n        /// <summary>\n        /// Disposes of the IButton class and clears all resources related to it\n        /// </summary>\n        public void Dispose()\n        {\n            GC.SuppressFinalize(this);\n        }\n\n        #endregion\n\n        #region \"Private variables\"\n\n        private Color _borderTop = Color.FromArgb(157, 183, 217);\n        private Color _borderBottom = Color.FromArgb(157, 183, 217);\n        private Color _borderInner = Color.FromArgb(255, 247, 185);\n        private Blend _borderBlend = null;\n        private float _borderAngle = 90f;\n\n        private Color _hoverBackTop = Color.FromArgb(255, 249, 218);\n        private Color _hoverBackBottom = Color.FromArgb(237, 189, 62);\n\n        private float _backAngle = 90f;\n        private Blend _backBlend = null;\n\n        private BlendRender _blendRender = BlendRender.Hover | BlendRender.Check;\n        private int _curve = 1;\n\n        #endregion\n\n        #region \"Properties\"\n\n        /// <summary>\n        /// Gets or sets the color of the Button background at the top, when hovered over\n        /// </summary>\n        public Color HoverBackgroundTop\n        {\n            get\n            {\n                return _hoverBackTop;\n            }\n\n            set\n            {\n                _hoverBackTop = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the color of the Button background at the bottom, when hovered over\n        /// </summary>\n        public Color HoverBackgroundBottom\n        {\n            get\n            {\n                return _hoverBackBottom;\n            }\n\n            set\n            {\n                _hoverBackBottom = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the blending that will occur when rendering the Button background\n        /// If set to null, the Button will simply draw the gradient\n        /// </summary>\n        public Blend BackgroundBlend\n        {\n            get\n            {\n                return _backBlend;\n            }\n\n            set\n            {\n                _backBlend = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the angle which the Button background will be drawn\n        /// </summary>\n        public float BackgroundAngle\n        {\n            get\n            {\n                return _backAngle;\n            }\n\n            set\n            {\n                _backAngle = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the color of the Button border gradient from the top\n        /// </summary>\n        public Color BorderTop\n        {\n            get\n            {\n                return _borderTop;\n            }\n\n            set\n            {\n                _borderTop = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the color of the Button border gradient from the bottom\n        /// </summary>\n        public Color BorderBottom\n        {\n            get\n            {\n                return _borderBottom;\n            }\n\n            set\n            {\n                _borderBottom = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the blending that will occur when rendering the Button border\n        /// If set to null, the Button will simply draw the border\n        /// </summary>\n        public Blend BorderBlend\n        {\n            get\n            {\n                return _borderBlend;\n            }\n\n            set\n            {\n                _borderBlend = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the angle which the Button border will be drawn\n        /// </summary>\n        public float BorderAngle\n        {\n            get\n            {\n                return _borderAngle;\n            }\n\n            set\n            {\n                _borderAngle = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the color of the inside border\n        /// </summary>\n        public Color InnerBorder\n        {\n            get { return _borderInner; }\n            set { _borderInner = value; }\n        }\n\n        /// <summary>\n        /// Gets or sets when to apply the rendering (\"Normal\" and \"Click\" do not apply here)\n        /// </summary>\n        public BlendRender BlendOptions\n        {\n            get\n            {\n                return _blendRender;\n            }\n\n            set\n            {\n                _blendRender = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the curve of the border of the Button\n        /// </summary>\n        public int Curve\n        {\n            get\n            {\n                return _curve;\n            }\n\n            set\n            {\n                _curve = value;\n            }\n        }\n\n        #endregion\n\n        #region \"Methods\"\n\n        /// <summary>\n        /// Imports the settings from a previous or pre-defined IDropDownButton and applies it to the current\n        /// </summary>\n        /// <param name=\"Import\">The IDropDownButton to import the settings from</param>\n        public void Apply(IDropDownButton Import)\n        {\n            _borderTop = Import._borderTop;\n            _borderBottom = Import._borderBottom;\n            _borderAngle = Import._borderAngle;\n            _borderBlend = Import._borderBlend;\n\n            _hoverBackTop = Import._hoverBackTop;\n            _hoverBackBottom = Import._hoverBackBottom;\n\n            _backAngle = Import._backAngle;\n            _backBlend = Import._backBlend;\n\n            _blendRender = Import._blendRender;\n            _curve = Import._curve;\n        }\n\n        /// <summary>\n        /// Sets the blending for both border and background to their defaults\n        /// </summary>\n        public void DefaultBlending()\n        {\n            _borderBlend = null;\n\n            _backBlend = new Blend();\n            _backBlend.Positions = new float[] { 0f, 0.5f, 0.5f, 1f };\n            _backBlend.Factors = new float[] { 0f, 0.2f, 1f, 0.3f };\n        }\n\n        #endregion\n    }\n\n    #endregion\n\n    #region \"EasyRender -- Split Button controlling class\"\n    public class ISplitButton : IDisposable\n    {\n        #region \"Initialization and Setup\"\n\n        /// <summary>\n        /// Creates a new ISplitButton class for customization\n        /// </summary>\n        public ISplitButton()\n        {\n            DefaultBlending();\n        }\n\n        /// <summary>\n        /// Disposes of the ISplitButton class and clears all resources related to it\n        /// </summary>\n        public void Dispose()\n        {\n            GC.SuppressFinalize(this);\n        }\n\n        #endregion\n\n        #region \"Private variables\"\n\n        private Color _borderTop = Color.FromArgb(157, 183, 217);\n        private Color _borderBottom = Color.FromArgb(157, 183, 217);\n        private Color _borderInner = Color.FromArgb(255, 247, 185);\n        private Blend _borderBlend = null;\n        private float _borderAngle = 90f;\n\n        private Color _hoverBackTop = Color.FromArgb(255, 249, 218);\n        private Color _hoverBackBottom = Color.FromArgb(237, 189, 62);\n\n        private Color _clickBackTop = Color.FromArgb(245, 207, 57);\n        private Color _clickBackBottom = Color.FromArgb(245, 225, 124);\n\n        private float _backAngle = 90f;\n        private Blend _backBlend = null;\n\n        private ArrowDisplay _arrowDisplay = ArrowDisplay.Always;\n        private Color _arrowColor = Color.Black;\n\n        private BlendRender _blendRender = BlendRender.Hover | BlendRender.Click | BlendRender.Check;\n        private int _curve = 1;\n\n        #endregion\n\n        #region \"Properties\"\n\n        /// <summary>\n        /// Gets or sets the color of the Button background at the top, when hovered over\n        /// </summary>\n        public Color HoverBackgroundTop\n        {\n            get\n            {\n                return _hoverBackTop;\n            }\n\n            set\n            {\n                _hoverBackTop = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the color of the Button background at the bottom, when hovered over\n        /// </summary>\n        public Color HoverBackgroundBottom\n        {\n            get\n            {\n                return _hoverBackBottom;\n            }\n\n            set\n            {\n                _hoverBackBottom = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the color of the Button background at the top, when clicked\n        /// </summary>\n        public Color ClickBackgroundTop\n        {\n            get\n            {\n                return _clickBackTop;\n            }\n\n            set\n            {\n                _clickBackTop = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the color of the Button background at the bottom, when clicked\n        /// </summary>\n        public Color ClickBackgroundBottom\n        {\n            get\n            {\n                return _clickBackBottom;\n            }\n\n            set\n            {\n                _clickBackBottom = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the blending that will occur when rendering the Button background\n        /// If set to null, the Button will simply draw the gradient\n        /// </summary>\n        public Blend BackgroundBlend\n        {\n            get\n            {\n                return _backBlend;\n            }\n\n            set\n            {\n                _backBlend = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the angle which the Button background will be drawn\n        /// </summary>\n        public float BackgroundAngle\n        {\n            get\n            {\n                return _backAngle;\n            }\n\n            set\n            {\n                _backAngle = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the color of the Button border gradient from the top\n        /// </summary>\n        public Color BorderTop\n        {\n            get\n            {\n                return _borderTop;\n            }\n\n            set\n            {\n                _borderTop = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the color of the Button border gradient from the bottom\n        /// </summary>\n        public Color BorderBottom\n        {\n            get\n            {\n                return _borderBottom;\n            }\n\n            set\n            {\n                _borderBottom = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the blending that will occur when rendering the Button border\n        /// If set to null, the Button will simply draw the border\n        /// </summary>\n        public Blend BorderBlend\n        {\n            get\n            {\n                return _borderBlend;\n            }\n\n            set\n            {\n                _borderBlend = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the angle which the Button border will be drawn\n        /// </summary>\n        public float BorderAngle\n        {\n            get\n            {\n                return _borderAngle;\n            }\n\n            set\n            {\n                _borderAngle = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the color of the inside border\n        /// </summary>\n        public Color InnerBorder\n        {\n            get { return _borderInner; }\n            set { _borderInner = value; }\n        }\n\n        /// <summary>\n        /// Gets or sets when to apply the rendering (\"Normal\" does not apply here)\n        /// </summary>\n        public BlendRender BlendOptions\n        {\n            get\n            {\n                return _blendRender;\n            }\n\n            set\n            {\n                _blendRender = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets the curve of the border of the Button\n        /// </summary>\n        public int Curve\n        {\n            get\n            {\n                return _curve;\n            }\n\n            set\n            {\n                _curve = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets when to display the drop-down arrow\n        /// </summary>\n        public ArrowDisplay ArrowDisplay\n        {\n            get { return _arrowDisplay; }\n            set { _arrowDisplay = value; }\n        }\n\n        /// <summary>\n        /// Gets or sets the color of the drop-down arrow\n        /// </summary>\n        public Color ArrowColor\n        {\n            get { return _arrowColor; }\n            set { _arrowColor = value; }\n        }\n\n        #endregion\n\n        #region \"Methods\"\n\n        /// <summary>\n        /// Imports the settings from a previous or pre-defined ISplitButton and applies it to the current\n        /// </summary>\n        /// <param name=\"Import\">The ISplitButton to import the settings from</param>\n        public void Apply(ISplitButton Import)\n        {\n            _borderTop = Import._borderTop;\n            _borderBottom = Import._borderBottom;\n            _borderAngle = Import._borderAngle;\n            _borderBlend = Import._borderBlend;\n\n            _hoverBackTop = Import._hoverBackTop;\n            _hoverBackBottom = Import._hoverBackBottom;\n            _clickBackTop = Import._clickBackTop;\n            _clickBackBottom = Import._clickBackBottom;\n\n            _backAngle = Import._backAngle;\n            _backBlend = Import._backBlend;\n\n            _blendRender = Import._blendRender;\n            _curve = Import._curve;\n\n            _arrowDisplay = Import._arrowDisplay;\n            _arrowColor = Import._arrowColor;\n        }\n\n        /// <summary>\n        /// Sets the blending for both border and background to their defaults\n        /// </summary>\n        public void DefaultBlending()\n        {\n            _borderBlend = null;\n\n            _backBlend = new Blend();\n            _backBlend.Positions = new float[] { 0f, 0.5f, 0.5f, 1f };\n            _backBlend.Factors = new float[] { 0f, 0.2f, 1f, 0.3f };\n        }\n\n        #endregion\n    }\n    #endregion\n\n    #region \"EasyRender -- Content and Panel controlling class\"\n    public class IPanel : IDisposable\n    {\n        #region \"Initialization and Setup\"\n\n        /// <summary>\n        /// Creates a new IPanel class for customization\n        /// </summary>\n        public IPanel()\n        {\n        }\n\n        /// <summary>\n        /// Disposes of the IButton class and clears all resources related to it\n        /// </summary>\n        public void Dispose()\n        {\n            GC.SuppressFinalize(this);\n        }\n\n        #endregion\n\n        #region \"Private variables\"\n\n        private Color _cPanelTop = Color.FromArgb(191, 219, 255);\n        private Color _cPanelBottom = Color.FromArgb(132, 171, 227);\n        private float _cPanelAngle = 90f;\n        private Blend _cPanelBlend = null;\n\n        private SmoothingMode _mode = SmoothingMode.HighSpeed;\n\n        private Boolean _panelsInherit = false;\n\n        #endregion\n\n        #region \"Properties\"\n\n        /// <summary>\n        /// Gets or sets the color of the gradient at the top of the content panel\n        /// </summary>\n        public Color ContentPanelTop\n        {\n            get { return _cPanelTop; }\n            set { _cPanelTop = value; }\n        }\n\n        /// <summary>\n        /// Gets or sets the color of the gradient at the bottom of the content panel\n        /// </summary>\n        public Color ContentPanelBottom\n        {\n            get { return _cPanelBottom; }\n            set { _cPanelBottom = value; }\n        }\n\n        /// <summary>\n        /// Gets or sets whether each panel inherits the shading from the content panel\n        /// </summary>\n        public Boolean PanelInheritance\n        {\n            get { return _panelsInherit; }\n            set { _panelsInherit = value; }\n        }\n\n        /// <summary>\n        /// Gets or sets the angle which the background gradient is drawn\n        /// </summary>\n        public float BackgroundAngle\n        {\n            get { return _cPanelAngle; }\n            set { _cPanelAngle = value; }\n        }\n\n        /// <summary>\n        /// Gets or sets the blend of the background\n        /// </summary>\n        public Blend BackgroundBlend\n        {\n            get { return _cPanelBlend; }\n            set { _cPanelBlend = value; }\n        }\n\n        /// <summary>\n        /// Gets or sets a mode to render the background in\n        /// </summary>\n        public SmoothingMode Mode\n        {\n            get { return _mode; }\n            set { _mode = value; }\n        }\n\n        #endregion\n    }\n    #endregion\n\n    #region \"EasyRender -- Status bar controlling class\n    public class IStatusBar : IDisposable\n    {\n        #region \"Initialization and Setup\"\n\n        /// <summary>\n        /// Creates a new IStatusBar class for customization\n        /// </summary>\n        public IStatusBar()\n        {\n            DefaultBlending();\n        }\n\n        /// <summary>\n        /// Disposes of the IButton class and clears all resources related to it\n        /// </summary>\n        public void Dispose()\n        {\n            GC.SuppressFinalize(this);\n        }\n\n        #endregion\n\n        #region \"Private variables\"\n\n        private Color _backTop = Color.FromArgb(227, 239, 255);\n        private Color _backBottom = Color.FromArgb(173, 209, 255);\n        private Blend _backBlend = null;\n        private float _backAngle = 90;\n\n        private Color _borderDark = Color.FromArgb(86, 125, 176);\n        private Color _borderLight = Color.White;\n        //private Blend _borderBlend = null;\n        //private float _borderAngle = 90;\n\n        private Color _gripTop = Color.FromArgb(114, 152, 204);\n        private Color _gripBottom = Color.FromArgb(248, 248, 248);\n        private Int32 _gripSpacing = 4;\n\n        #endregion\n\n        #region \"Properties\"\n\n        /// <summary>\n        /// Gets or sets the color of the gradient of the background at the top\n        /// </summary>\n        public Color BackgroundTop\n        {\n            get { return _backTop; }\n            set { _backTop = value; }\n        }\n\n        /// <summary>\n        /// Gets or sets the color of the gradient of the background at the bottom\n        /// </summary>\n        public Color BackgroundBottom\n        {\n            get { return _backBottom; }\n            set { _backBottom = value; }\n        }\n\n        /// <summary>\n        /// Gets or sets the blending that will apply to the background\n        /// </summary>\n        public Blend BackgroundBlend\n        {\n            get { return _backBlend; }\n            set { _backBlend = value; }\n        }\n\n        /// <summary>\n        /// Gets or sets the angle which the background gradient will be drawn\n        /// </summary>\n        public float BackgroundAngle\n        {\n            get { return _backAngle; }\n            set { _backAngle = value; }\n        }\n\n        /// <summary>\n        /// Gets or sets the color of the dark border\n        /// </summary>\n        public Color DarkBorder\n        {\n            get { return _borderDark; }\n            set { _borderDark = value; }\n        }\n\n        /// <summary>\n        /// Gets or sets the color of the light border\n        /// </summary>\n        public Color LightBorder\n        {\n            get { return _borderLight; }\n            set { _borderLight = value; }\n        }\n\n        /// <summary>\n        /// Gets or sets the color of the grip at the top-most\n        /// </summary>\n        public Color GripTop\n        {\n            get { return _gripTop; }\n            set { _gripTop = value; }\n        }\n\n        /// <summary>\n        /// Gets or sets the color of the grip at the bottom-most\n        /// </summary>\n        public Color GripBottom\n        {\n            get { return _gripBottom; }\n            set { _gripBottom = value; }\n        }\n\n        /// <summary>\n        /// Gets or sets the spacing of the grip blocks\n        /// </summary>\n        public Int32 GripSpacing\n        {\n            get { return _gripSpacing; }\n            set { _gripSpacing = value; }\n        }\n\n        #endregion\n\n        #region \"Methods\"\n\n        /// <summary>\n        /// Imports the settings from a previous or pre-defined IStatusBar and applies it to the current\n        /// </summary>\n        /// <param name=\"Import\">The IStatusBar to import the settings from</param>\n        public void Apply(IStatusBar Import)\n        {\n            _borderDark = Import._borderDark;\n            _borderLight = Import._borderLight;\n\n            _backTop = Import._backTop;\n            _backBottom = Import._backBottom;\n            _backAngle = Import._backAngle;\n            _backBlend = Import._backBlend;\n        }\n\n        /// <summary>\n        /// Sets the blending for both border and background to their defaults\n        /// </summary>\n        public void DefaultBlending()\n        {\n            //_borderBlend = null;\n\n            _backBlend = new Blend();\n            _backBlend.Positions = new float[] { 0f, 0.25f, 0.25f, 0.57f, 0.86f, 1f };\n            _backBlend.Factors = new float[] { 0.1f, 0.6f, 1f, 0.4f, 0f, 0.95f };\n        }\n\n        #endregion\n    }\n    #endregion\n\n    #region \"EasyRender -- Menustrip controlling class\"\n    /// <summary>\n    /// A class designed to be used in the EasyRender master control to customize the look and feel of the base Menustrip\n    /// </summary>\n    public class IMenustrip : IDisposable\n    {\n        #region \"Initialization and Setup\"\n\n        /// <summary>\n        /// Creates a new IToolstrip class for customization\n        /// </summary>\n        public IMenustrip()\n        {\n            _buttons = new IButton();\n\n            DefaultBlending();\n        }\n\n        /// <summary>\n        /// Creates a new IMenustrip class for customization\n        /// </summary>\n        /// <param name=\"Import\">The IMenustrip to import the settings from</param>\n        public IMenustrip(IMenustrip Import)\n        {\n            _buttons = new IButton();\n\n            DefaultBlending();\n\n            Apply(Import);\n        }\n\n        /// <summary>\n        /// Disposes of the IMenustrip class and clears all resources related to it\n        /// </summary>\n        public void Dispose()\n        {\n            GC.SuppressFinalize(this);\n        }\n\n        #endregion\n\n        #region \"Private variables\"\n\n        private Color _menuBorderDark = Color.FromArgb(157, 183, 217);\n        private Color _menuBorderLight = Color.Transparent;\n\n        private InheritenceType _menuBackInh = InheritenceType.FromContentPanel;\n        private Color _menuBackTop = Color.White;\n        private Color _menuBackBottom = Color.White;\n        private Blend _menuBackBlend = null;\n\n        private Color _menuStripBtnBackground = Color.White;\n        private Color _menuStripBtnBorder = Color.FromArgb(157, 183, 217);\n\n        private IButton _buttons = null;\n\n        private Color _marginLeft = Color.FromArgb(242, 255, 255);\n        private Color _marginRight = Color.FromArgb(233, 238, 238);\n        private Color _marginBorder = Color.FromArgb(197, 197, 197);\n\n        private Color _sepDark = Color.FromArgb(197, 197, 197);\n        private Color _sepLight = Color.FromArgb(254, 254, 254);\n        private Int32 _sepInset = 30;\n\n        #endregion\n\n        #region \"Properties\"\n\n        /// <summary>\n        /// Gets or sets the color of the menu-strip border (dark)\n        /// </summary>\n        public Color MenuBorderDark\n        {\n            get { return _menuBorderDark; }\n            set { _menuBorderDark = value; }\n        }\n\n        /// <summary>\n        /// Gets or sets the color of the menu-strip border (light)\n        /// </summary>\n        public Color MenuBorderLight\n        {\n            get { return _menuBorderLight; }\n            set { _menuBorderLight = value; }\n        }\n\n        /// <summary>\n        /// Gets or sets how the background of the menu-strip is inherited\n        /// </summary>\n        public InheritenceType BackgroundInheritence\n        {\n            get { return _menuBackInh; }\n            set { _menuBackInh = value; }\n        }\n\n        /// <summary>\n        /// If inheritence is set to none, the color of the background gradient at the top\n        /// </summary>\n        public Color BackgroundTop\n        {\n            get { return _menuBackTop; }\n            set { _menuBackTop = value; }\n        }\n\n        /// <summary>\n        /// If inheritence is set to none, the color of the background gradient at the bottom\n        /// </summary>\n        public Color BackgroundBottom\n        {\n            get { return _menuBackBottom; }\n            set { _menuBackBottom = value; }\n        }\n\n        /// <summary>\n        /// If inheritence is set to none, the blending option for the background\n        /// </summary>\n        public Blend BackgroundBlend\n        {\n            get { return _menuBackBlend; }\n            set { _menuBackBlend = value; }\n        }\n\n        /// <summary>\n        /// Gets or sets the color of the margin gradient at the left\n        /// </summary>\n        public Color MarginLeft\n        {\n            get { return _marginLeft; }\n            set { _marginLeft = value; }\n        }\n\n        /// <summary>\n        /// Gets or sets the color of the margin gradient at the right\n        /// </summary>\n        public Color MarginRight\n        {\n            get { return _marginRight; }\n            set { _marginRight = value; }\n        }\n\n        /// <summary>\n        /// Gets or sets the color of the margin border (displayed to the right)\n        /// </summary>\n        public Color MarginBorder\n        {\n            get { return _marginBorder; }\n            set { _marginBorder = value; }\n        }\n\n        /// <summary>\n        /// Gets or sets the color of the root menu-strip button background when it is selected\n        /// </summary>\n        public Color MenustripButtonBackground\n        {\n            get { return _menuStripBtnBackground; }\n            set { _menuStripBtnBackground = value; }\n        }\n\n        /// <summary>\n        /// Gets or sets the color of the root menu-strip button border when it is selected\n        /// </summary>\n        public Color MenustripButtonBorder\n        {\n            get { return _menuStripBtnBorder; }\n            set { _menuStripBtnBorder = value; }\n        }\n\n        /// <summary>\n        /// Gets or sets the color of the seperator dark color\n        /// </summary>\n        public Color SeperatorDark\n        {\n            get { return _sepDark; }\n            set { _sepDark = value; }\n        }\n\n        /// <summary>\n        /// Gets or sets the color of the seperator light color\n        /// </summary>\n        public Color SeperatorLight\n        {\n            get { return _sepLight; }\n            set { _sepLight = value; }\n        }\n\n        /// <summary>\n        /// Gets or sets the inset position of the seperator from the left\n        /// </summary>\n        public Int32 SeperatorInset\n        {\n            get { return _sepInset; }\n            set { _sepInset = value; }\n        }\n\n        /// <summary>\n        /// Gets the class that handles the look and feel of the menu-strip items\n        /// </summary>\n        [ReadOnly(true)]\n        public IButton Items\n        {\n            get { return _buttons; }\n        }\n\n        #endregion\n\n        #region \"Methods\"\n\n        /// <summary>\n        /// Imports the settings from a previous or pre-defined IMenustrip and applies it to the current\n        /// </summary>\n        /// <param name=\"Import\">The IMenustrip to import the settings from</param>\n        public void Apply(IMenustrip Import)\n        {\n            _menuBackInh = Import._menuBackInh;\n            _menuBackTop = Import._menuBackTop;\n            _menuBackBottom = Import._menuBackBottom;\n            _menuBorderDark = Import._menuBorderDark;\n            _menuBorderLight = Import._menuBorderLight;\n            _menuBackBlend = Import._menuBackBlend;\n            _buttons = Import._buttons;\n        }\n\n        /// <summary>\n        /// Sets the blending for the background to it's default\n        /// </summary>\n        public void DefaultBlending()\n        {\n            _menuBackBlend = new Blend();\n            _menuBackBlend.Positions = new float[] { 0f, 0.3f, 0.5f, 0.8f, 1f };\n            _menuBackBlend.Factors = new float[] { 0f, 0f, 0f, 0.5f, 1f };\n        }\n\n        #endregion\n    }\n    #endregion\n\n    #region \"EasyRender -- Enumerators\"\n\n    /// <summary>\n    /// Defines when to show an arrow\n    /// </summary>\n    public enum ArrowDisplay\n    {\n        Always,\n        Hover,\n        Never\n    }\n\n    /// <summary>\n    /// Defines when to use a blend property\n    /// </summary>\n    public enum BlendRender\n    {\n        /// <summary>\n        /// Use the blend when the object is drawn\n        /// </summary>\n        Normal,\n        /// <summary>\n        /// Use the blend when the object is hovered over\n        /// </summary>\n        Hover,\n        /// <summary>\n        /// Use the blend when the object is clicked\n        /// </summary>\n        Click,\n        /// <summary>\n        /// Use the blend when the object is checked\n        /// </summary>\n        Check,\n        /// <summary>\n        /// Always use the blend regardless of the state of the object\n        /// </summary>\n        All = Normal | Hover | Click | Check\n    }\n\n    /// <summary>\n    /// Defines a method of drawing a grip on a control\n    /// </summary>\n    public enum GripType\n    {\n        /// <summary>\n        /// Draws the grip as a set of dots\n        /// </summary>\n        Dotted,\n        /// <summary>\n        /// Draws the grip as two lines\n        /// </summary>\n        Lines,\n        /// <summary>\n        /// Does not draw the grip at all, but the object remains moveable\n        /// </summary>\n        None\n    }\n\n    /// <summary>\n    /// Defines a specific type of button to search by\n    /// </summary>\n    public enum ButtonType\n    {\n        NormalButton,\n        SplitButton,\n        MenuItem,\n        DropDownButton\n    }\n\n    /// <summary>\n    /// Defines a method for background or object inheritence\n    /// </summary>\n    public enum InheritenceType\n    {\n        FromContentPanel,\n        None\n    }\n\n    /// <summary>\n    /// Defines a method of rendering\n    /// </summary>\n    public enum RenderingMode\n    {\n        System,\n        Professional,\n        Custom\n    }\n\n    #endregion\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/Renderer/ToolStripRenders.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Drawing;\n\nnamespace Sheng.Winform.Controls\n{\n    public static class ToolStripRenders\n    {\n        static ToolStripRenders()\n        {\n        }\n\n        private static SEToolStripRender _default;\n        public static SEToolStripRender Default\n        {\n            get\n            {\n                if (_default == null)\n                {\n                    _default = new SEToolStripRender();\n                    _default.Panels.ContentPanelTop = Color.FromArgb(241, 239, 228);\n\n                    _default.Toolstrip.BackgroundTop = Color.FromArgb(250, 249, 245);\n                    _default.Toolstrip.BackgroundBottom = Color.FromArgb(200, 199, 178);\n                    _default.Toolstrip.BorderBottom = Color.FromArgb(200, 199, 178);\n\n                    _default.StatusBar.DarkBorder = Color.FromArgb(250, 249, 245);\n                    _default.StatusBar.BackgroundTop = Color.FromArgb(250, 249, 245);\n                    _default.StatusBar.BackgroundBottom = Color.FromArgb(200, 199, 178);\n\n                    _default.Toolstrip.Curve = 0;\n                    _default.AlterColor = true;\n                    _default.OverrideColor = Color.Black;\n                }\n\n                return _default;\n            }\n        }\n\n        private static SEToolStripRender _mainMenu;\n        /// <summary>\n        /// 主菜单\n        /// </summary>\n        public static SEToolStripRender MainMenu\n        {\n            get\n            {\n                if (_mainMenu == null)\n                {\n                    _mainMenu = new SEToolStripRender();\n\n                    //_mainMenu.Panels.BackgroundAngle = 0;\n                    _mainMenu.Panels.ContentPanelTop = SystemColors.Control;\n                    //_mainMenu.Panels.ContentPanelBottom = Color.Yellow;\n\n                    _mainMenu.AlterColor = true;\n                    _mainMenu.OverrideColor = Color.Black;\n                }\n\n                return _mainMenu;\n            }\n        }\n\n        private static SEToolStripRender _transparentToolStrip;\n        /// <summary>\n        /// 背景透明的工具条\n        /// </summary>\n        public static SEToolStripRender TransparentToolStrip\n        {\n            get\n            {\n                if (_transparentToolStrip == null)\n                {\n                    _transparentToolStrip = new SEToolStripRender();\n\n                    _transparentToolStrip.Panels.ContentPanelTop = Color.Transparent;\n\n                    _transparentToolStrip.Toolstrip.BackgroundTop = Color.Transparent;\n                    _transparentToolStrip.Toolstrip.BackgroundBottom = Color.Transparent;\n                    _transparentToolStrip.Toolstrip.BorderTop = Color.Transparent;\n                    _transparentToolStrip.Toolstrip.BorderBottom = Color.Transparent;\n\n                    _transparentToolStrip.Toolstrip.Curve = 0;\n                    _transparentToolStrip.AlterColor = true;\n                    _transparentToolStrip.OverrideColor = Color.Black;\n                }\n\n                return _transparentToolStrip;\n            }\n        }\n\n        private static SEToolStripRender _silverGrayToWhite;\n        /// <summary>\n        /// 银白色至白色渐变\n        /// </summary>\n        public static SEToolStripRender SilverGrayToWhite\n        {\n            get\n            {\n                if (_silverGrayToWhite == null)\n                {\n                    _silverGrayToWhite = new SEToolStripRender();\n\n                    _silverGrayToWhite.Panels.ContentPanelTop = Color.FromArgb(243, 242, 236);\n                    _silverGrayToWhite.Toolstrip.BackgroundTop = Color.FromArgb(243, 242, 236);\n                    _silverGrayToWhite.Toolstrip.BackgroundBottom = Color.White;\n\n                    _silverGrayToWhite.Toolstrip.BorderBottom = Color.FromArgb(243, 242, 236);\n                    _silverGrayToWhite.Toolstrip.BorderTop = Color.FromArgb(243, 242, 236);\n\n                    _silverGrayToWhite.Toolstrip.Curve = 0;\n                    _silverGrayToWhite.AlterColor = true;\n                    _silverGrayToWhite.OverrideColor = Color.Black;\n                }\n\n                return _silverGrayToWhite;\n            }\n        }\n\n        private static SEToolStripRender _whiteToSilverGray;\n        /// <summary>\n        /// 白色至银白色渐变\n        /// </summary>\n        public static SEToolStripRender WhiteToSilverGray\n        {\n            get\n            {\n                if (_whiteToSilverGray == null)\n                {\n                    _whiteToSilverGray = new SEToolStripRender();\n\n                    _whiteToSilverGray.Panels.ContentPanelTop = Color.FromArgb(243, 242, 236);\n                    _whiteToSilverGray.Toolstrip.BackgroundTop = Color.White;\n                    _whiteToSilverGray.Toolstrip.BackgroundBottom = Color.FromArgb(243, 242, 236);\n\n                    _whiteToSilverGray.Toolstrip.BorderBottom = Color.FromArgb(243, 242, 236);\n                    _whiteToSilverGray.Toolstrip.BorderTop = Color.FromArgb(243, 242, 236);\n\n                    _whiteToSilverGray.Toolstrip.Curve = 0;\n                    _whiteToSilverGray.AlterColor = true;\n                    _whiteToSilverGray.OverrideColor = Color.Black;\n                }\n\n                return _whiteToSilverGray;\n            }\n        }\n\n        private static SEToolStripRender _controlToControlLight;\n        public static SEToolStripRender ControlToControlLight\n        {\n            get\n            {\n                if (_controlToControlLight == null)\n                {\n                    _controlToControlLight = new SEToolStripRender();\n\n                    _controlToControlLight.Panels.ContentPanelTop = SystemColors.Control;\n\n                    _controlToControlLight.Toolstrip.BackgroundTop = SystemColors.Control;\n                    _controlToControlLight.Toolstrip.BackgroundBottom = SystemColors.ControlLight;\n                    _controlToControlLight.Toolstrip.BorderTop = SystemColors.ControlLight;\n                    _controlToControlLight.Toolstrip.BorderBottom = SystemColors.ControlLight;\n\n                    _controlToControlLight.Toolstrip.Curve = 0;\n                    _controlToControlLight.AlterColor = true;\n                    _controlToControlLight.OverrideColor = Color.Black;\n                }\n\n                return _controlToControlLight;\n            }\n        }\n\n        private static SEToolStripRender _control;\n        public static SEToolStripRender Control\n        {\n            get\n            {\n                if (_control == null)\n                {\n                    _control = new SEToolStripRender();\n\n                    _control.Panels.ContentPanelTop = SystemColors.Control;\n\n                    _control.Toolstrip.BackgroundTop = SystemColors.Control;\n                    _control.Toolstrip.BackgroundBottom = SystemColors.Control;\n                    _control.Toolstrip.BorderTop = SystemColors.Control;\n                    _control.Toolstrip.BorderBottom = SystemColors.Control;\n                    _control.Toolstrip.Curve = 0;\n                    _control.AlterColor = true;\n                    _control.OverrideColor = Color.Black;\n                }\n\n                return _control;\n            }\n        }\n\n        private static SEToolStripRender _activateToolStrip;\n        /// <summary>\n        /// 当前工作区窗体所关联并激活的工具栏\n        /// </summary>\n        public static SEToolStripRender ActivateToolStrip\n        {\n            get\n            {\n                if (_activateToolStrip == null)\n                {\n                    _activateToolStrip = new SEToolStripRender();\n\n                    _activateToolStrip.Panels.ContentPanelTop = SystemColors.Control;\n\n                    _activateToolStrip.Toolstrip.BackgroundTop = SystemColors.Control;\n                    _activateToolStrip.Toolstrip.BackgroundBottom = Color.LightGreen;\n                    _activateToolStrip.Toolstrip.BorderTop = SystemColors.Control;\n                    _activateToolStrip.Toolstrip.BorderBottom = SystemColors.Control;\n                    _activateToolStrip.Toolstrip.Curve = 0;\n                    _activateToolStrip.AlterColor = true;\n                    _activateToolStrip.OverrideColor = Color.Black;\n                }\n\n                return _activateToolStrip;\n            }\n        }\n\n        private static SEToolStripRender _shell;\n        /// <summary>\n        /// 模拟运行时的外观\n        /// </summary>\n        public static SEToolStripRender Shell\n        {\n            get\n            {\n                if (_shell == null)\n                {\n                    _shell = new SEToolStripRender();\n                    _shell.Panels.ContentPanelTop = Color.FromArgb(241, 239, 228);\n\n                    _shell.Toolstrip.BackgroundTop = Color.FromArgb(250, 249, 245);\n                    _shell.Toolstrip.BackgroundBottom = Color.FromArgb(200, 199, 178);\n                    _shell.Toolstrip.BorderBottom = Color.FromArgb(200, 199, 178);\n\n                    _shell.StatusBar.DarkBorder = Color.FromArgb(250, 249, 245);\n                    _shell.StatusBar.BackgroundTop = Color.FromArgb(250, 249, 245);\n                    _shell.StatusBar.BackgroundBottom = Color.FromArgb(200, 199, 178);\n\n                    _shell.Toolstrip.Curve = 0;\n                    _shell.AlterColor = true;\n                    _shell.OverrideColor = Color.Black;\n                }\n\n                return _shell;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/SEControl.csproj.pdsync",
    "content": "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\n<ModelFileSync />"
  },
  {
    "path": "Sheng.Winform.Controls/SEFormShadow.Designer.cs",
    "content": "﻿namespace Sheng.SIMBE.SEControl\n{\n    partial class SEFormShadow\n    {\n        /// <summary>\n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Windows Form Designer generated code\n\n        /// <summary>\n        /// Required method for Designer support - do not modify\n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.components = new System.ComponentModel.Container();\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.Text = \"SEFormShadow\";\n        }\n\n        #endregion\n    }\n}"
  },
  {
    "path": "Sheng.Winform.Controls/SEFormShadow.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Data;\nusing System.Drawing;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\n\nnamespace Sheng.SIMBE.SEControl\n{\n    /// <summary>\n    /// 注意,此窗体不实现 ISEForm\n    /// </summary>\n    [LicenseProvider(typeof(SEControlLicenseProvider))]\n    public partial class SEFormShadow : Form\n    {\n        public SEFormShadow()\n        {\n            LicenseManager.Validate(typeof(SEFormShadow)); \n\n            InitializeComponent();\n\n            const int CS_DropSHADOW = 0x20000;\n            const int GCL_STYLE = (-26);\n\n            WinAPI.SetClassLong(this.Handle, GCL_STYLE, WinAPI.GetClassLong(this.Handle, GCL_STYLE) | CS_DropSHADOW);\n        }\n\n        protected override CreateParams CreateParams\n        {\n            get\n            {\n                CreateParams cp = base.CreateParams;\n\n                cp.Parent = WinAPI.GetWindow();\n                return cp;\n            }\n        }\n\n        private void SetWindowShadow(byte bAlpha)\n        {\n            WinAPI.SetWindowLong(this.Handle, (int)WinAPI.WindowStyle.GWL_EXSTYLE,\n            WinAPI.GetWindowLong(this.Handle, (int)WinAPI.WindowStyle.GWL_EXSTYLE) | (uint)WinAPI.ExWindowStyle.WS_EX_LAYERED);\n\n            WinAPI.SetLayeredWindowAttributes(this.Handle, 0, bAlpha, WinAPI.LWA_COLORKEY | WinAPI.LWA_ALPHA);\n        }\n    }\n}\n\n   \n\n\n"
  },
  {
    "path": "Sheng.Winform.Controls/SEImageListView.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Windows.Forms;\nusing System.ComponentModel;\nusing System.Drawing;\nusing System.IO;\nusing System.Collections;\nusing System.Drawing.Drawing2D;\nusing System.Threading;\nusing System.Drawing.Design;\nusing System.ComponentModel.Design.Serialization;\nusing System.CodeDom;\nusing System.ComponentModel.Design;\nusing System.Windows.Forms.Design;\nusing System.Runtime.InteropServices;\nusing System.Text;\n\nnamespace Sheng.SailingEase.Controls\n{\n    /// <summary>\n    /// Represents an image list view control.\n    /// </summary>\n    [ToolboxBitmap(typeof(SEImageListView))]\n    [Description(\"Represents an image list view control.\")]\n    [DefaultEvent(\"ItemClick\")]\n    [DefaultProperty(\"Items\")]\n    [Designer(typeof(ImageListViewDesigner))]\n    [DesignerSerializer(typeof(SEImageListViewSerializer), typeof(CodeDomSerializer))]\n    [Docking(DockingBehavior.Ask)]\n    public class SEImageListView : Control\n    {\n\n        #region Constants\n        /// <summary>\n        /// Default width of column headers in pixels.\n        /// </summary>\n        internal const int DefaultColumnWidth = 100;\n        #endregion\n\n        #region Member Variables\n        private BorderStyle mBorderStyle;\n        private ImageListViewColumnHeaderCollection mColumns;\n        private Image mDefaultImage;\n        private Image mErrorImage;\n        private Font mHeaderFont;\n        private ImageListViewItemCollection mItems;\n        private Size mItemMargin;\n        private ImageListViewRenderer mRenderer;\n        internal ImageListViewSelectedItemCollection mSelectedItems;\n        private EnumColumnType mSortColumn;\n        private EnumSortOrder mSortOrder;\n        private Size mThumbnailSize;\n        private EnumUseEmbeddedThumbnails mUseEmbeddedThumbnails;\n        private EnumView mView;\n        private Point mViewOffset;\n\n        // Layout variables\n        private System.Windows.Forms.Timer scrollTimer;\n        private System.Windows.Forms.HScrollBar hScrollBar;\n        private System.Windows.Forms.VScrollBar vScrollBar;\n        internal ImageListViewLayoutManager layoutManager;\n        private bool disposed;\n\n        // Interaction variables\n        internal NavInfo nav;\n\n        // Cache thread\n        internal ImageListViewCacheManager cacheManager;\n        internal ImageListViewItemCacheManager itemCacheManager;\n        #endregion\n\n        #region Properties\n        /// <summary>\n        /// Gets or sets whether column headers respond to mouse clicks.\n        /// </summary>\n        [Category(\"Behavior\"), Description(\"Gets or sets whether column headers respond to mouse clicks.\"), DefaultValue(true)]\n        public bool AllowColumnClick { get; set; }\n        /// <summary>\n        /// Gets or sets whether column headers can be resized with the mouse.\n        /// </summary>\n        [Category(\"Behavior\"), Description(\"Gets or sets whether column headers can be resized with the mouse.\"), DefaultValue(true)]\n        public bool AllowColumnResize { get; set; }\n        /// <summary>\n        /// Gets or sets whether the user can drag items for drag-and-drop operations.\n        /// </summary>\n        [Category(\"Behavior\"), Description(\"Gets or sets whether the user can drag items for drag-and-drop operations.\"), DefaultValue(false)]\n        public bool AllowDrag { get; set; }\n        /// <summary>\n        /// Gets or sets whether duplicate items (image files pointing to the same path \n        /// on the file system) are allowed.\n        /// </summary>\n        [Category(\"Behavior\"), Description(\"Gets or sets whether duplicate items (image files pointing to the same path on the file system) are allowed.\"), DefaultValue(false)]\n        public bool AllowDuplicateFileNames { get; set; }\n        /// <summary>\n        /// Gets or sets whether the user can reorder items by dragging.\n        /// </summary>\n        [Category(\"Behavior\"), Description(\"Gets or sets whether the user can reorder items by dragging.\"), DefaultValue(false)]\n        public bool AllowItemDrag { get; set; }\n        /// <summary>\n        /// Gets or sets the background color of the control.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the background color of the control.\"), DefaultValue(typeof(Color), \"Window\")]\n        public override Color BackColor { get { return base.BackColor; } set { base.BackColor = value; } }\n        /// <summary>\n        /// Gets or sets the border style of the control.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the border style of the control.\"), DefaultValue(typeof(BorderStyle), \"Fixed3D\")]\n        public BorderStyle BorderStyle { get { return mBorderStyle; } set { mBorderStyle = value; mRenderer.Refresh(); } }\n        /// <summary>\n        /// Gets ot sets the maximum number of thumbnail images to cache.\n        /// A value of 0 will disable the cache size limit.\n        /// </summary>\n        [Category(\"Behavior\"), DesignOnly(true), Description(\"Gets ot sets the maximum number of thumbnail images to cache. A value of 0 will disable the cache size limit.\"), DefaultValue(1000)]\n        public int CacheSize { get { return cacheManager.CacheSize; } set { cacheManager.CacheSize = value; } }\n        /// <summary>\n        /// Gets or sets the collection of columns of the image list view.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets the collection of columns of the image list view.\"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]\n        public ImageListViewColumnHeaderCollection Columns { get { return mColumns; } internal set { mColumns = value; mRenderer.Refresh(); } }\n        /// <summary>\n        /// Gets or sets the placeholder image.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the placeholder image.\")]\n        public Image DefaultImage { get { return mDefaultImage; } set { mDefaultImage = value; } }\n        /// <summary>\n        /// Gets the rectangle that represents the display area of the control.\n        /// </summary>\n        [Category(\"Appearance\"), Browsable(false), Description(\"Gets the rectangle that represents the display area of the control.\")]\n        public override Rectangle DisplayRectangle\n        {\n            get\n            {\n                return layoutManager.ClientArea;\n            }\n        }\n        /// <summary>\n        /// Gets or sets the error image.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the error image.\")]\n        public Image ErrorImage { get { return mErrorImage; } set { mErrorImage = value; } }\n        /// <summary>\n        /// Gets or sets the font of the column headers.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the font of the column headers.\"), DefaultValue(typeof(Font), \"Microsoft Sans Serif; 8.25pt\")]\n        public Font HeaderFont\n        {\n            get\n            {\n                return mHeaderFont;\n            }\n            set\n            {\n                if (mHeaderFont != null)\n                    mHeaderFont.Dispose();\n                mHeaderFont = (Font)value.Clone();\n                mRenderer.Refresh();\n            }\n        }\n        /// <summary>\n        /// Gets the collection of items contained in the image list view.\n        /// </summary>\n        [Browsable(false), Category(\"Behavior\"), Description(\"Gets the collection of items contained in the image list view.\")]\n        public SEImageListView.ImageListViewItemCollection Items { get { return mItems; } }\n        /// <summary>\n        /// Gets or sets the spacing between items.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the spacing between items.\"), DefaultValue(typeof(Size), \"4,4\")]\n        public Size ItemMargin { get { return mItemMargin; } set { mItemMargin = value; mRenderer.Refresh(); } }\n        /// <summary>\n        /// Gets the collection of selected items contained in the image list view.\n        /// </summary>\n        [Browsable(false), Category(\"Behavior\"), Description(\"Gets the collection of selected items contained in the image list view.\")]\n        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]\n        public SEImageListView.ImageListViewSelectedItemCollection SelectedItems { get { return mSelectedItems; } }\n        /// <summary>\n        /// Gets or sets the sort column.\n        /// </summary>\n        [Category(\"Appearance\"), DefaultValue(typeof(EnumColumnType), \"Name\"), Description(\"Gets or sets the sort column.\")]\n        public EnumColumnType SortColumn { get { return mSortColumn; } set { mSortColumn = value; Sort(); } }\n        /// <summary>\n        /// Gets or sets the sort order.\n        /// </summary>\n        [Category(\"Appearance\"), DefaultValue(typeof(EnumSortOrder), \"None\"), Description(\"Gets or sets the sort order.\")]\n        public EnumSortOrder SortOrder { get { return mSortOrder; } set { mSortOrder = value; Sort(); } }\n        /// <summary>\n        /// This property is not relevant for this class.\n        /// </summary>\n        [EditorBrowsable(EditorBrowsableState.Never), Browsable(false), Bindable(false), DefaultValue(null)]\n        public override string Text { get; set; }\n        /// <summary>\n        /// Gets or sets the size of image thumbnails.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the size of image thumbnails.\"), DefaultValue(typeof(Size), \"96,96\")]\n        public Size ThumbnailSize\n        {\n            get\n            {\n                return mThumbnailSize;\n            }\n            set\n            {\n                if (mThumbnailSize != value)\n                {\n                    mThumbnailSize = value;\n                    cacheManager.Clean();\n                    mRenderer.Refresh();\n                }\n            }\n        }\n        /// <summary>\n        /// Gets or sets the embedded thumbnails extraction behavior.\n        /// </summary>\n        [Category(\"Behavior\"), Description(\"Gets or sets the embedded thumbnails extraction behavior.\"), DefaultValue(typeof(EnumUseEmbeddedThumbnails), \"Auto\")]\n        public EnumUseEmbeddedThumbnails UseEmbeddedThumbnails\n        {\n            get\n            {\n                return mUseEmbeddedThumbnails;\n            }\n            set\n            {\n                if (mUseEmbeddedThumbnails != value)\n                {\n                    mUseEmbeddedThumbnails = value;\n                    cacheManager.Clean();\n                    mRenderer.Refresh();\n                }\n            }\n        }\n        /// <summary>\n        /// Gets or sets the view mode of the image list view.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the view mode of the image list view.\"), DefaultValue(typeof(EnumView), \"Thumbnails\")]\n        public EnumView View\n        {\n            get\n            {\n                return mView;\n            }\n            set\n            {\n                mRenderer.SuspendPaint();\n                int current = layoutManager.FirstVisible;\n                mView = value;\n                layoutManager.Update();\n                EnsureVisible(current);\n                mRenderer.Refresh();\n                mRenderer.ResumePaint();\n            }\n        }\n        /// <summary>\n        /// Gets or sets the scroll offset.\n        /// </summary>\n        internal Point ViewOffset { get { return mViewOffset; } set { mViewOffset = value; } }\n        #endregion\n\n        #region Constructor\n        public SEImageListView()\n        {\n            SetRenderer(new ImageListViewRenderer());\n\n            AllowColumnClick = true;\n            AllowColumnResize = true;\n            AllowDrag = false;\n            AllowDuplicateFileNames = false;\n            AllowItemDrag = false;\n            BackColor = SystemColors.Window;\n            mBorderStyle = BorderStyle.Fixed3D;\n            mColumns = new ImageListViewColumnHeaderCollection(this);\n            DefaultImage = Utility.ImageFromBase64String(@\"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAdRJREFUOE+lk81LG1EUxeufVXFVUcSNlFIJ6ErUjaQUtYrfxrgQQewq2NKWVpN0nKdGRV1ELZRWdO9ClMyorUnTmMxnzAxicnrfWKIxUUEHfsN83Dn3zH3nlQF48qiDCzT0iROubhavdgtaeWsJmunZNSrbBO15pzDpNOcnVw/7G5HlnGGaMNMWDEInVAcbimkjZdg4dbAQV3TUvhbVvADvrBsmGj0+dH0KYuCLH72fGXqnw+ifCWPQH8ZwcB1eYQMtw5NI6Baq3EzLC1SQbd7Z41/DfMTAonyGkGQgJGcQOrSwdGRj+fgcK78vMMa+Ia6WEOCW+cvVaA6rJ9lb4TV/1Aw5EAsd8P/1BtawKJ2RA+ospcmNDnZgYo5g+wYWDlSMBlYQU9LFAopp4ZXvAz5uxzC19Qu+n4cY29zBSPgE3v+8+76LvvcBxFIlHKRouvVDQXSI8iWzEjoECe1fIwW8HPAXC/C1T9JkXSNzeDMfvRNeE73pgAucao8QeNoc1JIk8KzJ47i4C14TTWZQ2XZtFcodgQz24lkidw9ZErAKBWrcwnEiqUCjQWoUW9WBYkz3ShE2Ek6U2VWUX3SK43Xt7AcPB7d2H7QPNPrmbT7K/OKh/ANGwthSNAtyCAAAAABJRU5ErkJggg==\");\n            ErrorImage = Utility.ImageFromBase64String(@\"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAnpJREFUOE+lk/9LE3EYx+tf0TDtCyERhD9ofkHMvhg780t6zE3nZi2njExqN/dNckWihphEqJlDISiwgkpNJCQijLKIuozUbmtufpl3zpsF7+4+cDeViKAHnoODz/v1fp7n83x2AtjxXyEDNuev5rOJG54aJuYysusOA79mr+R5m46NXNIyyxfpxO3nt4glIRVzmfxL7loIvg6ID3tJ8r52BBkTQtZSf7C+iNoMUQExt4kSndVCpMuDn6NDEPuvIuo9R1K848XGyCDCHU34btYIczUFKoQARKcxIdpk4Fa63ES85qokqQRv14G3VSD2xIeF65fxtSqfY/V5CWR+8kfq0x52muNipx6CQ68CpP6x0qjFcgMN8dEAZupofKSz7SpAOsDKfYp9LUSoOCoEWbhkLUe4rgyRGy6Eb3rxriSdVQGLDWVR8XEfBI+RlKo4KgBZGKo9gwVzKYIWLSKDtzBFpUVVQLC+OLo+3ItVh0EtVXbc+DRNGLLwR00JAsZiBMw0IgPdeFVwKA7gzmvYlZ5WCN0etVTZMXK7Dfx9HxH6DUXg9KcR8jIItDdjMj813sKs6aT9m7UC68N31VJlRyVk4byuEHNaCqtDPXirO4WJ3P3xIX6pPJrwuSKX87c0Yu1Bv+q42OGV7r6FCGdpDRHPMBaM5+zlxrJS4tcoD+NDeRY1XZohzHsuQLjXh/A1aWmM5ZivLsPCFUYanCS2WfA8O0UYzdy9dZGU1XxTmEa91hz2v6/SINAmzaO3E4s9neBa3Ziij2M0M9n/LCPpz6usQF6eOJg4eSyVeZF3gJ3I3ceP5+zhx7KS2ZEjSczT9F1/f0zbX9q//P8GR0WnSFUgshMAAAAASUVORK5CYII=\");\n            HeaderFont = this.Font;\n            mItems = new ImageListViewItemCollection(this);\n            mItemMargin = new Size(4, 4);\n            mSelectedItems = new ImageListViewSelectedItemCollection(this);\n            mSortColumn = EnumColumnType.Name;\n            mSortOrder = EnumSortOrder.None;\n            SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint | ControlStyles.Opaque | ControlStyles.Selectable | ControlStyles.UserMouse, true);\n            Size = new Size(120, 100);\n            mThumbnailSize = new Size(96, 96);\n            mUseEmbeddedThumbnails = EnumUseEmbeddedThumbnails.Auto;\n            mView = EnumView.Thumbnails;\n\n            scrollTimer = new System.Windows.Forms.Timer();\n            scrollTimer.Interval = 100;\n            scrollTimer.Enabled = false;\n            scrollTimer.Tick += new EventHandler(scrollTimer_Tick);\n\n            mViewOffset = new Point(0, 0);\n            hScrollBar = new System.Windows.Forms.HScrollBar();\n            vScrollBar = new System.Windows.Forms.VScrollBar();\n            hScrollBar.Visible = false;\n            vScrollBar.Visible = false;\n            hScrollBar.Scroll += new ScrollEventHandler(hScrollBar_Scroll);\n            vScrollBar.Scroll += new ScrollEventHandler(vScrollBar_Scroll);\n            Controls.Add(hScrollBar);\n            Controls.Add(vScrollBar);\n            layoutManager = new ImageListViewLayoutManager(this);\n\n            nav = new NavInfo();\n\n            cacheManager = new ImageListViewCacheManager(this, 1000);\n            cacheManager.Start();\n            itemCacheManager = new ImageListViewItemCacheManager(this);\n            itemCacheManager.Start();\n\n            disposed = false;\n        }\n        #endregion\n\n        #region Instance Methods\n        /// <summary>\n        /// Temporarily suspends the layout logic for the control.\n        /// </summary>\n        public new void SuspendLayout()\n        {\n            base.SuspendLayout();\n            mRenderer.SuspendPaint();\n        }\n        /// <summary>\n        /// Resumes usual layout logic.\n        /// </summary>\n        public new void ResumeLayout()\n        {\n            ResumeLayout(false);\n        }\n        /// <summary>\n        /// Resumes usual layout logic, optionally forcing an immediate layout of pending layout requests.\n        /// </summary>\n        /// <param name=\"performLayout\">true to execute pending layout requests; otherwise, false.</param>\n        public new void ResumeLayout(bool performLayout)\n        {\n            base.ResumeLayout(performLayout);\n            if (performLayout) mRenderer.Refresh();\n            mRenderer.ResumePaint();\n        }\n        /// <summary>\n        /// Sets the properties of the specified column header.\n        /// </summary>\n        /// <param name=\"type\">The column header to modify.</param>\n        /// <param name=\"text\">Column header text.</param>\n        /// <param name=\"width\">Width (in pixels) of the column header.</param>\n        /// <param name=\"displayIndex\">Display index of the column header.</param>\n        /// <param name=\"visible\">true if the column header will be shown; otherwise false.</param>\n        public void SetColumnHeader(EnumColumnType type, string text, int width, int displayIndex, bool visible)\n        {\n            mRenderer.SuspendPaint();\n            ImageListViewColumnHeader col = Columns[type];\n            col.Text = text;\n            col.Width = width;\n            col.DisplayIndex = displayIndex;\n            col.Visible = visible;\n            mRenderer.Refresh();\n            mRenderer.ResumePaint();\n        }\n        /// <summary>\n        /// Sets the properties of the specified column header.\n        /// </summary>\n        /// <param name=\"type\">The column header to modify.</param>\n        /// <param name=\"width\">Width (in pixels) of the column header.</param>\n        /// <param name=\"displayIndex\">Display index of the column header.</param>\n        /// <param name=\"visible\">true if the column header will be shown; otherwise false.</param>\n        public void SetColumnHeader(EnumColumnType type, int width, int displayIndex, bool visible)\n        {\n            mRenderer.SuspendPaint();\n            ImageListViewColumnHeader col = Columns[type];\n            col.Width = width;\n            col.DisplayIndex = displayIndex;\n            col.Visible = visible;\n            mRenderer.Refresh();\n            mRenderer.ResumePaint();\n        }\n        /// <summary>\n        /// Sets the renderer for this instance.\n        /// </summary>\n        public void SetRenderer(ImageListViewRenderer renderer)\n        {\n            mRenderer = renderer;\n            mRenderer.mImageListView = this;\n        }\n        /// <summary>\n        /// Sorts the items.\n        /// </summary>\n        public void Sort()\n        {\n            mItems.Sort();\n            mRenderer.Refresh();\n        }\n        /// <summary>\n        /// Marks all items as selected.\n        /// </summary>\n        public void SelectAll()\n        {\n            mRenderer.SuspendPaint();\n\n            foreach (ImageListViewItem item in Items)\n                item.mSelected = true;\n\n            OnSelectionChangedInternal();\n\n            mRenderer.Refresh();\n            mRenderer.ResumePaint();\n        }\n        /// <summary>\n        /// Marks all items as unselected.\n        /// </summary>\n        public void ClearSelection()\n        {\n            mRenderer.SuspendPaint();\n            mSelectedItems.Clear();\n            mRenderer.Refresh();\n            mRenderer.ResumePaint();\n        }\n        /// <summary>\n        /// Determines the image list view element under the specified coordinates.\n        /// </summary>\n        /// <param name=\"pt\">The client coordinates of the point to be tested.</param>\n        /// <param name=\"hitInfo\">Details of the hit test.</param>\n        /// <returns>true if the point is over an item or column; false otherwise.</returns>\n        public bool HitTest(Point pt, out HitInfo hitInfo)\n        {\n            int sepSize = 12;\n\n            hitInfo = new HitInfo();\n            hitInfo.ColumnHit = false;\n            hitInfo.ItemHit = false;\n            hitInfo.ColumnSeparatorHit = false;\n            hitInfo.ColumnIndex = (EnumColumnType)(-1);\n            hitInfo.ItemIndex = -1;\n            hitInfo.ColumnSeparator = (EnumColumnType)(-1);\n            int headerHeight = mRenderer.MeasureColumnHeaderHeight();\n\n            if (View == EnumView.Details && pt.Y <= headerHeight + (BorderStyle == BorderStyle.None ? 0 : 1))\n            {\n                hitInfo.InHeaderArea = true;\n                int i = 0;\n                int x = layoutManager.ColumnHeaderBounds.Left;\n                foreach (ImageListViewColumnHeader col in Columns.GetUIColumns())\n                {\n                    // Over a column?\n                    if (pt.X >= x && pt.X < x + col.Width + sepSize / 2)\n                    {\n                        hitInfo.ColumnHit = true;\n                        hitInfo.ColumnIndex = col.Type;\n                    }\n                    // Over a colummn separator?\n                    if (pt.X > x + col.Width - sepSize / 2 && pt.X < x + col.Width + sepSize / 2)\n                    {\n                        hitInfo.ColumnSeparatorHit = true;\n                        hitInfo.ColumnSeparator = col.Type;\n                    }\n                    if (hitInfo.ColumnHit) break;\n                    x += col.Width;\n                    i++;\n                }\n            }\n            else\n            {\n                hitInfo.InItemArea = true;\n                // Normalize to item area coordinates\n                pt.X -= layoutManager.ItemAreaBounds.Left;\n                pt.Y -= layoutManager.ItemAreaBounds.Top;\n\n                int col = pt.X / layoutManager.ItemSizeWithMargin.Width;\n                int row = (pt.Y + mViewOffset.Y) / layoutManager.ItemSizeWithMargin.Height;\n\n                if (col <= layoutManager.Cols)\n                {\n                    int index = row * layoutManager.Cols + col;\n                    if (index >= 0 && index < Items.Count)\n                    {\n                        Rectangle bounds = layoutManager.GetItemBounds(index);\n                        if (bounds.Contains(pt.X + layoutManager.ItemAreaBounds.Left, pt.Y + layoutManager.ItemAreaBounds.Top))\n                        {\n                            hitInfo.ItemHit = true;\n                            hitInfo.ItemIndex = index;\n                        }\n                    }\n                }\n            }\n\n            return (hitInfo.ColumnHit || hitInfo.ColumnSeparatorHit || hitInfo.ItemHit);\n        }\n        /// <summary>\n        /// Scrolls the image list view to ensure that the item with the specified \n        /// index is visible on the screen.\n        /// </summary>\n        /// <param name=\"itemIndex\">The index of the item to make visible.</param>\n        /// <returns>true if the item was made visible; otherwise false (item is already visible or the image list view is empty).</returns>\n        public bool EnsureVisible(int itemIndex)\n        {\n            if (itemIndex == -1) return false;\n            if (Items.Count == 0) return false;\n\n            mRenderer.SuspendPaint();\n            bool ret = false;\n            // Already visible?\n            Rectangle bounds = layoutManager.ItemAreaBounds;\n            Rectangle itemBounds = layoutManager.GetItemBounds(itemIndex);\n            if (!bounds.Contains(itemBounds))\n            {\n                int delta = 0;\n                if (itemBounds.Top < bounds.Top)\n                    delta = bounds.Top - itemBounds.Top;\n                else\n                {\n                    int topItemIndex = itemIndex - (layoutManager.Rows - 1) * layoutManager.Cols;\n                    if (topItemIndex < 0) topItemIndex = 0;\n                    delta = bounds.Top - layoutManager.GetItemBounds(topItemIndex).Top;\n                }\n                int newYOffset = mViewOffset.Y - delta;\n                if (newYOffset > vScrollBar.Maximum - vScrollBar.LargeChange + 1)\n                    newYOffset = vScrollBar.Maximum - vScrollBar.LargeChange + 1;\n                if (newYOffset < vScrollBar.Minimum)\n                    newYOffset = vScrollBar.Minimum;\n                mViewOffset.X = 0;\n                mViewOffset.Y = newYOffset;\n                hScrollBar.Value = 0;\n                vScrollBar.Value = newYOffset;\n                mRenderer.Refresh();\n                ret = true;\n            }\n            mRenderer.ResumePaint();\n            return ret;\n        }\n        /// <summary>\n        /// Determines whether the specified item is visible on the screen.\n        /// </summary>\n        /// <param name=\"item\">The item to test.</param>\n        /// <returns>An ItemVisibility value.</returns>\n        public EnumItemVisibility IsItemVisible(ImageListViewItem item)\n        {\n            return IsItemVisible(mItems.IndexOf(item));\n        }\n        #endregion\n\n        #region Helper Methods\n        /// <summary>\n        /// Returns the item index after applying the given navigation key.\n        /// </summary>\n        private int ApplyNavKey(int index, System.Windows.Forms.Keys key)\n        {\n            if (key == Keys.Up && index >= layoutManager.Cols)\n                index -= layoutManager.Cols;\n            else if (key == Keys.Down && index < Items.Count - layoutManager.Cols)\n                index += layoutManager.Cols;\n            else if (key == Keys.Left && index > 0)\n                index--;\n            else if (key == Keys.Right && index < Items.Count)\n                index++;\n            else if (key == Keys.PageUp && index >= layoutManager.Cols * (layoutManager.Rows - 1))\n                index -= layoutManager.Cols * (layoutManager.Rows - 1);\n            else if (key == Keys.PageDown && index < Items.Count - layoutManager.Cols * (layoutManager.Rows - 1))\n                index += layoutManager.Cols * (layoutManager.Rows - 1);\n            else if (key == Keys.Home)\n                index = 0;\n            else if (key == Keys.End)\n                index = Items.Count - 1;\n\n            if (index < 0)\n                index = 0;\n            else if (index > Items.Count - 1)\n                index = Items.Count - 1;\n\n            return index;\n        }\n        /// <summary>\n        /// Determines whether the specified item is visible on the screen.\n        /// </summary>\n        /// <param name=\"item\">The Guid of the item to test.</param>\n        /// <returns>true if the item is visible or partially visible; otherwise false.</returns>\n        internal bool IsItemVisible(Guid guid)\n        {\n            return layoutManager.IsItemVisible(guid);\n        }\n        /// <summary>\n        /// Determines whether the specified item is visible on the screen.\n        /// </summary>\n        /// <param name=\"item\">The item to test.</param>\n        /// <returns>An ItemVisibility value.</returns>\n        internal EnumItemVisibility IsItemVisible(int itemIndex)\n        {\n            if (mItems.Count == 0) return EnumItemVisibility.NotVisible;\n            if (itemIndex < 0 || itemIndex > mItems.Count - 1) return EnumItemVisibility.NotVisible;\n\n            if (itemIndex < layoutManager.FirstPartiallyVisible || itemIndex > layoutManager.LastPartiallyVisible)\n                return EnumItemVisibility.NotVisible;\n            else if (itemIndex >= layoutManager.FirstVisible && itemIndex <= layoutManager.LastVisible)\n                return EnumItemVisibility.Visible;\n            else\n                return EnumItemVisibility.PartiallyVisible;\n        }\n        /// <summary>\n        /// Sets the column header colection.\n        /// </summary>\n        internal void SetColumnsInternal(ImageListViewColumnHeaderCollection columns)\n        {\n            /// TODO: This is called by the collection editor to set the Columns collection.\n            /// Current implementation does not support undoing in the IDE. Columns should\n            /// instead be set in the collection editor using its PropertyDescriptor.\n            /// However, the Columns property does not have a public setter, \n            /// and this seems to pose a problem; the collection editor can not set\n            /// the Columns if I set the Columns through its PropertyDescriptor in the\n            /// collection editor.\n            mColumns = columns;\n            mRenderer.Refresh();\n        }\n        #endregion\n\n        #region Event Handlers\n        /// <summary>\n        /// Handles the DragOver event.\n        /// </summary>\n        protected override void OnDragOver(DragEventArgs e)\n        {\n            base.OnDragOver(e);\n\n            if (AllowItemDrag && nav.SelfDragging)\n            {\n                e.Effect = DragDropEffects.Move;\n\n                // Calculate the location of the insertion cursor\n                Point pt = new Point(e.X, e.Y);\n                pt = PointToClient(pt);\n                // Normalize to item area coordinates\n                pt.X -= layoutManager.ItemAreaBounds.Left;\n                pt.Y -= layoutManager.ItemAreaBounds.Top;\n                // Row and column mouse is over\n                bool dragCaretOnRight = false;\n                int col = pt.X / layoutManager.ItemSizeWithMargin.Width;\n                int row = (pt.Y + mViewOffset.Y) / layoutManager.ItemSizeWithMargin.Height;\n                if (col > layoutManager.Cols - 1)\n                {\n                    col = layoutManager.Cols - 1;\n                    dragCaretOnRight = true;\n                }\n                // Index of the item mouse is over\n                int index = row * layoutManager.Cols + col;\n                if (index < 0) index = 0;\n                if (index > Items.Count - 1)\n                {\n                    index = Items.Count - 1;\n                    dragCaretOnRight = true;\n                }\n                if (index != nav.DragIndex || dragCaretOnRight != nav.DragCaretOnRight)\n                {\n                    nav.DragIndex = index;\n                    nav.DragCaretOnRight = dragCaretOnRight;\n                    mRenderer.Refresh(true);\n                }\n            }\n            else\n                e.Effect = DragDropEffects.None;\n        }\n        /// <summary>\n        /// Handles the DragEnter event.\n        /// </summary>\n        protected override void OnDragEnter(DragEventArgs e)\n        {\n            base.OnDragEnter(e);\n\n            if (!nav.SelfDragging && e.Data.GetDataPresent(DataFormats.FileDrop))\n                e.Effect = DragDropEffects.Copy;\n            else\n                e.Effect = DragDropEffects.None;\n        }\n        /// <summary>\n        /// Handles the DragLeave event.\n        /// </summary>\n        protected override void OnDragLeave(EventArgs e)\n        {\n            base.OnDragLeave(e);\n\n            if (AllowItemDrag && nav.SelfDragging)\n            {\n                nav.DragIndex = -1;\n                mRenderer.Refresh(true);\n            }\n        }\n\n        /// <summary>\n        /// Handles the DragDrop event.\n        /// </summary>\n        protected override void OnDragDrop(DragEventArgs e)\n        {\n            base.OnDragDrop(e);\n\n            mRenderer.SuspendPaint();\n\n            if (nav.SelfDragging)\n            {\n                // Reorder items\n                List<ImageListViewItem> draggedItems = new List<ImageListViewItem>();\n                int i = nav.DragIndex;\n                foreach (ImageListViewItem item in mSelectedItems)\n                {\n                    if (item.Index <= i) i--;\n                    draggedItems.Add(item);\n                    mItems.RemoveInternal(item);\n                }\n                if (i < 0) i = 0;\n                if (i > mItems.Count - 1) i = mItems.Count - 1;\n                if (nav.DragCaretOnRight) i++;\n                foreach (ImageListViewItem item in draggedItems)\n                {\n                    item.mSelected = false;\n                    mItems.InsertInternal(i, item);\n                    i++;\n                }\n                OnSelectionChanged(new EventArgs());\n            }\n            else\n            {\n                // Add items\n                foreach (string filename in (string[])e.Data.GetData(DataFormats.FileDrop))\n                {\n                    try\n                    {\n                        using (FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read))\n                        {\n                            using (Image img = Image.FromStream(stream, false, false))\n                            {\n                                mItems.Add(filename);\n                            }\n                        }\n                    }\n                    catch\n                    {\n                        ;\n                    }\n                }\n            }\n\n            nav.DragIndex = -1;\n            nav.SelfDragging = false;\n\n            mRenderer.ResumePaint();\n        }\n        /// <summary>\n        /// Handles the Scroll event of the vScrollBar control.\n        /// </summary>\n        private void vScrollBar_Scroll(object sender, ScrollEventArgs e)\n        {\n            mViewOffset.Y = e.NewValue;\n            mRenderer.Refresh();\n        }\n        /// <summary>\n        /// Handles the Scroll event of the hScrollBar control.\n        /// </summary>\n        private void hScrollBar_Scroll(object sender, ScrollEventArgs e)\n        {\n            mViewOffset.X = e.NewValue;\n            mRenderer.Refresh();\n        }\n        /// <summary>\n        /// Handles the Tick event of the scrollTimer control.\n        /// </summary>\n        private void scrollTimer_Tick(object sender, EventArgs e)\n        {\n            int delta = (int)scrollTimer.Tag;\n            if (nav.Dragging)\n            {\n                Point location = base.PointToClient(Control.MousePosition);\n                OnMouseMove(new MouseEventArgs(Control.MouseButtons, 0, location.X, location.Y, 0));\n            }\n            OnMouseWheel(new MouseEventArgs(MouseButtons.None, 0, 0, 0, delta));\n        }\n        /// <summary>\n        /// Handles the Resize event.\n        /// </summary>\n        protected override void OnResize(EventArgs e)\n        {\n            base.OnResize(e);\n\n            //cxs\n            //如果窗体不可见，以下不执行，否则在Update方法中会因为垂直滚动条的显示设置而形成死循环\n            if (this.FindForm() != null && this.FindForm().Visible == true)\n            {\n                if (!disposed && mRenderer != null)\n                    mRenderer.RecreateBuffer();\n\n                if (hScrollBar == null)\n                    return;\n\n                layoutManager.Update();\n                mRenderer.Refresh();\n            }\n        }\n        /// <summary>\n        /// Handles the Paint event.\n        /// </summary>\n        protected override void OnPaint(PaintEventArgs e)\n        {\n            if (!disposed && mRenderer != null)\n                mRenderer.Render(e.Graphics);\n        }\n        /// <summary>\n        /// Handles the MouseDown event.\n        /// </summary>\n        protected override void OnMouseDown(MouseEventArgs e)\n        {\n            nav.ClickedItem = null;\n            nav.HoveredItem = null;\n            nav.HoveredColumn = (EnumColumnType)(-1);\n            nav.HoveredSeparator = (EnumColumnType)(-1);\n            nav.SelSeperator = (EnumColumnType)(-1);\n\n            HitInfo h;\n            HitTest(e.Location, out h);\n\n            if (h.ItemHit && (((e.Button & MouseButtons.Left) == MouseButtons.Left) || ((e.Button & MouseButtons.Right) == MouseButtons.Right)))\n                nav.ClickedItem = mItems[h.ItemIndex];\n            if (h.ItemHit)\n                nav.HoveredItem = mItems[h.ItemIndex];\n            if (h.ColumnHit)\n                nav.HoveredColumn = h.ColumnIndex;\n            if (h.ColumnSeparatorHit)\n                nav.HoveredSeparator = h.ColumnSeparator;\n\n            nav.MouseInColumnArea = h.InHeaderArea;\n            nav.MouseInItemArea = h.InItemArea;\n\n            if ((e.Button & MouseButtons.Left) == MouseButtons.Left || (e.Button & MouseButtons.Right) == MouseButtons.Right)\n                nav.MouseClicked = true;\n\n            mRenderer.SuspendPaint();\n\n            if ((e.Button & MouseButtons.Left) == MouseButtons.Left && AllowColumnResize && nav.HoveredSeparator != (EnumColumnType)(-1))\n            {\n                nav.DraggingSeperator = true;\n                nav.SelSeperator = nav.HoveredSeparator;\n                nav.SelStart = e.Location;\n                mRenderer.Refresh();\n            }\n            else if ((e.Button & MouseButtons.Left) == MouseButtons.Left && AllowColumnClick && nav.HoveredColumn != (EnumColumnType)(-1))\n            {\n                if (SortColumn == nav.HoveredColumn)\n                {\n                    if (SortOrder == EnumSortOrder.Descending)\n                        SortOrder = EnumSortOrder.Ascending;\n                    else\n                        SortOrder = EnumSortOrder.Descending;\n                }\n                else\n                {\n                    SortColumn = nav.HoveredColumn;\n                    SortOrder = EnumSortOrder.Ascending;\n                }\n                mRenderer.Refresh();\n            }\n            else if (((e.Button & MouseButtons.Left) == MouseButtons.Left || (e.Button & MouseButtons.Right) == MouseButtons.Right) && nav.MouseInItemArea)\n            {\n                nav.SelStart = e.Location;\n                nav.SelEnd = e.Location;\n                mRenderer.Refresh();\n            }\n\n            mRenderer.ResumePaint();\n\n            base.OnMouseDown(e);\n        }\n        /// <summary>\n        /// Handles the MouseUp event.\n        /// </summary>\n        protected override void OnMouseUp(MouseEventArgs e)\n        {\n            bool suppressClick = nav.Dragging;\n            nav.SelfDragging = false;\n\n            scrollTimer.Enabled = false;\n            mRenderer.SuspendPaint();\n\n            if ((e.Button & MouseButtons.Left) == MouseButtons.Left && nav.DraggingSeperator)\n            {\n                OnColumnWidthChanged(new ColumnEventArgs(Columns[nav.SelSeperator]));\n                nav.DraggingSeperator = false;\n            }\n            else if (((e.Button & MouseButtons.Left) == MouseButtons.Left || (e.Button & MouseButtons.Right) == MouseButtons.Right) && nav.MouseClicked)\n            {\n                bool clear = true;\n                if (nav.ControlDown) clear = false;\n                if (nav.ShiftDown && nav.Dragging) clear = false;\n                if (!nav.Dragging && ((e.Button & MouseButtons.Right) == MouseButtons.Right))\n                {\n                    if (nav.HoveredItem != null && nav.HoveredItem.Selected)\n                        clear = false;\n                }\n                if (clear)\n                    ClearSelection();\n\n                if (nav.Dragging)\n                {\n                    if (nav.Highlight.Count != 0)\n                    {\n                        foreach (KeyValuePair<ImageListViewItem, bool> pair in nav.Highlight)\n                            pair.Key.mSelected = pair.Value;\n                        OnSelectionChanged(new EventArgs());\n                        nav.Highlight.Clear();\n                    }\n                    nav.Dragging = false;\n                }\n                else if (nav.ControlDown && nav.HoveredItem != null)\n                {\n                    nav.HoveredItem.Selected = !nav.HoveredItem.Selected;\n                }\n                else if (nav.ShiftDown && nav.HoveredItem != null && Items.FocusedItem != null)\n                {\n                    int focusedIndex = mItems.IndexOf(mItems.FocusedItem);\n                    int hoveredIndex = mItems.IndexOf(nav.HoveredItem);\n                    int start = System.Math.Min(focusedIndex, hoveredIndex);\n                    int end = System.Math.Max(focusedIndex, hoveredIndex);\n                    for (int i = start; i <= end; i++)\n                        Items[i].Selected = true;\n                }\n                else if (nav.HoveredItem != null)\n                {\n                    nav.HoveredItem.Selected = true;\n                }\n\n                // Move focus to the item under the cursor\n                if (!(!nav.Dragging && nav.ShiftDown) && nav.HoveredItem != null)\n                    Items.FocusedItem = nav.HoveredItem;\n\n                nav.Dragging = false;\n                nav.DraggingSeperator = false;\n\n                mRenderer.Refresh();\n\n                if (AllowColumnClick && nav.HoveredColumn != (EnumColumnType)(-1))\n                {\n                    OnColumnClick(new ColumnClickEventArgs(Columns[nav.HoveredColumn], e.Location, e.Button));\n                }\n            }\n\n            if (!suppressClick && nav.HoveredItem != null)\n                OnItemClick(new ItemClickEventArgs(nav.HoveredItem, e.Location, e.Button));\n\n            if ((e.Button & MouseButtons.Left) == MouseButtons.Left || (e.Button & MouseButtons.Right) == MouseButtons.Right)\n                nav.MouseClicked = false;\n\n            mRenderer.ResumePaint();\n\n            base.OnMouseUp(e);\n        }\n        /// <summary>\n        /// Handles the MouseMove event.\n        /// </summary>\n        protected override void OnMouseMove(MouseEventArgs e)\n        {\n            mRenderer.SuspendPaint();\n\n            ImageListViewItem oldHoveredItem = nav.HoveredItem;\n            EnumColumnType oldHoveredColumn = nav.HoveredColumn;\n            EnumColumnType oldHoveredSeparator = nav.HoveredSeparator;\n            EnumColumnType oldSelSeperator = nav.SelSeperator;\n            EnumColumnType oldSelSep = nav.SelSeperator;\n            nav.HoveredItem = null;\n            nav.HoveredColumn = (EnumColumnType)(-1);\n            nav.HoveredSeparator = (EnumColumnType)(-1);\n            nav.SelSeperator = (EnumColumnType)(-1);\n\n            HitInfo h;\n            HitTest(e.Location, out h);\n\n            if (h.ItemHit)\n                nav.HoveredItem = mItems[h.ItemIndex];\n            if (h.ColumnHit)\n                nav.HoveredColumn = h.ColumnIndex;\n            if (h.ColumnSeparatorHit)\n                nav.HoveredSeparator = h.ColumnSeparator;\n\n            nav.MouseInColumnArea = h.InHeaderArea;\n            nav.MouseInItemArea = h.InItemArea;\n\n            if (nav.DraggingSeperator)\n            {\n                nav.HoveredColumn = oldSelSep;\n                nav.HoveredSeparator = oldSelSep;\n                nav.SelSeperator = oldSelSep;\n            }\n            else if (nav.Dragging)\n            {\n                nav.HoveredColumn = (EnumColumnType)(-1);\n                nav.HoveredSeparator = (EnumColumnType)(-1);\n                nav.SelSeperator = (EnumColumnType)(-1);\n            }\n\n            if (nav.Dragging && e.Y > ClientRectangle.Bottom && !scrollTimer.Enabled)\n            {\n                scrollTimer.Tag = -120;\n                scrollTimer.Enabled = true;\n            }\n            else if (nav.Dragging && e.Y < ClientRectangle.Top && !scrollTimer.Enabled)\n            {\n                scrollTimer.Tag = 120;\n                scrollTimer.Enabled = true;\n            }\n            else if (scrollTimer.Enabled && e.Y >= ClientRectangle.Top && e.Y <= ClientRectangle.Bottom)\n            {\n                scrollTimer.Enabled = false;\n            }\n\n            if ((e.Button & MouseButtons.Left) == MouseButtons.Left && nav.DraggingSeperator)\n            {\n                int delta = e.Location.X - nav.SelStart.X;\n                nav.SelStart = e.Location;\n                int colwidth = Columns[nav.SelSeperator].Width + delta;\n                colwidth = System.Math.Max(16, colwidth);\n                Columns[nav.SelSeperator].Width = colwidth;\n                mRenderer.Refresh();\n            }\n            else if (((e.Button & MouseButtons.Left) == MouseButtons.Left || (e.Button & MouseButtons.Right) == MouseButtons.Right) &&\n                AllowDrag && !nav.SelfDragging &&\n                nav.HoveredItem != null && nav.ClickedItem != null &&\n                ReferenceEquals(nav.HoveredItem, nav.ClickedItem))\n            {\n                nav.Dragging = false;\n                if (!nav.HoveredItem.Selected)\n                    ClearSelection();\n                if (mSelectedItems.Count == 0)\n                {\n                    nav.HoveredItem.Selected = true;\n                    // Force a refresh\n                    mRenderer.Refresh(true);\n                }\n\n                // Start drag-and-drop\n                string[] filenames = new string[mSelectedItems.Count];\n                for (int i = 0; i < mSelectedItems.Count; i++)\n                    filenames[i] = mSelectedItems[i].FileName;\n                DataObject data = new DataObject(DataFormats.FileDrop, filenames);\n                nav.SelfDragging = true;\n                nav.DragIndex = -1;\n                DoDragDrop(data, DragDropEffects.Copy | DragDropEffects.Move);\n                nav.SelfDragging = false;\n            }\n            else if (((e.Button & MouseButtons.Left) == MouseButtons.Left || (e.Button & MouseButtons.Right) == MouseButtons.Right) && nav.Dragging)\n            {\n                if (!nav.ShiftDown && !nav.ControlDown && SelectedItems.Count != 0)\n                    ClearSelection();\n\n                nav.SelEnd = e.Location;\n                Rectangle sel = new Rectangle(System.Math.Min(nav.SelStart.X, nav.SelEnd.X), System.Math.Min(nav.SelStart.Y, nav.SelEnd.Y), System.Math.Abs(nav.SelStart.X - nav.SelEnd.X), System.Math.Abs(nav.SelStart.Y - nav.SelEnd.Y));\n                nav.Highlight.Clear();\n                int startRow = (Math.Min(nav.SelStart.Y, nav.SelEnd.Y) + ViewOffset.Y - (mView == EnumView.Details ? mRenderer.MeasureColumnHeaderHeight() : 0)) / layoutManager.ItemSizeWithMargin.Height;\n                int endRow = (Math.Max(nav.SelStart.Y, nav.SelEnd.Y) + ViewOffset.Y - (mView == EnumView.Details ? mRenderer.MeasureColumnHeaderHeight() : 0)) / layoutManager.ItemSizeWithMargin.Height;\n                int startCol = (Math.Min(nav.SelStart.X, nav.SelEnd.X) + ViewOffset.X) / layoutManager.ItemSizeWithMargin.Width;\n                int endCol = (Math.Max(nav.SelStart.X, nav.SelEnd.X) + ViewOffset.X) / layoutManager.ItemSizeWithMargin.Width;\n                if (startCol <= layoutManager.Cols - 1 || endCol <= layoutManager.Cols - 1)\n                {\n                    startCol = Math.Min(layoutManager.Cols - 1, startCol);\n                    endCol = Math.Min(layoutManager.Cols - 1, endCol);\n                    for (int row = startRow; row <= endRow; row++)\n                    {\n                        for (int col = startCol; col <= endCol; col++)\n                        {\n                            int i = row * layoutManager.Cols + col;\n                            if (i >= 0 && i <= mItems.Count - 1 && !nav.Highlight.ContainsKey(mItems[i]))\n                                nav.Highlight.Add(mItems[i], (nav.ControlDown ? !Items[i].Selected : true));\n                        }\n                    }\n                }\n                mRenderer.Refresh();\n            }\n            else if (nav.MouseClicked && ((e.Button & MouseButtons.Left) == MouseButtons.Left || (e.Button & MouseButtons.Right) == MouseButtons.Right) && nav.MouseInItemArea)\n            {\n                nav.SelEnd = e.Location;\n                if (System.Math.Max(System.Math.Abs(nav.SelEnd.X - nav.SelStart.X), System.Math.Abs(nav.SelEnd.Y - nav.SelStart.Y)) > 2)\n                    nav.Dragging = true;\n            }\n\n            if (Focused && AllowColumnResize && nav.HoveredSeparator != (EnumColumnType)(-1) && Cursor == Cursors.Default)\n                Cursor = Cursors.VSplit;\n            else if (Focused && nav.HoveredSeparator == (EnumColumnType)(-1) && Cursor != Cursors.Default)\n                Cursor = Cursors.Default;\n\n            if (oldHoveredItem != nav.HoveredItem ||\n                oldHoveredColumn != nav.HoveredColumn ||\n                oldHoveredSeparator != nav.HoveredSeparator ||\n                oldSelSeperator != nav.SelSeperator)\n                mRenderer.Refresh();\n\n            mRenderer.ResumePaint();\n\n            base.OnMouseMove(e);\n        }\n        /// <summary>\n        /// Handles the MouseWheel event.\n        /// </summary>\n        protected override void OnMouseWheel(MouseEventArgs e)\n        {\n            int newYOffset = mViewOffset.Y - (e.Delta / 120) * vScrollBar.SmallChange;\n            if (newYOffset > vScrollBar.Maximum - vScrollBar.LargeChange + 1)\n                newYOffset = vScrollBar.Maximum - vScrollBar.LargeChange + 1;\n            if (newYOffset < 0)\n                newYOffset = 0;\n            int delta = newYOffset - mViewOffset.Y;\n            if (newYOffset < vScrollBar.Minimum) newYOffset = vScrollBar.Minimum;\n            if (newYOffset > vScrollBar.Maximum) newYOffset = vScrollBar.Maximum;\n            mViewOffset.Y = newYOffset;\n            hScrollBar.Value = 0;\n            vScrollBar.Value = newYOffset;\n            if (nav.Dragging)\n                nav.SelStart = new Point(nav.SelStart.X, nav.SelStart.Y - delta);\n\n            mRenderer.Refresh();\n\n            base.OnMouseWheel(e);\n        }\n        /// <summary>\n        /// Handles the MouseLeave event.\n        /// </summary>\n        protected override void OnMouseLeave(EventArgs e)\n        {\n            nav.MouseInItemArea = false;\n            nav.MouseInColumnArea = false;\n\n            mRenderer.SuspendPaint();\n            if (nav.HoveredItem != null)\n            {\n                nav.HoveredItem = null;\n                mRenderer.Refresh();\n            }\n            if (nav.HoveredColumn != (EnumColumnType)(-1))\n            {\n                nav.HoveredColumn = (EnumColumnType)(-1);\n                mRenderer.Refresh();\n            }\n            if (nav.HoveredSeparator != (EnumColumnType)(-1))\n                Cursor = Cursors.Default;\n\n            mRenderer.ResumePaint();\n\n            base.OnMouseLeave(e);\n        }\n        /// <summary>\n        /// Handles the MouseDoubleClick event.\n        /// </summary>\n        protected override void OnMouseDoubleClick(MouseEventArgs e)\n        {\n            mRenderer.SuspendPaint();\n            if (nav.HoveredItem != null)\n            {\n                OnItemDoubleClick(new ItemClickEventArgs(nav.HoveredItem, e.Location, e.Button));\n            }\n            if (AllowColumnClick && nav.HoveredSeparator != (EnumColumnType)(-1))\n            {\n                Columns[nav.HoveredSeparator].AutoFit();\n                mRenderer.Refresh();\n            }\n            mRenderer.ResumePaint();\n\n            base.OnMouseDoubleClick(e);\n        }\n        /// <summary>\n        /// Handles the IsInputKey event.\n        /// </summary>\n        protected override bool IsInputKey(Keys keyData)\n        {\n            if ((keyData & Keys.ShiftKey) == Keys.ShiftKey || (keyData & Keys.ControlKey) == Keys.ControlKey)\n            {\n                ImageListViewItem item = this.Items.FocusedItem;\n                int index = 0;\n                if (item != null)\n                    index = mItems.IndexOf(item);\n                nav.SelStartKey = index;\n            }\n\n            if ((keyData & Keys.ShiftKey) == Keys.ShiftKey ||\n                (keyData & Keys.ControlKey) == Keys.ControlKey ||\n                (keyData & Keys.Left) == Keys.Left ||\n                (keyData & Keys.Right) == Keys.Right ||\n                (keyData & Keys.Up) == Keys.Up ||\n                (keyData & Keys.Down) == Keys.Down)\n                return true;\n            else\n                return base.IsInputKey(keyData);\n        }\n        /// <summary>\n        /// Handles the KeyDown event.\n        /// </summary>\n        protected override void OnKeyDown(KeyEventArgs e)\n        {\n            base.OnKeyDown(e);\n\n            nav.ShiftDown = e.Shift;\n            nav.ControlDown = e.Control;\n\n            if (Items.Count == 0)\n                return;\n\n            ImageListViewItem item = this.Items.FocusedItem;\n            int index = 0;\n            if (item != null)\n                index = mItems.IndexOf(item);\n\n            int newindex = ApplyNavKey(index, e.KeyCode);\n            if (index == newindex)\n                return;\n\n            mRenderer.SuspendPaint();\n            index = newindex;\n            if (nav.ControlDown)\n            {\n                nav.SelStartKey = index;\n                Items.FocusedItem = Items[index];\n                EnsureVisible(index);\n            }\n            else if (nav.ShiftDown)\n            {\n                ClearSelection();\n                nav.SelEndKey = index;\n                Items.FocusedItem = Items[index];\n                int imin = System.Math.Min(nav.SelStartKey, nav.SelEndKey);\n                int imax = System.Math.Max(nav.SelStartKey, nav.SelEndKey);\n                for (int i = imin; i <= imax; i++)\n                {\n                    Items[i].Selected = true;\n                }\n                EnsureVisible(nav.SelEndKey);\n            }\n            else\n            {\n                ClearSelection();\n                nav.SelStartKey = index;\n                Items[index].Selected = true;\n                Items.FocusedItem = Items[index];\n                EnsureVisible(index);\n            }\n            mRenderer.ResumePaint();\n        }\n        /// <summary>\n        /// Handles the KeyUp event.\n        /// </summary>\n        protected override void OnKeyUp(KeyEventArgs e)\n        {\n            base.OnKeyUp(e);\n\n            nav.ShiftDown = e.Shift;\n            nav.ControlDown = e.Control;\n        }\n        /// <summary>\n        /// Handles the GotFocus event.\n        /// </summary>\n        protected override void OnGotFocus(EventArgs e)\n        {\n            base.OnGotFocus(e);\n            mRenderer.Refresh();\n        }\n        /// <summary>\n        /// Handles the LostFocus event.\n        /// </summary>\n        protected override void OnLostFocus(EventArgs e)\n        {\n            base.OnLostFocus(e);\n            mRenderer.Refresh();\n        }\n        /// <summary>\n        /// Releases the unmanaged resources used by the <see cref=\"T:System.Windows.Forms.Control\"/> and its child controls and optionally releases the managed resources.\n        /// </summary>\n        /// <param name=\"disposing\">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposed) return;\n\n            disposed = true;\n            if (disposing)\n            {\n                mRenderer.Dispose();\n                mHeaderFont.Dispose();\n            }\n\n            base.Dispose(disposing);\n        }\n        /// <summary>\n        /// Handles the HandleDestroyed event.\n        /// </summary>\n        protected override void OnHandleDestroyed(EventArgs e)\n        {\n            //cxs\n            //这里一个bug\n            //当窗体隐藏时，会走到这里来，把线程Stop掉，但是再次显示窗体时，无法重新开始线程\n            //导致在隐藏窗体再显示后，无法显示出新加入图片的缩略图。\n            //可能原作者的意图是走到这个handle就表示窗体关闭了，没有考虑到hide\n            //解决办法是重写 OnHandleCreated 事件\n\n            itemCacheManager.Stop();\n            cacheManager.Stop();\n\n            base.OnHandleDestroyed(e);\n        }\n\n        //cxs\n        protected override void OnHandleCreated(EventArgs e)\n        {\n            if (itemCacheManager.Thread.ThreadState == ThreadState.Stopped)\n            {\n                itemCacheManager.Start();\n            }\n            if (cacheManager.Thread.ThreadState == ThreadState.Stopped)\n            {\n                cacheManager.Start();\n            }\n\n            base.OnHandleCreated(e);\n        }\n\n        #endregion\n\n        #region Public Classes\n        /// <summary>\n        /// Represents a column header displayed in details view mode.\n        /// </summary>\n        public class ImageListViewColumnHeader\n        {\n            #region Member Variables\n            private int mDisplayIndex;\n            internal SEImageListView mImageListView;\n            private string mText;\n            private EnumColumnType mType;\n            private bool mVisible;\n            private int mWidth;\n\n            internal ImageListViewColumnHeaderCollection owner;\n            #endregion\n\n            #region Properties\n            /// <summary>\n            /// Gets the default header text for this column type.\n            /// </summary>\n            [Category(\"Appearance\"), Browsable(false), Description(\"Gets the default header text for this column type.\"), Localizable(true)]\n            public virtual string DefaultText\n            {\n                get\n                {\n                    switch (mType)\n                    {\n                        case EnumColumnType.DateAccessed:\n                            return \"Last Access\";\n                        case EnumColumnType.DateCreated:\n                            return \"Created\";\n                        case EnumColumnType.DateModified:\n                            return \"Modified\";\n                        case EnumColumnType.FileName:\n                            return \"Filename\";\n                        case EnumColumnType.Name:\n                            return \"Name\";\n                        case EnumColumnType.FilePath:\n                            return \"Path\";\n                        case EnumColumnType.FileSize:\n                            return \"Size\";\n                        case EnumColumnType.FileType:\n                            return \"Type\";\n                        case EnumColumnType.Dimension:\n                            return \"Dimension\";\n                        case EnumColumnType.Resolution:\n                            return \"Resolution\";\n                        default:\n                            throw new InvalidOperationException(\"Unknown column type.\");\n                    }\n                }\n            }\n            /// <summary>\n            /// Gets or sets the display order of the column.\n            /// </summary>\n            [Category(\"Appearance\"), Browsable(true), Description(\"Gets the bounds of the item in client coordinates.\")]\n            public int DisplayIndex\n            {\n                get\n                {\n                    return mDisplayIndex;\n                }\n                set\n                {\n                    int oldIndex = mDisplayIndex;\n                    int newIndex = value;\n                    if (newIndex < 0 || newIndex > owner.Count - 1)\n                        throw new IndexOutOfRangeException();\n\n                    if (oldIndex == -1)\n                        mDisplayIndex = newIndex;\n                    else\n                    {\n                        ImageListViewColumnHeader targetColumn = null;\n                        foreach (ImageListViewColumnHeader column in owner)\n                        {\n                            if (column.DisplayIndex == newIndex)\n                            {\n                                targetColumn = column;\n                                break;\n                            }\n                        }\n                        if (targetColumn != null)\n                        {\n                            this.mDisplayIndex = newIndex;\n                            targetColumn.mDisplayIndex = oldIndex;\n                            if (mImageListView != null)\n                                mImageListView.mRenderer.Refresh();\n                        }\n                    }\n                }\n            }\n            /// <summary>\n            /// Determines whether the mouse is currently hovered over the column header.\n            /// </summary>\n            [Category(\"Appearance\"), Browsable(false), Description(\"Determines whether the mouse is currently hovered over the column.\")]\n            public bool Hovered\n            {\n                get\n                {\n                    if (mImageListView == null) return false;\n                    return (mImageListView.nav.HoveredColumn == this.Type);\n                }\n            }\n            /// <summary>\n            /// Gets the ImageListView owning this item.\n            /// </summary>\n            [Category(\"Behavior\"), Browsable(false), Description(\"Gets the ImageListView owning this item.\")]\n            public SEImageListView ImageListView { get { return mImageListView; } }\n            /// <summary>\n            /// Gets or sets the column header text.\n            /// </summary>\n            [Category(\"Appearance\"), Browsable(true), Description(\"Gets or sets the column header text.\")]\n            public string Text\n            {\n                get\n                {\n                    if (!string.IsNullOrEmpty(mText))\n                        return mText;\n                    else\n                        return DefaultText;\n                }\n                set\n                {\n                    mText = value;\n                    if (mImageListView != null)\n                        mImageListView.mRenderer.Refresh();\n                }\n            }\n            /// <summary>\n            /// Gets the type of information displayed by the column.\n            /// </summary>\n            [Category(\"Appearance\"), Browsable(false), Description(\"Gets or sets the type of information displayed by the column.\")]\n            public EnumColumnType Type\n            {\n                get\n                {\n                    return mType;\n                }\n            }\n            /// <summary>\n            /// Gets or sets a value indicating whether the control is displayed.\n            /// </summary>\n            [Category(\"Appearance\"), Browsable(true), Description(\"Gets or sets a value indicating whether the control is displayed.\"), DefaultValue(true)]\n            public bool Visible\n            {\n                get\n                {\n                    return mVisible;\n                }\n                set\n                {\n                    mVisible = value;\n                    if (mImageListView != null)\n                        mImageListView.mRenderer.Refresh();\n                }\n            }\n            /// <summary>\n            /// Gets or sets the column width.\n            /// </summary>\n            [Category(\"Appearance\"), Browsable(true), Description(\"Gets or sets the column width.\"), DefaultValue(SEImageListView.DefaultColumnWidth)]\n            public int Width\n            {\n                get\n                {\n                    return mWidth;\n                }\n                set\n                {\n                    mWidth = System.Math.Max(12, value);\n                    if (mImageListView != null)\n                        mImageListView.mRenderer.Refresh();\n                }\n            }\n            #endregion\n\n            #region Constructors\n            public ImageListViewColumnHeader(EnumColumnType type, string text, int width)\n            {\n                mImageListView = null;\n                owner = null;\n                mText = text;\n                mType = type;\n                mWidth = width;\n                mVisible = true;\n                mDisplayIndex = -1;\n            }\n            public ImageListViewColumnHeader(EnumColumnType type, string text)\n                : this(type, text, SEImageListView.DefaultColumnWidth)\n            {\n                ;\n            }\n            public ImageListViewColumnHeader(EnumColumnType type, int width)\n                : this(type, \"\", width)\n            {\n                ;\n            }\n            public ImageListViewColumnHeader(EnumColumnType type)\n                : this(type, \"\", SEImageListView.DefaultColumnWidth)\n            {\n                ;\n            }\n            public ImageListViewColumnHeader()\n                : this(EnumColumnType.Name)\n            {\n            }\n            #endregion\n\n            #region Instance Methods\n            /// <summary>\n            /// Resizes the width of the column based on the length of the column content.\n            /// </summary>\n            public void AutoFit()\n            {\n                if (mImageListView == null)\n                    throw new InvalidOperationException(\"Cannot calculate column width. Owner image list view is null.\");\n\n                int width = TextRenderer.MeasureText(Text, (mImageListView.HeaderFont == null ? mImageListView.Font : mImageListView.HeaderFont)).Width;\n                if (mImageListView.SortColumn == mType && mImageListView.SortOrder != EnumSortOrder.None)\n                    width += mImageListView.mRenderer.GetSortArrowImage(mImageListView.SortOrder).Width + 4;\n                foreach (ImageListViewItem item in mImageListView.Items)\n                {\n                    int itemwidth = TextRenderer.MeasureText(item.GetSubItemText(Type), mImageListView.Font).Width;\n                    width = System.Math.Max(width, itemwidth);\n                }\n                this.Width = width + 8;\n                mImageListView.mRenderer.Refresh();\n            }\n            #endregion\n        }\n        /// <summary>\n        /// Represents the collection of columns in an ImageListView control.\n        /// </summary>\n        [Editor(typeof(ColumnHeaderCollectionEditor), typeof(UITypeEditor))]\n        [TypeConverter(typeof(ColumnHeaderCollectionTypeConverter))]\n        public class ImageListViewColumnHeaderCollection : IEnumerable<ImageListViewColumnHeader>, ICloneable\n        {\n            #region Member Variables\n            private SEImageListView mImageListView;\n            private ImageListViewColumnHeader[] mItems;\n            #endregion\n\n            #region Properties\n            /// <summary>\n            /// Gets the number of columns in the collection.\n            /// </summary>\n            [Category(\"Behavior\"), Browsable(false), Description(\"Gets the number of columns in the collection.\")]\n            public int Count { get { return mItems.Length; } }\n            /// <summary>\n            /// Gets the ImageListView owning this collection.\n            /// </summary>\n            [Category(\"Behavior\"), Browsable(false), Description(\"Gets the ImageListView owning this collection.\")]\n            public SEImageListView ImageListView { get { return mImageListView; } }\n            /// <summary>\n            /// Gets the item at the specified index within the collection.\n            /// </summary>\n            [Category(\"Behavior\"), Browsable(false), Description(\"Gets or item at the specified index within the collection.\")]\n            public ImageListViewColumnHeader this[int index]\n            {\n                get\n                {\n                    return mItems[index];\n                }\n            }\n            /// <summary>\n            /// Gets or sets the item with the specified type within the collection.\n            /// </summary>\n            [Category(\"Behavior\"), Browsable(false), Description(\"Gets or sets the item with the specified type within the collection.\")]\n            public ImageListViewColumnHeader this[EnumColumnType type]\n            {\n                get\n                {\n                    foreach (ImageListViewColumnHeader column in this)\n                        if (column.Type == type) return column;\n                    throw new ArgumentException(\"Unknown column type.\", \"type\");\n                }\n            }\n            #endregion\n\n            #region Constructors\n            public ImageListViewColumnHeaderCollection(SEImageListView owner)\n            {\n                mImageListView = owner;\n                // Create the default column set\n                mItems = new ImageListViewColumnHeader[] {\n                    new ImageListViewColumnHeader(EnumColumnType.Name),\n                    new ImageListViewColumnHeader(EnumColumnType.FileSize),\n                    new ImageListViewColumnHeader(EnumColumnType.DateModified),\n                    new ImageListViewColumnHeader(EnumColumnType.FilePath),\n                    new ImageListViewColumnHeader(EnumColumnType.FileType),\n                    new ImageListViewColumnHeader(EnumColumnType.FileName),\n                    new ImageListViewColumnHeader(EnumColumnType.DateCreated),\n                    new ImageListViewColumnHeader(EnumColumnType.DateAccessed),\n                    new ImageListViewColumnHeader(EnumColumnType.Dimension),\n                    new ImageListViewColumnHeader(EnumColumnType.Resolution),\n               };\n                for (int i = 0; i < mItems.Length; i++)\n                {\n                    ImageListViewColumnHeader col = mItems[i];\n                    col.mImageListView = mImageListView;\n                    col.owner = this;\n                    col.DisplayIndex = i;\n                    if (i >= 4) col.Visible = false;\n                }\n            }\n            #endregion\n\n            #region Instance Methods\n            /// <summary>\n            /// Returns an enumerator to use to iterate through columns.\n            /// </summary>\n            /// <returns>An IEnumerator&lt;ImageListViewColumn&gt; that represents the item collection.</returns>\n            public IEnumerator<ImageListViewColumnHeader> GetEnumerator()\n            {\n                foreach (ImageListViewColumnHeader column in mItems)\n                    yield return column;\n                yield break;\n            }\n            #endregion\n\n            #region Helper Methods\n            /// <summary>\n            /// Gets the columns as diplayed on the UI.\n            /// </summary>\n            internal List<ImageListViewColumnHeader> GetUIColumns()\n            {\n                List<ImageListViewColumnHeader> list = new List<ImageListViewColumnHeader>();\n                foreach (ImageListViewColumnHeader column in mItems)\n                {\n                    if (column.Visible)\n                        list.Add(column);\n                }\n                list.Sort(ColumnCompare);\n                return list;\n            }\n            /// <summary>\n            /// Compares the columns by their display index.\n            /// </summary>\n            internal static int ColumnCompare(ImageListViewColumnHeader a, ImageListViewColumnHeader b)\n            {\n                if (a.DisplayIndex < b.DisplayIndex)\n                    return -1;\n                else if (a.DisplayIndex > b.DisplayIndex)\n                    return 1;\n                else\n                    return 0;\n            }\n            #endregion\n\n            #region Unsupported Interface\n            /// <summary>\n            /// Returns an enumerator that iterates through a collection.\n            /// </summary>\n            IEnumerator IEnumerable.GetEnumerator()\n            {\n                return GetEnumerator();\n            }\n            #endregion\n\n            #region ICloneable Members\n            /// <summary>\n            /// Creates a new object that is a copy of the current instance.\n            /// </summary>\n            public object Clone()\n            {\n                ImageListViewColumnHeaderCollection clone = new ImageListViewColumnHeaderCollection(this.mImageListView);\n                Array.Copy(this.mItems, clone.mItems, 0);\n                return clone;\n            }\n            #endregion\n        }\n        /// <summary>\n        /// Represents the collection of items in the image list view.\n        /// </summary>\n        public class ImageListViewItemCollection : IList<ImageListViewItem>, ICollection, IList, IEnumerable\n        {\n            #region Member Variables\n            private List<ImageListViewItem> mItems;\n            internal SEImageListView mImageListView;\n            private ImageListViewItem mFocused;\n            #endregion\n\n            #region Constructors\n            public ImageListViewItemCollection(SEImageListView owner)\n            {\n                mItems = new List<ImageListViewItem>();\n                mFocused = null;\n                mImageListView = owner;\n            }\n            #endregion\n\n            #region Properties\n            /// <summary>\n            /// Gets the number of elements contained in the <see cref=\"T:System.Collections.Generic.ICollection`1\"/>.\n            /// </summary>\n            public int Count\n            {\n                get { return mItems.Count; }\n            }\n            /// <summary>\n            /// Gets a value indicating whether the <see cref=\"T:System.Collections.Generic.ICollection`1\"/> is read-only.\n            /// </summary>\n            public bool IsReadOnly\n            {\n                get { return false; }\n            }\n            /// <summary>\n            /// Gets or sets the focused item.\n            /// </summary>\n            internal ImageListViewItem FocusedItem\n            {\n                get\n                {\n                    return mFocused;\n                }\n                set\n                {\n                    ImageListViewItem oldFocusedItem = mFocused;\n                    mFocused = value;\n                    // Refresh items\n                    if (oldFocusedItem != mFocused && mImageListView != null)\n                        mImageListView.mRenderer.Refresh();\n                }\n            }\n            /// <summary>\n            /// Gets the ImageListView owning this collection.\n            /// </summary>\n            [Category(\"Behavior\"), Browsable(false), Description(\"Gets the ImageListView owning this collection.\")]\n            public SEImageListView ImageListView { get { return mImageListView; } }\n            /// <summary>\n            /// Gets or sets the <see cref=\"NetHelpers.ImageListViewItem\"/> at the specified index.\n            /// </summary>\n            [Category(\"Behavior\"), Browsable(false), Description(\"Gets or sets the item at the specified index.\")]\n            public ImageListViewItem this[int index]\n            {\n                get\n                {\n                    return mItems[index];\n                }\n                set\n                {\n                    bool oldSelected = mItems[index].Selected;\n                    mItems[index] = value;\n                    mItems[index].mIndex = index;\n                    if (mImageListView != null)\n                    {\n                        mImageListView.itemCacheManager.AddToCache(mItems[index]);\n                        if (mItems[index].Selected != oldSelected)\n                            mImageListView.OnSelectionChangedInternal();\n                    }\n                }\n            }\n            /// <summary>\n            /// Gets the <see cref=\"NetHelpers.ImageListViewItem\"/> with the specified Guid.\n            /// </summary>\n            [Category(\"Behavior\"), Browsable(false), Description(\"Gets or sets the item with the specified Guid.\")]\n            public ImageListViewItem this[Guid guid]\n            {\n                get\n                {\n                    foreach (ImageListViewItem item in this)\n                        if (item.Guid == guid) return item;\n                    throw new ArgumentException(\"No item with this guid exists.\", \"guid\");\n                }\n            }\n            #endregion\n\n            #region Instance Methods\n            /// <summary>\n            /// Adds an item to the <see cref=\"T:System.Collections.Generic.ICollection`1\"/>.\n            /// </summary>\n            /// <param name=\"item\">The object to add to the <see cref=\"T:System.Collections.Generic.ICollection`1\"/>.</param>\n            public void Add(ImageListViewItem item)\n            {\n                // Check if the file already exists\n                if (mImageListView != null && !mImageListView.AllowDuplicateFileNames)\n                {\n                    if (mItems.Exists(a => string.Compare(a.FileName, item.FileName, StringComparison.OrdinalIgnoreCase) == 0))\n                        return;\n                }\n                item.owner = this;\n                item.mIndex = mItems.Count;\n                mItems.Add(item);\n                if (mImageListView != null)\n                {\n                    item.mImageListView = mImageListView;\n                    mImageListView.itemCacheManager.AddToCache(item);\n                    if (item.Selected)\n                        mImageListView.OnSelectionChangedInternal();\n                    mImageListView.mRenderer.Refresh();\n                }\n            }\n            /// <summary>\n            /// Adds an item to the <see cref=\"T:System.Collections.Generic.ICollection`1\"/>.\n            /// </summary>\n            /// <param name=\"filename\">The name of the image file.</param>\n            public void Add(string filename)\n            {\n                Add(new ImageListViewItem(filename));\n            }\n            /// <summary>\n            /// Adds a range of items to the <see cref=\"T:System.Collections.Generic.ICollection`1\"/>.\n            /// </summary>\n            /// <param name=\"items\">The items to add to the collection.</param>\n            public void AddRange(ImageListViewItem[] items)\n            {\n                if (mImageListView != null)\n                    mImageListView.mRenderer.SuspendPaint();\n\n                foreach (ImageListViewItem item in items)\n                    Add(item);\n\n                if (mImageListView != null)\n                {\n                    mImageListView.mRenderer.Refresh();\n                    mImageListView.mRenderer.ResumePaint();\n                }\n            }\n            /// <summary>\n            /// Adds a range of items to the <see cref=\"T:System.Collections.Generic.ICollection`1\"/>.\n            /// </summary>\n            /// <param name=\"filenames\">The names or the image files.</param>\n            public void AddRange(string[] filenames)\n            {\n                if (mImageListView != null)\n                    mImageListView.mRenderer.SuspendPaint();\n\n                for (int i = 0; i < filenames.Length; i++)\n                {\n                    Add(filenames[i]);\n                }\n\n                if (mImageListView != null)\n                {\n                    mImageListView.mRenderer.Refresh();\n                    mImageListView.mRenderer.ResumePaint();\n                }\n\n            }\n            /// <summary>\n            /// Removes all items from the <see cref=\"T:System.Collections.Generic.ICollection`1\"/>.\n            /// </summary>\n            public void Clear()\n            {\n                mItems.Clear();\n                if (mImageListView != null)\n                {\n                    mImageListView.SelectedItems.Clear();\n                    mImageListView.mRenderer.Refresh();\n                }\n            }\n            /// <summary>\n            /// Determines whether the <see cref=\"T:System.Collections.Generic.ICollection`1\"/> contains a specific value.\n            /// </summary>\n            /// <param name=\"item\">The object to locate in the <see cref=\"T:System.Collections.Generic.ICollection`1\"/>.</param>\n            /// <returns>\n            /// true if <paramref name=\"item\"/> is found in the <see cref=\"T:System.Collections.Generic.ICollection`1\"/>; otherwise, false.\n            /// </returns>\n            public bool Contains(ImageListViewItem item)\n            {\n                return mItems.Contains(item);\n            }\n            /// <summary>\n            /// Returns an enumerator that iterates through the collection.\n            /// </summary>\n            /// <returns>\n            /// A <see cref=\"T:System.Collections.Generic.IEnumerator`1\"/> that can be used to iterate through the collection.\n            /// </returns>\n            public IEnumerator<ImageListViewItem> GetEnumerator()\n            {\n                return mItems.GetEnumerator();\n            }\n            /// <summary>\n            /// Returns an enumerator that iterates through a collection.\n            /// </summary>\n            /// <returns>\n            /// An <see cref=\"T:System.Collections.IEnumerator\"/> object that can be used to iterate through the collection.\n            /// </returns>\n            System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()\n            {\n                return mItems.GetEnumerator();\n            }\n            /// <summary>\n            /// Inserts an item to the <see cref=\"T:System.Collections.Generic.IList`1\"/> at the specified index.\n            /// </summary>\n            /// <param name=\"index\">The zero-based index at which <paramref name=\"item\"/> should be inserted.</param>\n            /// <param name=\"item\">The object to insert into the <see cref=\"T:System.Collections.Generic.IList`1\"/>.</param>\n            /// <exception cref=\"T:System.ArgumentOutOfRangeException\">\n            /// \t<paramref name=\"index\"/> is not a valid index in the <see cref=\"T:System.Collections.Generic.IList`1\"/>.\n            /// </exception>\n            public void Insert(int index, ImageListViewItem item)\n            {\n                item.owner = this;\n                item.mIndex = index;\n                for (int i = index; i < mItems.Count; i++)\n                    mItems[i].mIndex++;\n                mItems.Insert(index, item);\n                if (mImageListView != null)\n                {\n                    item.mImageListView = this.mImageListView;\n                    mImageListView.itemCacheManager.AddToCache(item);\n                    if (item.Selected)\n                        mImageListView.OnSelectionChangedInternal();\n                    mImageListView.mRenderer.Refresh();\n                }\n            }\n            /// <summary>\n            /// Removes the first occurrence of a specific object from the <see cref=\"T:System.Collections.Generic.ICollection`1\"/>.\n            /// </summary>\n            /// <param name=\"item\">The object to remove from the <see cref=\"T:System.Collections.Generic.ICollection`1\"/>.</param>\n            /// <returns>\n            /// true if <paramref name=\"item\"/> was successfully removed from the <see cref=\"T:System.Collections.Generic.ICollection`1\"/>; otherwise, false. This method also returns false if <paramref name=\"item\"/> is not found in the original <see cref=\"T:System.Collections.Generic.ICollection`1\"/>.\n            /// </returns>\n            public bool Remove(ImageListViewItem item)\n            {\n                for (int i = item.mIndex; i < mItems.Count; i++)\n                    mItems[i].mIndex--;\n                bool ret = mItems.Remove(item);\n                if (mImageListView != null)\n                {\n                    if (item.Selected)\n                        mImageListView.OnSelectionChangedInternal();\n                    mImageListView.mRenderer.Refresh();\n                }\n                return ret;\n            }\n            /// <summary>\n            /// Removes the <see cref=\"T:System.Collections.Generic.IList`1\"/> item at the specified index.\n            /// </summary>\n            /// <param name=\"index\">The zero-based index of the item to remove.</param>\n            /// <exception cref=\"T:System.ArgumentOutOfRangeException\">\n            /// \t<paramref name=\"index\"/> is not a valid index in the <see cref=\"T:System.Collections.Generic.IList`1\"/>.\n            /// </exception>\n            public void RemoveAt(int index)\n            {\n                for (int i = index; i < mItems.Count; i++)\n                    mItems[i].mIndex--;\n                mItems.RemoveAt(index);\n                if (mImageListView != null)\n                {\n                    if (mItems[index].Selected)\n                        mImageListView.OnSelectionChangedInternal();\n                    mImageListView.mRenderer.Refresh();\n                }\n            }\n            #endregion\n\n            #region Helper Methods\n            /// <summary>\n            /// Adds the given item without raising a selection changed event.\n            /// </summary>\n            internal void AddInternal(ImageListViewItem item)\n            {\n                item.owner = this;\n                item.mIndex = mItems.Count;\n                mItems.Add(item);\n                if (mImageListView != null)\n                {\n                    item.mImageListView = mImageListView;\n                    mImageListView.itemCacheManager.AddToCache(item);\n                }\n            }\n            /// <summary>\n            /// Inserts the given item without raising a selection changed event.\n            /// </summary>\n            internal void InsertInternal(int index, ImageListViewItem item)\n            {\n                item.owner = this;\n                item.mIndex = index;\n                for (int i = index; i < mItems.Count; i++)\n                    mItems[i].mIndex++;\n                mItems.Insert(index, item);\n                if (mImageListView != null)\n                {\n                    item.mImageListView = this.mImageListView;\n                    mImageListView.itemCacheManager.AddToCache(item);\n                }\n            }\n            /// <summary>\n            /// Removes the given item without raising a selection changed event.\n            /// </summary>\n            internal void RemoveInternal(ImageListViewItem item)\n            {\n                for (int i = item.mIndex; i < mItems.Count; i++)\n                    mItems[i].mIndex--;\n                bool ret = mItems.Remove(item);\n            }\n            /// <summary>\n            /// Returns the index of the specified item.\n            /// </summary>\n            internal int IndexOf(ImageListViewItem item)\n            {\n                return item.Index;\n            }\n            /// <summary>\n            /// Returns the index of the item with the specified Guid.\n            /// </summary>\n            internal int IndexOf(Guid guid)\n            {\n                for (int i = 0; i < mItems.Count; i++)\n                    if (mItems[i].Guid == guid) return i;\n                return -1;\n            }\n            /// <summary>\n            /// Sorts the items by the sort order and sort column of the owner.\n            /// </summary>\n            internal void Sort()\n            {\n                if (mImageListView == null || mImageListView.SortOrder == EnumSortOrder.None)\n                    return;\n                mItems.Sort(new ImageListViewItemComparer(mImageListView.SortColumn, mImageListView.SortOrder));\n            }\n            #endregion\n\n            #region ImageListViewItemComparer\n            /// <summary>\n            /// Compares items by the sort order and sort column of the owner.\n            /// </summary>\n            private class ImageListViewItemComparer : IComparer<ImageListViewItem>\n            {\n                private EnumColumnType mSortColumn;\n                private EnumSortOrder mOrder;\n\n                public ImageListViewItemComparer(EnumColumnType sortColumn, EnumSortOrder order)\n                {\n                    mSortColumn = sortColumn;\n                    mOrder = order;\n                }\n\n                /// <summary>\n                /// Compares two objects and returns a value indicating whether one is less than, equal to, or greater than the other.\n                /// </summary>\n                public int Compare(ImageListViewItem x, ImageListViewItem y)\n                {\n                    int sign = (mOrder == EnumSortOrder.Ascending ? 1 : -1);\n                    int result = 0;\n                    switch (mSortColumn)\n                    {\n                        case EnumColumnType.DateAccessed:\n                            result = DateTime.Compare(x.DateAccessed, y.DateAccessed);\n                            break;\n                        case EnumColumnType.DateCreated:\n                            result = DateTime.Compare(x.DateCreated, y.DateCreated);\n                            break;\n                        case EnumColumnType.DateModified:\n                            result = DateTime.Compare(x.DateModified, y.DateModified);\n                            break;\n                        case EnumColumnType.Dimension:\n                            long ax = x.Dimension.Width * x.Dimension.Height;\n                            long ay = y.Dimension.Width * y.Dimension.Height;\n                            result = (ax < ay ? -1 : (ax > ay ? 1 : 0));\n                            break;\n                        case EnumColumnType.FileName:\n                            result = string.Compare(x.FileName, y.FileName, StringComparison.InvariantCultureIgnoreCase);\n                            break;\n                        case EnumColumnType.FilePath:\n                            result = string.Compare(x.FilePath, y.FilePath, StringComparison.InvariantCultureIgnoreCase);\n                            break;\n                        case EnumColumnType.FileSize:\n                            result = (x.FileSize < y.FileSize ? -1 : (x.FileSize > y.FileSize ? 1 : 0));\n                            break;\n                        case EnumColumnType.FileType:\n                            result = string.Compare(x.FileType, y.FileType, StringComparison.InvariantCultureIgnoreCase);\n                            break;\n                        case EnumColumnType.Name:\n                            result = string.Compare(x.Text, y.Text, StringComparison.InvariantCultureIgnoreCase);\n                            break;\n                        case EnumColumnType.Resolution:\n                            float rx = x.Resolution.Width * x.Resolution.Height;\n                            float ry = y.Resolution.Width * y.Resolution.Height;\n                            result = (rx < ry ? -1 : (rx > ry ? 1 : 0));\n                            break;\n                        default:\n                            result = 0;\n                            break;\n                    }\n                    return sign * result;\n                }\n            }\n            #endregion\n\n            #region Unsupported Interface\n            /// <summary>\n            /// Copies the elements of the <see cref=\"T:System.Collections.Generic.ICollection`1\"/> to an <see cref=\"T:System.Array\"/>, starting at a particular <see cref=\"T:System.Array\"/> index.\n            /// </summary>\n            void ICollection<ImageListViewItem>.CopyTo(ImageListViewItem[] array, int arrayIndex)\n            {\n                mItems.CopyTo(array, arrayIndex);\n            }\n            /// <summary>\n            /// Determines the index of a specific item in the <see cref=\"T:System.Collections.Generic.IList`1\"/>.\n            /// </summary>\n            [Obsolete(\"Use ImageListViewItem.Index property instead.\")]\n            int IList<ImageListViewItem>.IndexOf(ImageListViewItem item)\n            {\n                return mItems.IndexOf(item);\n            }\n            /// <summary>\n            /// Copies the elements of the <see cref=\"T:System.Collections.ICollection\"/> to an <see cref=\"T:System.Array\"/>, starting at a particular <see cref=\"T:System.Array\"/> index.\n            /// </summary>\n            void ICollection.CopyTo(Array array, int index)\n            {\n                if (!(array is ImageListViewItem[]))\n                    throw new ArgumentException(\"An array of ImageListViewItem is required.\", \"array\");\n                mItems.CopyTo((ImageListViewItem[])array, index);\n            }\n            /// <summary>\n            /// Gets the number of elements contained in the <see cref=\"T:System.Collections.Generic.ICollection`1\"/>.\n            /// </summary>\n            int ICollection.Count\n            {\n                get { return mItems.Count; }\n            }\n            /// <summary>\n            /// Gets a value indicating whether access to the <see cref=\"T:System.Collections.ICollection\"/> is synchronized (thread safe).\n            /// </summary>\n            bool ICollection.IsSynchronized\n            {\n                get { return false; }\n            }\n            /// <summary>\n            /// Gets an object that can be used to synchronize access to the <see cref=\"T:System.Collections.ICollection\"/>.\n            /// </summary>\n            object ICollection.SyncRoot\n            {\n                get { throw new NotSupportedException(); }\n            }\n            /// <summary>\n            /// Adds an item to the <see cref=\"T:System.Collections.IList\"/>.\n            /// </summary>\n            int IList.Add(object value)\n            {\n                if (!(value is ImageListViewItem))\n                    throw new ArgumentException(\"An object of type ImageListViewItem is required.\", \"value\");\n                ImageListViewItem item = (ImageListViewItem)value;\n                Add(item);\n                return mItems.IndexOf(item);\n            }\n            /// <summary>\n            /// Determines whether the <see cref=\"T:System.Collections.IList\"/> contains a specific value.\n            /// </summary>\n            bool IList.Contains(object value)\n            {\n                if (!(value is ImageListViewItem))\n                    throw new ArgumentException(\"An object of type ImageListViewItem is required.\", \"value\");\n                return mItems.Contains((ImageListViewItem)value);\n            }\n            /// <summary>\n            /// Determines the index of a specific item in the <see cref=\"T:System.Collections.IList\"/>.\n            /// </summary>\n            int IList.IndexOf(object value)\n            {\n                if (!(value is ImageListViewItem))\n                    throw new ArgumentException(\"An object of type ImageListViewItem is required.\", \"value\");\n                return IndexOf((ImageListViewItem)value);\n            }\n            /// <summary>\n            /// Inserts an item to the <see cref=\"T:System.Collections.IList\"/> at the specified index.\n            /// </summary>\n            void IList.Insert(int index, object value)\n            {\n                if (!(value is ImageListViewItem))\n                    throw new ArgumentException(\"An object of type ImageListViewItem is required.\", \"value\");\n                Insert(index, (ImageListViewItem)value);\n            }\n            /// <summary>\n            /// Gets a value indicating whether the <see cref=\"T:System.Collections.IList\"/> has a fixed size.\n            /// </summary>\n            bool IList.IsFixedSize\n            {\n                get { return false; }\n            }\n            /// <summary>\n            /// Removes the first occurrence of a specific object from the <see cref=\"T:System.Collections.IList\"/>.\n            /// </summary>\n            void IList.Remove(object value)\n            {\n                if (!(value is ImageListViewItem))\n                    throw new ArgumentException(\"An object of type ImageListViewItem is required.\", \"value\");\n                Remove((ImageListViewItem)value);\n            }\n            /// <summary>\n            /// Gets or sets the <see cref=\"System.Object\"/> at the specified index.\n            /// </summary>\n            object IList.this[int index]\n            {\n                get\n                {\n                    return this[index];\n                }\n                set\n                {\n                    if (!(value is ImageListViewItem))\n                        throw new ArgumentException(\"An object of type ImageListViewItem is required.\", \"value\");\n                    this[index] = (ImageListViewItem)value;\n                }\n            }\n            #endregion\n        }\n        /// <summary>\n        /// Represents the collection of selected items in the image list view.\n        /// </summary>\n        public class ImageListViewSelectedItemCollection : IList<ImageListViewItem>\n        {\n            #region Member Variables\n            internal SEImageListView mImageListView;\n            #endregion\n\n            #region Constructors\n            public ImageListViewSelectedItemCollection(SEImageListView owner)\n            {\n                mImageListView = owner;\n            }\n            #endregion\n\n            #region Properties\n            /// <summary>\n            /// Gets the number of elements contained in the <see cref=\"T:System.Collections.Generic.ICollection`1\"/>.\n            /// </summary>\n            [Category(\"Behavior\"), Browsable(true), Description(\"Gets the number of elements contained in the collection.\")]\n            public int Count\n            {\n                get\n                {\n                    int count = 0;\n                    foreach (ImageListViewItem item in mImageListView.mItems)\n                        if (item.Selected) count++;\n                    return count;\n                }\n            }            /// <summary>\n            /// Gets a value indicating whether the <see cref=\"T:System.Collections.Generic.ICollection`1\"/> is read-only.\n            /// </summary>\n            [Category(\"Behavior\"), Browsable(false), Description(\"Gets a value indicating whether the collection is read-only.\")]\n            public bool IsReadOnly { get { return true; } }\n            /// <summary>\n            /// Gets the ImageListView owning this collection.\n            /// </summary>\n            [Category(\"Behavior\"), Browsable(false), Description(\"Gets the ImageListView owning this collection.\")]\n            public SEImageListView ImageListView { get { return mImageListView; } }\n            /// <summary>\n            /// Gets or sets the <see cref=\"NetHelpers.ImageListViewItem\"/> at the specified index.\n            /// </summary>\n            [Category(\"Behavior\"), Browsable(false), Description(\"Gets or sets the item at the specified index\")]\n            public ImageListViewItem this[int index]\n            {\n                get\n                {\n                    int i = 0;\n                    foreach (ImageListViewItem item in this)\n                    {\n                        if (i == index)\n                            return item;\n                        i++;\n                    }\n                    throw new ArgumentException(\"No item with the given index exists.\", \"index\");\n                }\n            }\n            #endregion\n\n            #region Instance Methods\n            /// <summary>\n            /// Determines whether the <see cref=\"T:System.Collections.Generic.ICollection`1\"/> contains a specific value.\n            /// </summary>\n            /// <param name=\"item\">The object to locate in the <see cref=\"T:System.Collections.Generic.ICollection`1\"/>.</param>\n            /// <returns>\n            /// true if <paramref name=\"item\"/> is found in the <see cref=\"T:System.Collections.Generic.ICollection`1\"/>; otherwise, false.\n            /// </returns>\n            public bool Contains(ImageListViewItem item)\n            {\n                return (item.Selected && mImageListView.Items.Contains(item));\n            }\n            /// <summary>\n            /// Returns an enumerator that iterates through the collection.\n            /// </summary>\n            /// <returns>\n            /// A <see cref=\"T:System.Collections.Generic.IEnumerator`1\"/> that can be used to iterate through the collection.\n            /// </returns>\n            public IEnumerator<ImageListViewItem> GetEnumerator()\n            {\n                return new ImageListViewSelectedItemEnumerator(mImageListView.mItems);\n            }\n            /// <summary>\n            /// Returns an enumerator that iterates through a collection.\n            /// </summary>\n            /// <returns>\n            /// An <see cref=\"T:System.Collections.IEnumerator\"/> object that can be used to iterate through the collection.\n            /// </returns>\n            System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()\n            {\n                return GetEnumerator();\n            }\n            #endregion\n\n            #region Helper Methods\n            /// <summary>\n            /// Removes all items from the <see cref=\"T:System.Collections.Generic.ICollection`1\"/>.\n            /// </summary>\n            /// <exception cref=\"T:System.NotSupportedException\">\n            /// The <see cref=\"T:System.Collections.Generic.ICollection`1\"/> is read-only.\n            /// </exception>\n            internal void Clear()\n            {\n                foreach (ImageListViewItem item in this)\n                    item.mSelected = false;\n                if (mImageListView != null)\n                    mImageListView.OnSelectionChangedInternal();\n            }\n            #endregion\n\n            #region Unsupported Interface\n            /// <summary>\n            /// Adds an item to the <see cref=\"T:System.Collections.Generic.ICollection`1\"/>.\n            /// </summary>\n            /// <param name=\"item\">The object to add to the <see cref=\"T:System.Collections.Generic.ICollection`1\"/>.</param>\n            /// <exception cref=\"T:System.NotSupportedException\">\n            /// The <see cref=\"T:System.Collections.Generic.ICollection`1\"/> is read-only.\n            /// </exception>\n            void ICollection<ImageListViewItem>.Add(ImageListViewItem item)\n            {\n                throw new NotSupportedException();\n            }\n            /// <summary>\n            /// Removes all items from the <see cref=\"T:System.Collections.Generic.ICollection`1\"/>.\n            /// </summary>\n            void ICollection<ImageListViewItem>.Clear()\n            {\n                throw new NotSupportedException();\n            }\n            /// <summary>\n            /// Copies the elements of the <see cref=\"T:System.Collections.Generic.ICollection`1\"/> to an <see cref=\"T:System.Array\"/>, starting at a particular <see cref=\"T:System.Array\"/> index.\n            /// </summary>\n            /// <param name=\"array\">The one-dimensional <see cref=\"T:System.Array\"/> that is the destination of the elements copied from <see cref=\"T:System.Collections.Generic.ICollection`1\"/>. The <see cref=\"T:System.Array\"/> must have zero-based indexing.</param>\n            /// <param name=\"arrayIndex\">The zero-based index in <paramref name=\"array\"/> at which copying begins.</param>\n            /// <exception cref=\"T:System.ArgumentNullException\">\n            /// \t<paramref name=\"array\"/> is null.\n            /// </exception>\n            /// <exception cref=\"T:System.ArgumentOutOfRangeException\">\n            /// \t<paramref name=\"arrayIndex\"/> is less than 0.\n            /// </exception>\n            /// <exception cref=\"T:System.ArgumentException\">\n            /// \t<paramref name=\"array\"/> is multidimensional.\n            /// -or-\n            /// <paramref name=\"arrayIndex\"/> is equal to or greater than the length of <paramref name=\"array\"/>.\n            /// -or-\n            /// The number of elements in the source <see cref=\"T:System.Collections.Generic.ICollection`1\"/> is greater than the available space from <paramref name=\"arrayIndex\"/> to the end of the destination <paramref name=\"array\"/>.\n            /// -or-\n            /// Type <paramref name=\"T\"/> cannot be cast automatically to the type of the destination <paramref name=\"array\"/>.\n            /// </exception>\n            void ICollection<ImageListViewItem>.CopyTo(ImageListViewItem[] array, int arrayIndex)\n            {\n                throw new NotSupportedException();\n            }\n            /// <summary>\n            /// Determines the index of a specific item in the <see cref=\"T:System.Collections.Generic.IList`1\"/>.\n            /// </summary>\n            /// <param name=\"item\">The object to locate in the <see cref=\"T:System.Collections.Generic.IList`1\"/>.</param>\n            /// <returns>\n            /// The index of <paramref name=\"item\"/> if found in the list; otherwise, -1.\n            /// </returns>\n            [Obsolete(\"Use ImageListViewItem.Index property instead.\")]\n            int IList<ImageListViewItem>.IndexOf(ImageListViewItem item)\n            {\n                throw new NotSupportedException();\n            }\n            /// <summary>\n            /// Inserts an item to the <see cref=\"T:System.Collections.Generic.IList`1\"/> at the specified index.\n            /// </summary>\n            /// <param name=\"index\">The zero-based index at which <paramref name=\"item\"/> should be inserted.</param>\n            /// <param name=\"item\">The object to insert into the <see cref=\"T:System.Collections.Generic.IList`1\"/>.</param>\n            /// <exception cref=\"T:System.ArgumentOutOfRangeException\">\n            /// \t<paramref name=\"index\"/> is not a valid index in the <see cref=\"T:System.Collections.Generic.IList`1\"/>.\n            /// </exception>\n            /// <exception cref=\"T:System.NotSupportedException\">\n            /// The <see cref=\"T:System.Collections.Generic.IList`1\"/> is read-only.\n            /// </exception>\n            void IList<ImageListViewItem>.Insert(int index, ImageListViewItem item)\n            {\n                throw new NotSupportedException();\n            }\n            /// <summary>\n            /// Removes the first occurrence of a specific object from the <see cref=\"T:System.Collections.Generic.ICollection`1\"/>.\n            /// </summary>\n            /// <param name=\"item\">The object to remove from the <see cref=\"T:System.Collections.Generic.ICollection`1\"/>.</param>\n            /// <returns>\n            /// true if <paramref name=\"item\"/> was successfully removed from the <see cref=\"T:System.Collections.Generic.ICollection`1\"/>; otherwise, false. This method also returns false if <paramref name=\"item\"/> is not found in the original <see cref=\"T:System.Collections.Generic.ICollection`1\"/>.\n            /// </returns>\n            /// <exception cref=\"T:System.NotSupportedException\">\n            /// The <see cref=\"T:System.Collections.Generic.ICollection`1\"/> is read-only.\n            /// </exception>\n            bool ICollection<ImageListViewItem>.Remove(ImageListViewItem item)\n            {\n                throw new NotSupportedException();\n            }\n            /// <summary>\n            /// Removes the <see cref=\"T:System.Collections.Generic.IList`1\"/> item at the specified index.\n            /// </summary>\n            /// <param name=\"index\">The zero-based index of the item to remove.</param>\n            /// <exception cref=\"T:System.ArgumentOutOfRangeException\">\n            /// \t<paramref name=\"index\"/> is not a valid index in the <see cref=\"T:System.Collections.Generic.IList`1\"/>.\n            /// </exception>\n            /// <exception cref=\"T:System.NotSupportedException\">\n            /// The <see cref=\"T:System.Collections.Generic.IList`1\"/> is read-only.\n            /// </exception>\n            void IList<ImageListViewItem>.RemoveAt(int index)\n            {\n                throw new NotSupportedException();\n            }\n            /// <summary>\n            /// Gets or sets the <see cref=\"NetHelpers.ImageListViewItem\"/> at the specified index.\n            /// </summary>\n            ImageListViewItem IList<ImageListViewItem>.this[int index]\n            {\n                get\n                {\n                    throw new NotSupportedException();\n                }\n                set\n                {\n                    throw new NotSupportedException();\n                }\n            }\n            #endregion\n\n            #region Internal Classes\n            /// <summary>\n            /// Represents an enumerator to walk though the selected items.\n            /// </summary>\n            internal class ImageListViewSelectedItemEnumerator : IEnumerator<ImageListViewItem>\n            {\n                #region Member Variables\n                private ImageListViewItemCollection owner;\n                private int current;\n                private Guid lastItem;\n                #endregion\n\n                #region Constructor\n                public ImageListViewSelectedItemEnumerator(ImageListViewItemCollection collection)\n                {\n                    owner = collection;\n                    current = -1;\n                    lastItem = Guid.Empty;\n                }\n                #endregion\n\n                #region Properties\n                /// <summary>\n                /// Gets the element in the collection at the current position of the enumerator.\n                /// </summary>\n                public ImageListViewItem Current\n                {\n                    get\n                    {\n                        if (current == -1 || current > owner.Count - 1)\n                            throw new InvalidOperationException();\n                        return owner[current];\n                    }\n                }\n                /// <summary>\n                /// Gets the element in the collection at the current position of the enumerator.\n                /// </summary>\n                object IEnumerator.Current\n                {\n                    get { return Current; }\n                }\n                #endregion\n\n                #region Instance Methods\n                /// <summary>\n                /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.\n                /// </summary>\n                public void Dispose()\n                {\n                    ;\n                }\n                /// <summary>\n                /// Advances the enumerator to the next element of the collection.\n                /// </summary>\n                public bool MoveNext()\n                {\n                    // Did we reach the end?\n                    if (current > owner.Count - 1)\n                    {\n                        lastItem = Guid.Empty;\n                        return false;\n                    }\n\n                    // Move to the next item if:\n                    // 1. We are before the first item. - OR -\n                    // 2. The current item is the same as the one we enumerated before. \n                    //    The current item may have differed if the user for example \n                    //    removed the current item between MoveNext calls. - OR -\n                    // 3. The current item is not selected.\n                    while (current == -1 ||\n                        owner[current].Guid == lastItem ||\n                        owner[current].Selected == false)\n                    {\n                        current++;\n                        if (current > owner.Count - 1)\n                        {\n                            lastItem = Guid.Empty;\n                            return false;\n                        }\n                    }\n\n                    // Cache the last item\n                    lastItem = owner[current].Guid;\n                    return true;\n                }\n                /// <summary>\n                /// Sets the enumerator to its initial position, which is before the first element in the collection.\n                /// </summary>\n                public void Reset()\n                {\n                    current = -1;\n                    lastItem = Guid.Empty;\n                }\n                #endregion\n            }\n            #endregion\n        }\n        /// <summary>\n        /// Represents an overridable class for image list view renderers.\n        /// </summary>\n        public class ImageListViewRenderer : IDisposable\n        {\n            #region Member Variables\n            internal SEImageListView mImageListView;\n            private BufferedGraphicsContext bufferContext;\n            private BufferedGraphics bufferGraphics;\n            private bool disposed;\n            private int suspendCount;\n            private bool needsPaint;\n            #endregion\n\n            #region Properties\n            /// <summary>\n            /// Gets the ImageListView owning this item.\n            /// </summary>\n            public SEImageListView ImageListView { get { return mImageListView; } }\n            #endregion\n\n            #region Constructors\n            public ImageListViewRenderer()\n            {\n                disposed = false;\n                suspendCount = 0;\n                needsPaint = true;\n            }\n            #endregion\n\n            #region Instance Methods\n            /// <summary>\n            /// Redraws the owner control.\n            /// </summary>\n            /// <param name=\"forceUpdate\">If true, forces an immediate update, even if\n            /// the renderer is suspended by a SuspendPaint call.</param>\n            internal void Refresh(bool forceUpdate)\n            {\n                if (forceUpdate || CanPaint())\n                    mImageListView.Refresh();\n                else\n                    needsPaint = true;\n            }\n            /// <summary>\n            /// Redraws the owner control.\n            /// </summary>\n            internal void Refresh()\n            {\n                Refresh(false);\n            }\n            /// <summary>\n            /// Suspends painting until a matching ResumePaint call is made.\n            /// </summary>\n            internal void SuspendPaint()\n            {\n                if (suspendCount == 0) needsPaint = false;\n                suspendCount++;\n            }\n            /// <summary>\n            /// Resumes painting. This call must be matched by a prior SuspendPaint call.\n            /// </summary>\n            internal void ResumePaint()\n            {\n                System.Diagnostics.Debug.Assert(\n                    suspendCount > 0,\n                    \"Suspend count does not match resume count.\",\n                    \"ResumePaint() must be matched by a prior SuspendPaint() call.\"\n                    );\n\n                suspendCount--;\n                if (needsPaint)\n                    Refresh();\n            }\n            /// <summary>\n            /// Determines if the control can be painted.\n            /// </summary>\n            internal bool CanPaint()\n            {\n                return (suspendCount == 0);\n            }\n            /// <summary>\n            /// Renders the control.\n            /// </summary>\n            internal void Render(Graphics graphics)\n            {\n                if (bufferGraphics == null)\n                    RecreateBuffer();\n\n                // Update the layout\n                mImageListView.layoutManager.Update();\n\n                // Set drawing area\n                Graphics g = bufferGraphics.Graphics;\n                g.ResetClip();\n\n                // Erase background\n                g.SetClip(mImageListView.layoutManager.ColumnHeaderBounds);\n                g.Clear(mImageListView.BackColor);\n                g.SetClip(mImageListView.layoutManager.ItemAreaBounds);\n                DrawBackground(g, mImageListView.layoutManager.ItemAreaBounds);\n\n                // Draw Border\n                g.ResetClip();\n                if (mImageListView.BorderStyle == BorderStyle.FixedSingle)\n                    ControlPaint.DrawBorder3D(g, mImageListView.ClientRectangle, Border3DStyle.Flat);\n                else if (mImageListView.BorderStyle == BorderStyle.Fixed3D)\n                    ControlPaint.DrawBorder3D(g, mImageListView.ClientRectangle, Border3DStyle.SunkenInner);\n\n                // Draw column headers\n                if (mImageListView.View == EnumView.Details)\n                {\n                    int x = mImageListView.layoutManager.ColumnHeaderBounds.Left;\n                    int y = mImageListView.layoutManager.ColumnHeaderBounds.Top;\n                    int h = MeasureColumnHeaderHeight();\n                    int lastX = 0;\n                    foreach (ImageListViewColumnHeader column in mImageListView.Columns.GetUIColumns())\n                    {\n                        EnumColumnState state = EnumColumnState.None;\n                        if (column.Hovered)\n                            state |= EnumColumnState.Hovered;\n                        if (mImageListView.nav.HoveredSeparator == column.Type)\n                            state |= EnumColumnState.SeparatorHovered;\n                        if (mImageListView.nav.SelSeperator == column.Type)\n                            state |= EnumColumnState.SeparatorSelected;\n\n                        Rectangle bounds = new Rectangle(x, y, column.Width, h);\n                        Rectangle clip = Rectangle.Intersect(bounds, mImageListView.layoutManager.ClientArea);\n                        g.SetClip(clip);\n                        DrawColumnHeader(g, column, state, bounds);\n                        x += column.Width;\n                        lastX = bounds.Right;\n                    }\n\n                    // Extender column\n                    if (mImageListView.Columns.Count != 0)\n                    {\n                        if (lastX < mImageListView.layoutManager.ItemAreaBounds.Right)\n                        {\n                            Rectangle extender = new Rectangle(lastX, mImageListView.layoutManager.ColumnHeaderBounds.Top, mImageListView.layoutManager.ItemAreaBounds.Right - lastX, mImageListView.layoutManager.ColumnHeaderBounds.Height);\n                            g.SetClip(extender);\n                            DrawColumnExtender(g, extender);\n                        }\n                    }\n                    else\n                    {\n                        Rectangle extender = mImageListView.layoutManager.ColumnHeaderBounds;\n                        g.SetClip(extender);\n                        DrawColumnExtender(g, extender);\n                    }\n                }\n\n                // Draw items\n                if (mImageListView.Items.Count > 0 &&\n                    (mImageListView.View == EnumView.Thumbnails ||\n                    (mImageListView.View == EnumView.Details && mImageListView.Columns.GetUIColumns().Count != 0)))\n                {\n                    for (int i = mImageListView.layoutManager.FirstPartiallyVisible; i <= mImageListView.layoutManager.LastPartiallyVisible; i++)\n                    {\n                        ImageListViewItem item = mImageListView.Items[i];\n\n                        EnumItemState state = EnumItemState.None;\n                        bool isSelected;\n                        if (mImageListView.nav.Highlight.TryGetValue(item, out isSelected))\n                        {\n                            if (isSelected)\n                                state |= EnumItemState.Selected;\n                        }\n                        else if (item.Selected)\n                            state |= EnumItemState.Selected;\n\n                        if (item.Hovered && mImageListView.nav.Dragging == false)\n                            state |= EnumItemState.Hovered;\n\n                        if (item.Focused)\n                            state |= EnumItemState.Focused;\n\n                        Rectangle bounds = mImageListView.layoutManager.GetItemBounds(i);\n                        Rectangle clip = Rectangle.Intersect(bounds, mImageListView.layoutManager.ItemAreaBounds);\n                        g.SetClip(clip);\n\n                        DrawItem(g, item, state, bounds);\n                    }\n                }\n\n                // Scrollbar filler\n                if (mImageListView.hScrollBar.Visible && mImageListView.vScrollBar.Visible)\n                {\n                    Rectangle bounds = mImageListView.layoutManager.ItemAreaBounds;\n                    Rectangle filler = new Rectangle(bounds.Right, bounds.Bottom, mImageListView.vScrollBar.Width, mImageListView.hScrollBar.Height);\n                    g.SetClip(filler);\n                    DrawScrollBarFiller(g, filler);\n                }\n\n                // Draw the selection rectangle\n                if (mImageListView.nav.Dragging)\n                {\n                    Rectangle sel = new Rectangle(System.Math.Min(mImageListView.nav.SelStart.X, mImageListView.nav.SelEnd.X), System.Math.Min(mImageListView.nav.SelStart.Y, mImageListView.nav.SelEnd.Y), System.Math.Abs(mImageListView.nav.SelStart.X - mImageListView.nav.SelEnd.X), System.Math.Abs(mImageListView.nav.SelStart.Y - mImageListView.nav.SelEnd.Y));\n                    if (sel.Height > 0 && sel.Width > 0)\n                    {\n                        Rectangle selclip = new Rectangle(sel.Left, sel.Top, sel.Width + 1, sel.Height + 1);\n                        g.SetClip(selclip);\n                        g.ExcludeClip(mImageListView.layoutManager.ColumnHeaderBounds);\n                        DrawSelectionRectangle(g, sel);\n                    }\n                }\n\n                // Draw the insertion caret\n                if (mImageListView.nav.DragIndex != -1)\n                {\n                    int i = mImageListView.nav.DragIndex;\n                    Rectangle bounds = bounds = mImageListView.layoutManager.GetItemBounds(i);\n                    if (mImageListView.nav.DragCaretOnRight)\n                        bounds.Offset(mImageListView.layoutManager.ItemSizeWithMargin.Width, 0);\n                    bounds.Offset(-mImageListView.ItemMargin.Width, 0);\n                    bounds.Width = mImageListView.ItemMargin.Width;\n                    g.SetClip(bounds);\n                    DrawInsertionCaret(g, bounds);\n                }\n\n                // Draw on to the control\n                bufferGraphics.Render(graphics);\n            }\n            /// <summary>\n            /// Destroys the current buffer and creates a new buffered graphics \n            /// sized to the client area of the owner control.\n            /// </summary>\n            internal void RecreateBuffer()\n            {\n                bufferContext = BufferedGraphicsManager.Current;\n\n                if (disposed)\n                    throw (new ObjectDisposedException(\"bufferContext\"));\n\n                int width = System.Math.Max(mImageListView.Width, 1);\n                int height = System.Math.Max(mImageListView.Height, 1);\n\n                bufferContext.MaximumBuffer = new Size(width, height);\n\n                if (bufferGraphics != null) bufferGraphics.Dispose();\n                bufferGraphics = bufferContext.Allocate(mImageListView.CreateGraphics(), new Rectangle(0, 0, width, height));\n            }\n            /// <summary>\n            /// Releases buffered graphics objects.\n            /// </summary>\n            public void Dispose()\n            {\n                if (disposed) return;\n                disposed = true;\n\n                if (bufferGraphics != null)\n                    bufferGraphics.Dispose();\n            }\n            #endregion\n\n            #region Virtual Methods\n            /// <summary>\n            /// Returns the height of column headers.\n            /// </summary>\n            public virtual int MeasureColumnHeaderHeight()\n            {\n                if (mImageListView.HeaderFont == null)\n                    return 24;\n                else\n                    return System.Math.Max(mImageListView.HeaderFont.Height + 4, 24);\n            }\n            /// <summary>\n            /// Returns item size for the given view mode.\n            /// </summary>\n            /// <param name=\"view\">The view mode for which the item measurement should be made.</param>\n            public virtual Size MeasureItem(EnumView view)\n            {\n                Size itemSize = new Size();\n\n                // Reference text height\n                int textHeight = mImageListView.Font.Height;\n\n                if (mImageListView.View == EnumView.Thumbnails)\n                {\n                    // Calculate item size\n                    Size itemPadding = new Size(4, 4);\n                    itemSize = mImageListView.ThumbnailSize + itemPadding + itemPadding;\n                    itemSize.Height += textHeight + System.Math.Max(4, textHeight / 3); // textHeight / 3 = vertical space between thumbnail and text\n                }\n                else if (mImageListView.View == EnumView.Details)\n                {\n                    // Calculate total column width\n                    int colWidth = 0;\n                    foreach (ImageListViewColumnHeader column in mImageListView.Columns)\n                        if (column.Visible) colWidth += column.Width;\n\n                    // Calculate item size\n                    itemSize = new Size(colWidth, textHeight + 2 * textHeight / 6); // textHeight / 6 = vertical space between item border and text\n                }\n\n                return itemSize;\n            }\n            /// <summary>\n            /// Draws the background of the control.\n            /// </summary>\n            /// <param name=\"g\">The System.Drawing.Graphics to draw on.</param>\n            /// <param name=\"bounds\">The client coordinates of the item area.</param>\n            public virtual void DrawBackground(Graphics g, Rectangle bounds)\n            {\n                // Clear the background\n                g.Clear(mImageListView.BackColor);\n\n                // Draw the background image\n                if (ImageListView.BackgroundImage != null)\n                {\n                    Image img = ImageListView.BackgroundImage;\n\n                    if (ImageListView.BackgroundImageLayout == ImageLayout.None)\n                    {\n                        g.DrawImageUnscaled(img, ImageListView.layoutManager.ItemAreaBounds.Location);\n                    }\n                    else if (ImageListView.BackgroundImageLayout == ImageLayout.Center)\n                    {\n                        int x = bounds.Left + (bounds.Width - img.Width) / 2;\n                        int y = bounds.Top + (bounds.Height - img.Height) / 2;\n                        g.DrawImageUnscaled(img, x, y);\n                    }\n                    else if (ImageListView.BackgroundImageLayout == ImageLayout.Stretch)\n                    {\n                        g.DrawImage(img, bounds);\n                    }\n                    else if (ImageListView.BackgroundImageLayout == ImageLayout.Tile)\n                    {\n                        using (Brush imgBrush = new TextureBrush(img, WrapMode.Tile))\n                        {\n                            g.FillRectangle(imgBrush, bounds);\n                        }\n                    }\n                    else if (ImageListView.BackgroundImageLayout == ImageLayout.Zoom)\n                    {\n                        float xscale = (float)bounds.Width / (float)img.Width;\n                        float yscale = (float)bounds.Height / (float)img.Height;\n                        float scale = Math.Min(xscale, yscale);\n                        int width = (int)(((float)img.Width) * scale);\n                        int height = (int)(((float)img.Height) * scale);\n                        int x = bounds.Left + (bounds.Width - width) / 2;\n                        int y = bounds.Top + (bounds.Height - height) / 2;\n                        g.DrawImage(img, x, y, width, height);\n                    }\n                }\n            }\n            /// <summary>\n            /// Draws the selection rectangle.\n            /// </summary>\n            /// <param name=\"g\">The System.Drawing.Graphics to draw on.</param>\n            /// <param name=\"selection\">The client coordinates of the selection rectangle.</param>\n            public virtual void DrawSelectionRectangle(Graphics g, Rectangle selection)\n            {\n                using (Brush bSelection = new SolidBrush(Color.FromArgb(128, SystemColors.Highlight)))\n                {\n                    g.FillRectangle(bSelection, selection);\n                    g.DrawRectangle(SystemPens.Highlight, selection);\n                }\n            }\n            /// <summary>\n            /// Draws the specified item on the given graphics.\n            /// </summary>\n            /// <param name=\"g\">The System.Drawing.Graphics to draw on.</param>\n            /// <param name=\"item\">The ImageListViewItem to draw.</param>\n            /// <param name=\"state\">The current view state of item.</param>\n            /// <param name=\"bounds\">The bounding rectangle of item in client coordinates.</param>\n            public virtual void DrawItem(Graphics g, ImageListViewItem item, EnumItemState state, Rectangle bounds)\n            {\n                Size itemPadding = new Size(4, 4);\n\n                // Paint background\n                using (Brush bItemBack = new SolidBrush(item.BackColor))\n                {\n                    g.FillRectangle(bItemBack, bounds);\n                }\n                if (mImageListView.Focused && ((state & EnumItemState.Selected) != EnumItemState.None))\n                {\n                    using (Brush bSelected = new LinearGradientBrush(bounds, Color.FromArgb(16, SystemColors.Highlight), Color.FromArgb(64, SystemColors.Highlight), LinearGradientMode.Vertical))\n                    {\n                        Utility.FillRoundedRectangle(g, bSelected, bounds, (mImageListView.View == EnumView.Details ? 2 : 4));\n                    }\n                }\n                else if (!mImageListView.Focused && ((state & EnumItemState.Selected) != EnumItemState.None))\n                {\n                    using (Brush bGray64 = new LinearGradientBrush(bounds, Color.FromArgb(16, SystemColors.GrayText), Color.FromArgb(64, SystemColors.GrayText), LinearGradientMode.Vertical))\n                    {\n                        Utility.FillRoundedRectangle(g, bGray64, bounds, (mImageListView.View == EnumView.Details ? 2 : 4));\n                    }\n                }\n                if (((state & EnumItemState.Hovered) != EnumItemState.None))\n                {\n                    using (Brush bHovered = new LinearGradientBrush(bounds, Color.FromArgb(8, SystemColors.Highlight), Color.FromArgb(32, SystemColors.Highlight), LinearGradientMode.Vertical))\n                    {\n                        Utility.FillRoundedRectangle(g, bHovered, bounds, (mImageListView.View == EnumView.Details ? 2 : 4));\n                    }\n                }\n\n                if (mImageListView.View == EnumView.Thumbnails)\n                {\n                    // Draw the image\n                    Image img = item.ThumbnailImage;\n                    if (img != null)\n                    {\n                        int x = bounds.Left + itemPadding.Width + (mImageListView.ThumbnailSize.Width - img.Width) / 2;\n                        int y = bounds.Top + itemPadding.Height + (mImageListView.ThumbnailSize.Height - img.Height) / 2;\n                        g.DrawImageUnscaled(img, x, y);\n                        // Draw image border\n                        if (img.Width > 32)\n                        {\n                            using (Pen pGray128 = new Pen(Color.FromArgb(128, Color.Gray)))\n                            {\n                                g.DrawRectangle(pGray128, x, y, img.Width, img.Height);\n                            }\n                            if (System.Math.Min(mImageListView.ThumbnailSize.Width, mImageListView.ThumbnailSize.Height) > 32)\n                            {\n                                using (Pen pWhite128 = new Pen(Color.FromArgb(128, Color.White)))\n                                {\n                                    g.DrawRectangle(pWhite128, x + 1, y + 1, img.Width - 2, img.Height - 2);\n                                }\n                            }\n                        }\n                    }\n\n                    // Draw item text\n                    SizeF szt = TextRenderer.MeasureText(item.Text, mImageListView.Font);\n                    RectangleF rt;\n                    StringFormat sf = new StringFormat();\n                    rt = new RectangleF(bounds.Left + itemPadding.Width, bounds.Top + 2 * itemPadding.Height + mImageListView.ThumbnailSize.Height, mImageListView.ThumbnailSize.Width, szt.Height);\n                    sf.Alignment = StringAlignment.Center;\n                    sf.FormatFlags = StringFormatFlags.NoWrap;\n                    sf.LineAlignment = StringAlignment.Center;\n                    sf.Trimming = StringTrimming.EllipsisCharacter;\n                    using (Brush bItemFore = new SolidBrush(item.ForeColor))\n                    {\n                        g.DrawString(item.Text, mImageListView.Font, bItemFore, rt, sf);\n                    }\n                }\n                else if (mImageListView.View == EnumView.Details)\n                {\n                    // Separators \n                    int x = mImageListView.layoutManager.ColumnHeaderBounds.Left;\n                    List<ImageListViewColumnHeader> uicolumns = mImageListView.Columns.GetUIColumns();\n                    foreach (ImageListViewColumnHeader column in uicolumns)\n                    {\n                        x += column.Width;\n                        if (!ReferenceEquals(column, uicolumns[uicolumns.Count - 1]))\n                        {\n                            using (Pen pGray32 = new Pen(Color.FromArgb(32, SystemColors.GrayText)))\n                            {\n                                g.DrawLine(pGray32, x, bounds.Top, x, bounds.Bottom);\n                            }\n                        }\n                    }\n                    Size offset = new Size(2, (bounds.Height - mImageListView.Font.Height) / 2);\n                    StringFormat sf = new StringFormat();\n                    sf.FormatFlags = StringFormatFlags.NoWrap;\n                    sf.Alignment = StringAlignment.Near;\n                    sf.LineAlignment = StringAlignment.Center;\n                    sf.Trimming = StringTrimming.EllipsisCharacter;\n                    // Sub text\n                    RectangleF rt = new RectangleF(bounds.Left + offset.Width, bounds.Top + offset.Height, uicolumns[0].Width - 2 * offset.Width, bounds.Height - 2 * offset.Height);\n                    foreach (ImageListViewColumnHeader column in uicolumns)\n                    {\n                        rt.Width = column.Width - 2 * offset.Width;\n                        using (Brush bItemFore = new SolidBrush(item.ForeColor))\n                        {\n                            g.DrawString(item.GetSubItemText(column.Type), mImageListView.Font, bItemFore, rt, sf);\n                        }\n                        rt.X += column.Width;\n                    }\n                }\n\n                // Item border\n                using (Pen pWhite128 = new Pen(Color.FromArgb(128, Color.White)))\n                {\n                    Utility.DrawRoundedRectangle(g, pWhite128, bounds.Left + 1, bounds.Top + 1, bounds.Width - 3, bounds.Height - 3, (mImageListView.View == EnumView.Details ? 2 : 4));\n                }\n                if (mImageListView.Focused && ((state & EnumItemState.Focused) != EnumItemState.None))\n                    ControlPaint.DrawFocusRectangle(g, bounds);\n                else if (mImageListView.Focused && ((state & EnumItemState.Selected) != EnumItemState.None))\n                {\n                    using (Pen pHighlight128 = new Pen(Color.FromArgb(128, SystemColors.Highlight)))\n                    {\n                        Utility.DrawRoundedRectangle(g, pHighlight128, bounds.Left, bounds.Top, bounds.Width - 1, bounds.Height - 1, (mImageListView.View == EnumView.Details ? 2 : 4));\n                    }\n                }\n                else if (!mImageListView.Focused && ((state & EnumItemState.Selected) != EnumItemState.None))\n                {\n                    using (Pen pGray128 = new Pen(Color.FromArgb(128, SystemColors.GrayText)))\n                    {\n                        Utility.DrawRoundedRectangle(g, pGray128, bounds.Left, bounds.Top, bounds.Width - 1, bounds.Height - 1, (mImageListView.View == EnumView.Details ? 2 : 4));\n                    }\n                }\n                else if (mImageListView.View == EnumView.Thumbnails && (state & EnumItemState.Selected) == EnumItemState.None)\n                {\n                    using (Pen pGray64 = new Pen(Color.FromArgb(64, SystemColors.GrayText)))\n                    {\n                        Utility.DrawRoundedRectangle(g, pGray64, bounds.Left, bounds.Top, bounds.Width - 1, bounds.Height - 1, (mImageListView.View == EnumView.Details ? 2 : 4));\n                    }\n                }\n\n                if (mImageListView.Focused && ((state & EnumItemState.Hovered) != EnumItemState.None))\n                {\n                    using (Pen pHighlight64 = new Pen(Color.FromArgb(64, SystemColors.Highlight)))\n                    {\n                        Utility.DrawRoundedRectangle(g, pHighlight64, bounds.Left, bounds.Top, bounds.Width - 1, bounds.Height - 1, (mImageListView.View == EnumView.Details ? 2 : 4));\n                    }\n                }\n            }\n            /// <summary>\n            /// Draws the column headers.\n            /// </summary>\n            /// <param name=\"g\">The System.Drawing.Graphics to draw on.</param>\n            /// <param name=\"column\">The ImageListViewColumnHeader to draw.</param>\n            /// <param name=\"state\">The current view state of column.</param>\n            /// <param name=\"bounds\">The bounding rectangle of column in client coordinates.</param>\n            public virtual void DrawColumnHeader(Graphics g, ImageListViewColumnHeader column, EnumColumnState state, Rectangle bounds)\n            {\n                StringFormat sf = new StringFormat();\n                sf.FormatFlags = StringFormatFlags.NoWrap;\n                sf.Alignment = StringAlignment.Near;\n                sf.LineAlignment = StringAlignment.Center;\n                sf.Trimming = StringTrimming.EllipsisCharacter;\n\n                // Paint background\n                if (mImageListView.Focused && column.Hovered)\n                {\n                    using (Brush bHovered = new LinearGradientBrush(bounds, Color.FromArgb(16, SystemColors.Highlight), Color.FromArgb(64, SystemColors.Highlight), LinearGradientMode.Vertical))\n                    {\n                        g.FillRectangle(bHovered, bounds);\n                    }\n                }\n                else\n                {\n                    using (Brush bNormal = new LinearGradientBrush(bounds, Color.FromArgb(32, SystemColors.Control), Color.FromArgb(196, SystemColors.Control), LinearGradientMode.Vertical))\n                    {\n                        g.FillRectangle(bNormal, bounds);\n                    }\n                }\n                using (Brush bBorder = new LinearGradientBrush(bounds, SystemColors.ControlLightLight, SystemColors.ControlDark, LinearGradientMode.Vertical))\n                using (Pen pBorder = new Pen(bBorder))\n                {\n                    g.DrawLine(pBorder, bounds.Left, bounds.Top, bounds.Left, bounds.Bottom);\n                    g.DrawLine(pBorder, bounds.Left, bounds.Bottom - 1, bounds.Right, bounds.Bottom - 1);\n                }\n                g.DrawLine(SystemPens.ControlLightLight, bounds.Left + 1, bounds.Top + 1, bounds.Left + 1, bounds.Bottom - 2);\n                g.DrawLine(SystemPens.ControlLightLight, bounds.Right - 1, bounds.Top + 1, bounds.Right - 1, bounds.Bottom - 2);\n\n                // Sort image\n                int textOffset = 4;\n                if (column.Type == mImageListView.SortColumn && mImageListView.SortOrder != EnumSortOrder.None)\n                {\n                    Image img = GetSortArrowImage(mImageListView.SortOrder);\n                    if (img != null)\n                    {\n                        g.DrawImageUnscaled(img, bounds.X + 4, bounds.Top + (bounds.Height - img.Height) / 2);\n                        textOffset += img.Width;\n                    }\n                }\n\n                // Text\n                bounds.X += textOffset;\n                bounds.Width -= textOffset;\n                if (bounds.Width > 4)\n                    g.DrawString(column.Text, (mImageListView.HeaderFont == null ? mImageListView.Font : mImageListView.HeaderFont), SystemBrushes.WindowText, bounds, sf);\n            }\n            /// <summary>\n            /// Draws the extender after the last column.\n            /// </summary>\n            /// <param name=\"g\">The System.Drawing.Graphics to draw on.</param>\n            /// <param name=\"bounds\">The bounding rectangle of extender column in client coordinates.</param>\n            public virtual void DrawColumnExtender(Graphics g, Rectangle bounds)\n            {\n                // Paint background\n                using (Brush bBack = new LinearGradientBrush(bounds, Color.FromArgb(32, SystemColors.Control), Color.FromArgb(196, SystemColors.Control), LinearGradientMode.Vertical))\n                {\n                    g.FillRectangle(bBack, bounds);\n                }\n                using (Brush bBorder = new LinearGradientBrush(bounds, SystemColors.ControlLightLight, SystemColors.ControlDark, LinearGradientMode.Vertical))\n                using (Pen pBorder = new Pen(bBorder))\n                {\n                    g.DrawLine(pBorder, bounds.Left, bounds.Top, bounds.Left, bounds.Bottom);\n                    g.DrawLine(pBorder, bounds.Left, bounds.Bottom - 1, bounds.Right, bounds.Bottom - 1);\n                }\n                g.DrawLine(SystemPens.ControlLightLight, bounds.Left + 1, bounds.Top + 1, bounds.Left + 1, bounds.Bottom - 2);\n                g.DrawLine(SystemPens.ControlLightLight, bounds.Right - 1, bounds.Top + 1, bounds.Right - 1, bounds.Bottom - 2);\n            }\n            /// <summary>\n            /// Draws the area between the vertical and horizontal scrollbars.\n            /// </summary>\n            /// <param name=\"g\">The System.Drawing.Graphics to draw on.</param>\n            /// <param name=\"bounds\">The bounding rectangle of the filler in client coordinates.</param>\n            public virtual void DrawScrollBarFiller(Graphics g, Rectangle bounds)\n            {\n                g.FillRectangle(SystemBrushes.Control, bounds);\n            }\n            /// <summary>\n            /// Gets the image representing the sort arrow on column headers.\n            /// </summary>\n            /// <param name=\"sortOrder\">The SortOrder for which the sort arrow image should be returned.</param>\n            /// <returns>The sort arrow image representing sortOrder.</returns>\n            public virtual Image GetSortArrowImage(EnumSortOrder sortOrder)\n            {\n                if (mImageListView.SortOrder == EnumSortOrder.Ascending)\n                {\n                    return Utility.ImageFromBase64String(@\"iVBORw0KGgoAAAANSUhEUgAAAAoAAAAGCAYAAAD68A/GAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAHNJREFUGFdjYCAXFB9LP1lwKPUIXv1FR9Mudpyq+996ovp/xo7Y8xiKS45nsBUdSbvdfqrm//Jr8/4vvTLnf+2B4v9xa0JvRi4LYINrKDycujtvf9L35mOV/xdfmfV/4eUZ/9sO1/6PWOL/PXie1w6SvAEA+BE3G3fNEd8AAAAASUVORK5CYII=\");\n                }\n                else if (mImageListView.SortOrder == EnumSortOrder.Descending)\n                    return Utility.ImageFromBase64String(@\"iVBORw0KGgoAAAANSUhEUgAAAAoAAAAGCAYAAAD68A/GAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAHNJREFUGFdjYCAFeE1y2uHaY/s9Z23q/6ZDtf8bDlb9D5jk/V8nV/27RobKbrhZzl02bHbNFjfDZwb+rztQ+b9mf9l/7163/+ppyreVkxTYMCw1LtU979vv8d+rx/W/WqrSRbyu0sxUPaKaoniSFKejqAUAXY8qTCsVRMkAAAAASUVORK5CYII=\");\n                return\n                    null;\n            }\n            /// <summary>\n            /// Draws the insertion caret for drag & drop operations.\n            /// </summary>\n            /// <param name=\"g\">The System.Drawing.Graphics to draw on.</param>\n            /// <param name=\"bounds\">The bounding rectangle of the insertion caret.</param>\n            public virtual void DrawInsertionCaret(Graphics g, Rectangle bounds)\n            {\n                using (Brush b = new SolidBrush(SystemColors.Highlight))\n                {\n                    bounds.X = bounds.X + bounds.Width / 2 - 1;\n                    bounds.Width = 2;\n                    g.FillRectangle(b, bounds);\n                }\n            }\n            #endregion\n        }\n        /// <summary>\n        /// Represents the details of a mouse hit test.\n        /// </summary>\n        public struct HitInfo\n        {\n            #region Member Variables\n            public bool InHeaderArea;\n            public bool InItemArea;\n            public bool ColumnHit;\n            public bool ItemHit;\n            public bool ColumnSeparatorHit;\n            public EnumColumnType ColumnIndex;\n            public int ItemIndex;\n            public EnumColumnType ColumnSeparator;\n            #endregion\n        }\n        #endregion\n\n        #region Internal Classes\n        /// <summary>\n        /// Represents the cache manager responsible for asynchronously loading\n        /// item details.\n        /// </summary>\n        internal class ImageListViewItemCacheManager\n        {\n            #region Member Variables\n            private SEImageListView mImageListView;\n            private Thread mThread;\n\n            private Queue<CacheItem> toCache;\n            #endregion\n\n            #region Private Classes\n            /// <summary>\n            /// Represents an item in the item cache.\n            /// </summary>\n            private class CacheItem\n            {\n                private ImageListViewItem mItem;\n                private string mFileName;\n\n                /// <summary>\n                /// Gets the item.\n                /// </summary>\n                public ImageListViewItem Item { get { return mItem; } }\n                /// <summary>\n                /// Gets the name of the image file.\n                /// </summary>\n                public string FileName { get { return mFileName; } }\n\n                public CacheItem(ImageListViewItem item)\n                {\n                    mItem = item;\n                    mFileName = item.FileName;\n                }\n            }\n            #endregion\n\n            #region Properties\n            /// <summary>\n            /// Gets the owner image list view.\n            /// </summary>\n            public SEImageListView ImageListView { get { return mImageListView; } }\n            /// <summary>\n            /// Gets the thumbnail generator thread.\n            /// </summary>\n            public Thread Thread { get { return mThread; } }\n            #endregion\n\n            #region Constructor\n            public ImageListViewItemCacheManager(SEImageListView owner)\n            {\n                mImageListView = owner;\n\n                toCache = new Queue<CacheItem>();\n\n                mThread = new Thread(new ParameterizedThreadStart(DoWork));\n                mThread.IsBackground = true;\n            }\n            #endregion\n\n            #region Instance Methods\n            /// <summary>\n            /// Starts the thumbnail generator thread.\n            /// </summary>\n            public void Start()\n            {\n                //cxs\n                //窗体hide后线程会被OnHandleDestroyed事件终止，这里做判断为OnHandleCreated重新调用提供条件\n                if (mThread.ThreadState == ThreadState.Stopped)\n                {\n                    mThread = new Thread(new ParameterizedThreadStart(DoWork));\n                    mThread.IsBackground = true;\n                }\n\n                mThread.Start(this);\n                while (!mThread.IsAlive) ;\n            }\n            /// <summary>\n            /// Stops the thumbnail generator thread.\n            /// </summary>\n            public void Stop()\n            {\n                if (mThread.IsAlive)\n                {\n                    mThread.Abort();\n                    mThread.Join();\n                }\n            }\n            /// <summary>\n            /// Adds the item to the cache queue.\n            /// </summary>\n            public void AddToCache(ImageListViewItem item)\n            {\n                if (!item.isDirty)\n                    return;\n\n                lock (toCache)\n                {\n                    toCache.Enqueue(new CacheItem(item));\n                    Monitor.Pulse(toCache);\n                }\n            }\n            #endregion\n\n            #region Static Methods\n            /// <summary>\n            /// Used by the worker thread to read item data.\n            /// </summary>\n            private static void DoWork(object data)\n            {\n                ImageListViewItemCacheManager owner = (ImageListViewItemCacheManager)data;\n\n                while (true)\n                {\n                    CacheItem item = null;\n                    lock (owner.toCache)\n                    {\n                        // Wait until we have items waiting to be cached\n                        if (owner.toCache.Count == 0)\n                            Monitor.Wait(owner.toCache);\n\n                        // Get an item from the queue\n                        item = owner.toCache.Dequeue();\n                    }\n                    // Read file info\n                    string filename = item.FileName;\n                    Utility.ShellFileInfo info = new Utility.ShellFileInfo(filename);\n                    string path = Path.GetDirectoryName(filename);\n                    string name = Path.GetFileName(filename);\n                    Size dimension;\n                    SizeF resolution;\n                    try\n                    {\n                        using (FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read))\n                        {\n                            //cxs\n                            //如果使用了无法创建Image对象的流，如选了一个文本文件过来，这里会抛出参数错误异常\n                            //需要处理这个异常，在外面的using 上try catch了\n                            using (Image img = Image.FromStream(stream, false, false))\n                            {\n                                dimension = img.Size;\n                                resolution = new SizeF(img.HorizontalResolution, img.VerticalResolution);\n                            }\n                        }\n\n                        // Update file info\n                        if (!info.Error)\n                        {\n                            lock (item.Item)\n                            {\n                                item.Item.UpdateDetailsInternal(info.LastAccessTime, info.CreationTime, info.LastWriteTime,\n                                info.Size, info.TypeName, path, name, dimension, resolution);\n                            }\n                        }\n                    }\n                    catch { }\n                }\n            }\n            #endregion\n        }\n        /// <summary>\n        /// Represents the cache manager responsible for asynchronously loading\n        /// item thumbnails.\n        /// </summary>\n        internal class ImageListViewCacheManager\n        {\n            #region Constants\n            private const int PropertyTagThumbnailData = 0x501B;\n            private const int PropertyTagThumbnailImageWidth = 0x5020;\n            private const int PropertyTagThumbnailImageHeight = 0x5021;\n            private const float EmbeddedThumbnailSizeTolerance = 1.2f;\n            #endregion\n\n            #region Member Variables\n            private SEImageListView mImageListView;\n            private int mCacheSize;\n            private Thread mThread;\n\n            private Dictionary<Guid, CacheItem> toCache;\n            private Dictionary<Guid, CacheItem> thumbCache;\n            #endregion\n\n            #region Private Classes\n            /// <summary>\n            /// Represents an item in the thumbnail cache.\n            /// </summary>\n            private class CacheItem\n            {\n                private string mFileName;\n                private Size mSize;\n                private Image mImage;\n                private EnumCacheState mState;\n                private EnumUseEmbeddedThumbnails mUseEmbeddedThumbnails;\n\n                /// <summary>\n                /// Gets the name of the image file.\n                /// </summary>\n                public string FileName { get { return mFileName; } }\n                /// <summary>\n                /// Gets the size of the requested thumbnail.\n                /// </summary>\n                public Size Size { get { return mSize; } }\n                /// <summary>\n                /// Gets the cached image.\n                /// </summary>\n                public Image Image { get { return mImage; } }\n                /// <summary>\n                /// Gets the state of the cache item.\n                /// </summary>\n                public EnumCacheState State { get { return mState; } }\n                /// <summary>\n                /// Gets embedded thumbnail extraction behavior.\n                /// </summary>\n                public EnumUseEmbeddedThumbnails UseEmbeddedThumbnails { get { return mUseEmbeddedThumbnails; } }\n\n                public CacheItem(string filename, Size size, Image image, EnumCacheState state)\n                {\n                    mFileName = filename;\n                    mSize = size;\n                    mImage = image;\n                    mState = state;\n                }\n\n                public CacheItem(string filename, Size size, Image image, EnumCacheState state, EnumUseEmbeddedThumbnails useEmbeddedThumbnails)\n                    : this(filename, size, image, state)\n                {\n                    mUseEmbeddedThumbnails = useEmbeddedThumbnails;\n                }\n            }\n            #endregion\n\n            #region Properties\n            /// <summary>\n            /// Gets or sets the cache limit. A value of 0 disables the limit.\n            /// </summary>\n            public int CacheSize { get { return mCacheSize; } set { mCacheSize = value; } }\n            /// <summary>\n            /// Gets the owner image list view.\n            /// </summary>\n            public SEImageListView ImageListView { get { return mImageListView; } }\n            /// <summary>\n            /// Gets the thumbnail generator thread.\n            /// </summary>\n            public Thread Thread { get { return mThread; } }\n            #endregion\n\n            #region Constructor\n            public ImageListViewCacheManager(SEImageListView owner, int cacheSize)\n            {\n                mImageListView = owner;\n                mCacheSize = cacheSize;\n\n                toCache = new Dictionary<Guid, CacheItem>();\n                thumbCache = new Dictionary<Guid, CacheItem>();\n\n                mThread = new Thread(new ParameterizedThreadStart(DoWork));\n                mThread.IsBackground = true;\n            }\n            #endregion\n\n            #region Instance Methods\n            /// <summary>\n            /// Gets the cache state of the specified item.\n            /// </summary>\n            public EnumCacheState GetCacheState(Guid guid)\n            {\n                EnumCacheState state = EnumCacheState.Unknown;\n\n                lock (thumbCache)\n                {\n                    if (thumbCache.ContainsKey(guid))\n                        state = thumbCache[guid].State;\n                }\n                if (state == EnumCacheState.Unknown)\n                {\n                    lock (toCache)\n                    {\n                        if (toCache.ContainsKey(guid))\n                            state = toCache[guid].State;\n                    }\n                }\n\n                return state;\n            }\n            /// <summary>\n            /// Starts the thumbnail generator thread.\n            /// </summary>\n            public void Start()\n            {\n                //cxs\n                //窗体hide后线程会被OnHandleDestroyed事件终止，这里做判断为OnHandleCreated重新调用提供条件\n                if (mThread.ThreadState == ThreadState.Stopped)\n                {\n                    mThread = new Thread(new ParameterizedThreadStart(DoWork));\n                    mThread.IsBackground = true;\n                }\n\n                mThread.Start(this);\n                while (!mThread.IsAlive) ;\n            }\n            /// <summary>\n            /// Stops the thumbnail generator thread.\n            /// </summary>\n            public void Stop()\n            {\n                if (mThread.IsAlive)\n                {\n                    mThread.Abort();\n                    mThread.Join();\n                }\n            }\n            /// <summary>\n            /// Cleans the thumbnail cache.\n            /// </summary>\n            public void Clean()\n            {\n                lock (thumbCache)\n                {\n                    thumbCache.Clear();\n                }\n            }\n            /// <summary>\n            /// Adds the image to the cache queue.\n            /// </summary>\n            public void AddToCache(Guid guid, string filename)\n            {\n                Size thumbSize = mImageListView.ThumbnailSize;\n                EnumUseEmbeddedThumbnails useEmbeddedThumbnails = mImageListView.UseEmbeddedThumbnails;\n\n                bool isCached = false;\n                lock (thumbCache)\n                {\n                    if (thumbCache.ContainsKey(guid))\n                    {\n                        if (thumbCache[guid].Size == thumbSize)\n                            isCached = true;\n                        else\n                            thumbCache.Remove(guid);\n                    }\n                }\n                if (!isCached)\n                {\n                    lock (toCache)\n                    {\n                        if (!toCache.ContainsKey(guid))\n                        {\n                            toCache.Add(guid, new CacheItem(filename, thumbSize, null, EnumCacheState.InQueue, useEmbeddedThumbnails));\n                            Monitor.Pulse(toCache);\n                        }\n                    }\n                }\n            }\n            /// <summary>\n            /// Removes the given item from the cache.\n            /// </summary>\n            public bool RemoveFromCache(Guid guid)\n            {\n                bool ret = false;\n                lock (thumbCache)\n                {\n                    if (thumbCache.ContainsKey(guid))\n                    {\n                        ret = thumbCache.Remove(guid);\n                    }\n                }\n                lock (toCache)\n                {\n                    if (toCache.ContainsKey(guid))\n                    {\n                        toCache.Remove(guid);\n                    }\n                }\n                return ret;\n            }\n            /// <summary>\n            /// Gets the image from the thumbnail cache. If the image is not cached,\n            /// null will be returned.\n            /// </summary>\n            public Image GetImage(Guid guid)\n            {\n                // Default to null.\n                Image img = null;\n\n                lock (thumbCache)\n                {\n                    if (thumbCache.ContainsKey(guid))\n                    {\n                        img = thumbCache[guid].Image;\n                    }\n                }\n                return img;\n            }\n            #endregion\n\n            #region Static Methods\n            /// <summary>\n            /// Used by the worker thread to generate image thumbnails.\n            /// Once a thumbnail image is generated, the item will be redrawn\n            /// to replace the placeholder image.\n            /// </summary>\n            private static void DoWork(object data)\n            {\n                ImageListViewCacheManager owner = (ImageListViewCacheManager)data;\n\n                while (true)\n                {\n                    EnumUseEmbeddedThumbnails useEmbedded = EnumUseEmbeddedThumbnails.Auto;\n                    Size thumbsize = new Size();\n                    Guid guid = new Guid();\n                    string filename = \"\";\n                    lock (owner.toCache)\n                    {\n                        // Wait until we have items waiting to be cached\n                        if (owner.toCache.Count == 0)\n                            Monitor.Wait(owner.toCache);\n\n                        if (owner.toCache.Count != 0)\n                        {\n                            // Get an item from the queue\n                            foreach (KeyValuePair<Guid, CacheItem> pair in owner.toCache)\n                            {\n                                guid = pair.Key;\n                                CacheItem request = pair.Value;\n                                filename = request.FileName;\n                                thumbsize = request.Size;\n                                useEmbedded = request.UseEmbeddedThumbnails;\n                                break;\n                            }\n                            owner.toCache.Remove(guid);\n                        }\n                    }\n                    // Is it already cached?\n                    if (filename != \"\")\n                    {\n                        lock (owner.thumbCache)\n                        {\n                            if (owner.thumbCache.ContainsKey(guid))\n                            {\n                                if (owner.thumbCache[guid].Size == thumbsize)\n                                    filename = \"\";\n                                else\n                                    owner.thumbCache.Remove(guid);\n                            }\n                        }\n                    }\n                    // Is it outside visible area?\n                    if (filename != \"\")\n                    {\n                        bool isvisible = (bool)owner.ImageListView.Invoke(new CheckItemVisibleInternal(owner.mImageListView.IsItemVisible), guid);\n                        if (!isvisible)\n                            filename = \"\";\n                    }\n\n                    // Proceed if we have a filename\n                    if (filename != \"\")\n                    {\n                        bool thumbnailCreated = false;\n                        Image thumb = ThumbnailFromFile(filename, thumbsize, useEmbedded);\n                        lock (owner.thumbCache)\n                        {\n                            if (!owner.thumbCache.ContainsKey(guid) || owner.thumbCache[guid].Size != thumbsize)\n                            {\n                                owner.thumbCache.Remove(guid);\n                                if (thumb == null)\n                                    owner.thumbCache.Add(guid, new CacheItem(filename, thumbsize, null, EnumCacheState.Error));\n                                else\n                                    owner.thumbCache.Add(guid, new CacheItem(filename, thumbsize, thumb, EnumCacheState.Cached));\n                                thumbnailCreated = true;\n\n                                // Do some cleanup if we exceeded the cache limit\n                                int itemsremoved = 0;\n                                int cachesize = owner.mCacheSize;\n                                if (cachesize != 0 && owner.thumbCache.Count > cachesize)\n                                {\n                                    for (int i = owner.thumbCache.Count - 1; i >= 0; i--)\n                                    {\n                                        Guid iguid = Guid.Empty;\n                                        foreach (KeyValuePair<Guid, CacheItem> item in owner.thumbCache)\n                                        {\n                                            iguid = item.Key;\n                                            break;\n                                        }\n                                        bool isvisible = (bool)owner.ImageListView.Invoke(new CheckItemVisibleInternal(owner.mImageListView.IsItemVisible), guid);\n                                        if (!isvisible)\n                                        {\n                                            owner.thumbCache.Remove(iguid);\n                                            itemsremoved++;\n                                            if (itemsremoved >= cachesize / 2)\n                                                break;\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                        if (thumbnailCreated)\n                        {\n                            owner.mImageListView.Invoke(new ThumbnailCachedEventHandlerInternal(owner.mImageListView.OnThumbnailCachedInternal), guid);\n                            owner.mImageListView.Invoke(new RefreshEventHandlerInternal(owner.mImageListView.mRenderer.Refresh));\n                        }\n                    }\n                }\n            }\n            /// <summary>\n            /// Creates a thumbnail image of given size for the specified image file.\n            /// </summary>\n            private static Image ThumbnailFromFile(string filename, Size thumbSize, EnumUseEmbeddedThumbnails useEmbedded)\n            {\n                Bitmap thumb = null;\n                try\n                {\n                    if (thumbSize.Width <= 0 || thumbSize.Height <= 0)\n                        throw new ArgumentException();\n\n                    Image sourceImage = null;\n                    if (useEmbedded != EnumUseEmbeddedThumbnails.Never)\n                    {\n                        using (FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read))\n                        {\n                            sourceImage = Image.FromStream(stream, false, false);\n                            bool hasTag = false;\n                            // Try to get the embedded thumbnail.\n                            foreach (int index in sourceImage.PropertyIdList)\n                            {\n                                if (index == PropertyTagThumbnailData)\n                                {\n                                    hasTag = true;\n                                    byte[] rawImage = sourceImage.GetPropertyItem(PropertyTagThumbnailData).Value;\n                                    sourceImage.Dispose();\n                                    using (MemoryStream memStream = new MemoryStream(rawImage))\n                                    {\n                                        sourceImage = Image.FromStream(memStream);\n                                    }\n                                    if (useEmbedded == EnumUseEmbeddedThumbnails.Auto)\n                                    {\n                                        // Check that the embedded thumbnail is large enough.\n                                        float aspectRatio = (float)sourceImage.Width / (float)sourceImage.Height;\n                                        Size actualThumbSize = Size.Empty;\n                                        if (aspectRatio > 1.0f)\n                                            actualThumbSize = new Size(thumbSize.Width, (int)(((float)thumbSize.Height) / aspectRatio));\n                                        else\n                                            actualThumbSize = new Size((int)(((float)thumbSize.Width) * aspectRatio), thumbSize.Height);\n\n                                        if (System.Math.Max((float)actualThumbSize.Width / (float)sourceImage.Width, (float)actualThumbSize.Height / (float)sourceImage.Height) > EmbeddedThumbnailSizeTolerance)\n                                        {\n                                            sourceImage.Dispose();\n                                            sourceImage = null;\n                                        }\n                                    }\n                                }\n                            }\n                            if (!hasTag)\n                            {\n                                sourceImage.Dispose();\n                                sourceImage = null;\n                            }\n                        }\n                    }\n\n                    // If the source image does not have an embedded thumbnail or if the\n                    // embedded thumbnail is too small, read and scale the entire image.\n                    if (sourceImage == null)\n                        sourceImage = Image.FromFile(filename);\n\n                    float f = System.Math.Max((float)sourceImage.Width / (float)thumbSize.Width, (float)sourceImage.Height / (float)thumbSize.Height);\n                    if (f < 1.0f) f = 1.0f; // Do not upsize small images\n                    int x = (int)System.Math.Round((float)sourceImage.Width / f);\n                    int y = (int)System.Math.Round((float)sourceImage.Height / f);\n                    thumb = new Bitmap(x, y);\n                    using (Graphics g = Graphics.FromImage(thumb))\n                    {\n                        g.FillRectangle(Brushes.White, 0, 0, x, y);\n                        g.DrawImage(sourceImage, 0, 0, x, y);\n                    }\n                    sourceImage.Dispose();\n                }\n                catch\n                {\n                    thumb = null;\n                }\n                return thumb;\n            }\n            #endregion\n        }\n        /// <summary>\n        /// Represents the layout of the image list view drawing area.\n        /// </summary>\n        internal class ImageListViewLayoutManager\n        {\n            #region Member Variables\n            private Rectangle mClientArea;\n            private SEImageListView mImageListView;\n            private Rectangle mItemAreaBounds;\n            private Rectangle mColumnHeaderBounds;\n            private Size mItemSize;\n            private Size mItemSizeWithMargin;\n            private int mCols;\n            private int mRows;\n            private int mFirstPartiallyVisible;\n            private int mLastPartiallyVisible;\n            private int mFirstVisible;\n            private int mLastVisible;\n\n            private BorderStyle cachedBorderStyle;\n            private EnumView cachedView;\n            private Point cachedViewOffset;\n            private Size cachedSize;\n            private int cachedItemCount;\n            private Size cachedItemSize;\n            private int cachedHeaderHeight;\n            private Dictionary<Guid, bool> cachedVisibleItems;\n            #endregion\n\n            #region Properties\n            /// <summary>\n            /// Gets the bounds of the entire client area.\n            /// </summary>\n            public Rectangle ClientArea { get { return mClientArea; } }\n            /// <summary>\n            /// Gets the owner image list view.\n            /// </summary>\n            public SEImageListView ImageListView { get { return mImageListView; } }\n            /// <summary>\n            /// Gets the extends of the item area.\n            /// </summary>\n            public Rectangle ItemAreaBounds { get { return mItemAreaBounds; } }\n            /// <summary>\n            /// Gets the extents of the column header area.\n            /// </summary>\n            public Rectangle ColumnHeaderBounds { get { return mColumnHeaderBounds; } }\n            /// <summary>\n            /// Gets the items size.\n            /// </summary>\n            public Size ItemSize { get { return mItemSize; } }\n            /// <summary>\n            /// Gets the items size including the margin around the item.\n            /// </summary>\n            public Size ItemSizeWithMargin { get { return mItemSizeWithMargin; } }\n            /// <summary>\n            /// Gets the maximum number of columns that can be displayed.\n            /// </summary>\n            public int Cols { get { return mCols; } }\n            /// <summary>\n            /// Gets the maximum number of rows that can be displayed.\n            /// </summary>\n            public int Rows { get { return mRows; } }\n            /// <summary>\n            /// Gets the index of the first partially visible item.\n            /// </summary>\n            public int FirstPartiallyVisible { get { return mFirstPartiallyVisible; } }\n            /// <summary>\n            /// Gets the index of the last partially visible item.\n            /// </summary>\n            public int LastPartiallyVisible { get { return mLastPartiallyVisible; } }\n            /// <summary>\n            /// Gets the index of the first fully visible item.\n            /// </summary>\n            public int FirstVisible { get { return mFirstVisible; } }\n            /// <summary>\n            /// Gets the index of the last fully visible item.\n            /// </summary>\n            public int LastVisible { get { return mLastVisible; } }\n            /// <summary>\n            /// Determines whether an update is required.\n            /// </summary>\n            public bool UpdateRequired\n            {\n                get\n                {\n                    if (mImageListView.BorderStyle != cachedBorderStyle)\n                        return true;\n                    else if (mImageListView.View != cachedView)\n                        return true;\n                    else if (mImageListView.ViewOffset != cachedViewOffset)\n                        return true;\n                    else if (mImageListView.Size != cachedSize)\n                        return true;\n                    else if (mImageListView.Items.Count != cachedItemCount)\n                        return true;\n                    else if (mImageListView.mRenderer.MeasureItem(mImageListView.View) != cachedItemSize)\n                        return true;\n                    else if (mImageListView.mRenderer.MeasureColumnHeaderHeight() != cachedHeaderHeight)\n                        return true;\n                    else\n                        return false;\n                }\n            }\n            /// <summary>\n            /// Returns the item margin adjusted to the current view mode.\n            /// </summary>\n            public Size AdjustedItemMargin\n            {\n                get\n                {\n                    if (mImageListView.View == EnumView.Details)\n                        return new Size(2, 0);\n                    else\n                        return mImageListView.ItemMargin;\n                }\n            }\n            #endregion\n\n            #region Constructor\n            public ImageListViewLayoutManager(SEImageListView owner)\n            {\n                mImageListView = owner;\n                cachedVisibleItems = new Dictionary<Guid, bool>();\n                Update();\n            }\n            #endregion\n\n            #region Instance Methods\n            /// <summary>\n            /// Returns the bounds of the item with the specified index.\n            /// </summary>\n            public Rectangle GetItemBounds(int itemIndex)\n            {\n                Point location = new Point();\n                Size itemMargin = AdjustedItemMargin;\n                if (mImageListView.BorderStyle != BorderStyle.None)\n                    location.Offset(1, 1);\n                location.X += itemMargin.Width / 2 + (itemIndex % mCols) * (mItemSize.Width + itemMargin.Width) - mImageListView.ViewOffset.X;\n                location.Y += itemMargin.Height / 2 + (itemIndex / mCols) * (mItemSize.Height + itemMargin.Height) - mImageListView.ViewOffset.Y;\n                if (mImageListView.View == EnumView.Details)\n                    location.Y += mImageListView.mRenderer.MeasureColumnHeaderHeight();\n                return new Rectangle(location, mItemSize);\n            }\n            /// <summary>\n            /// Returns the bounds of the item with the specified index, \n            /// including the margin around the item.\n            /// </summary>\n            public Rectangle GetItemBoundsWithMargin(int itemIndex)\n            {\n                Rectangle rec = GetItemBounds(itemIndex);\n                if (mImageListView.View == EnumView.Details)\n                    rec.Inflate(2, 0);\n                else\n                    rec.Inflate(mImageListView.ItemMargin.Width / 2, mImageListView.ItemMargin.Height / 2);\n                return rec;\n            }\n            /// <summary>\n            /// Recalculates the control layout.\n            /// </summary>\n            public void Update()\n            {\n                //cxs\n                //这里有个问题，即使窗体不可见，还是会进到这个方法\n                Update(false);\n            }\n            /// <summary>\n            /// Recalculates the control layout.\n            /// </summary>\n            public void Update(bool forceUpdate)\n            {\n                if (mImageListView.ClientRectangle.Width == 0 || mImageListView.ClientRectangle.Height == 0) return;\n                if (!forceUpdate && !UpdateRequired) return;\n                // Cache current properties to determine if we will need an update later\n                cachedBorderStyle = mImageListView.BorderStyle;\n                cachedView = mImageListView.View;\n                cachedViewOffset = mImageListView.ViewOffset;\n                cachedSize = mImageListView.Size;\n                cachedItemCount = mImageListView.Items.Count;\n                cachedItemSize = mImageListView.mRenderer.MeasureItem(mImageListView.View);\n                cachedHeaderHeight = mImageListView.mRenderer.MeasureColumnHeaderHeight();\n                cachedVisibleItems.Clear();\n\n                // Calculate drawing area\n                mClientArea = mImageListView.ClientRectangle;\n                mItemAreaBounds = mImageListView.ClientRectangle;\n\n                // Allocate space for border\n                if (mImageListView.BorderStyle != BorderStyle.None)\n                {\n                    mClientArea.Inflate(-1, -1);\n                    mItemAreaBounds.Inflate(-1, -1);\n                }\n\n                // Allocate space for scrollbars\n                if (mImageListView.hScrollBar.Visible)\n                {\n                    mClientArea.Height -= mImageListView.hScrollBar.Height;\n                    mItemAreaBounds.Height -= mImageListView.hScrollBar.Height;\n                }\n                if (mImageListView.vScrollBar.Visible)\n                {\n                    mClientArea.Width -= mImageListView.vScrollBar.Width;\n                    mItemAreaBounds.Width -= mImageListView.vScrollBar.Width;\n                }\n\n                // Allocate space for column headers\n                if (mImageListView.View == EnumView.Details)\n                {\n                    int headerHeight = mImageListView.mRenderer.MeasureColumnHeaderHeight();\n\n                    // Location of the column headers\n                    mColumnHeaderBounds.X = mClientArea.Left - mImageListView.ViewOffset.X;\n                    mColumnHeaderBounds.Y = mClientArea.Top;\n                    mColumnHeaderBounds.Height = headerHeight;\n                    mColumnHeaderBounds.Width = mClientArea.Width + mImageListView.ViewOffset.X;\n\n                    mItemAreaBounds.Y += headerHeight;\n                    mItemAreaBounds.Height -= headerHeight;\n                }\n                else\n                {\n                    mColumnHeaderBounds = Rectangle.Empty;\n                }\n                if (mItemAreaBounds.Height < 1 || mItemAreaBounds.Height < 1) return;\n\n                // Item size\n                mItemSize = mImageListView.mRenderer.MeasureItem(mImageListView.View);\n                mItemSizeWithMargin = mItemSize + AdjustedItemMargin;\n\n                // Maximum number of rows and columns that can be fully displayed\n                mCols = (int)System.Math.Floor((float)mItemAreaBounds.Width / (float)mItemSizeWithMargin.Width);\n                mRows = (int)System.Math.Floor((float)mItemAreaBounds.Height / (float)mItemSizeWithMargin.Height);\n                if (mImageListView.View == EnumView.Details) mCols = 1;\n                if (mCols < 1) mCols = 1;\n                if (mRows < 1) mRows = 1;\n\n                // Check if we need the horizontal scroll bar\n                bool hScrollRequired = (mImageListView.Items.Count > 0) && (mItemAreaBounds.Width < mItemSizeWithMargin.Width);\n                if (hScrollRequired != mImageListView.hScrollBar.Visible)\n                {\n                    mImageListView.hScrollBar.Visible = hScrollRequired;\n                    Update(true);\n                    return;\n                }\n\n                // Check if we need the vertical scroll bar\n                //cxs\n                //这里有一个BUG，如果窗体不可见，并需要显示垂直滚动条，此处会形成死循环\n                //因为mImageListView.vScrollBar.Visible一定会为false\n                //这个问题是由Resize一只引发的，解决办法是在Resize中判断窗体是否可见\n                bool vScrollRequired = (mImageListView.Items.Count > 0) && (mCols * mRows < mImageListView.Items.Count);\n                if (vScrollRequired != mImageListView.vScrollBar.Visible)\n                {\n                    mImageListView.vScrollBar.Visible = vScrollRequired;\n                    Update(true);\n                    return;\n                }\n\n                // Horizontal scroll range\n                mImageListView.hScrollBar.SmallChange = 1;\n                mImageListView.hScrollBar.LargeChange = mItemAreaBounds.Width;\n                mImageListView.hScrollBar.Minimum = 0;\n                mImageListView.hScrollBar.Maximum = mItemSizeWithMargin.Width;\n                if (mImageListView.ViewOffset.X > mImageListView.hScrollBar.Maximum - mImageListView.hScrollBar.LargeChange + 1)\n                {\n                    mImageListView.hScrollBar.Value = mImageListView.hScrollBar.Maximum - mImageListView.hScrollBar.LargeChange + 1;\n                    mImageListView.ViewOffset = new Point(mImageListView.hScrollBar.Value, mImageListView.ViewOffset.Y);\n                }\n\n                // Vertical scroll range\n                mImageListView.vScrollBar.SmallChange = mItemSizeWithMargin.Height;\n                mImageListView.vScrollBar.LargeChange = mItemAreaBounds.Height;\n                mImageListView.vScrollBar.Minimum = 0;\n                mImageListView.vScrollBar.Maximum = Math.Max(0, (int)System.Math.Ceiling((float)mImageListView.Items.Count / (float)mCols) * mItemSizeWithMargin.Height - 1);\n                if (mImageListView.ViewOffset.Y > mImageListView.vScrollBar.Maximum - mImageListView.vScrollBar.LargeChange + 1)\n                {\n                    mImageListView.vScrollBar.Value = mImageListView.vScrollBar.Maximum - mImageListView.vScrollBar.LargeChange + 1;\n                    mImageListView.ViewOffset = new Point(mImageListView.ViewOffset.X, mImageListView.vScrollBar.Value);\n                }\n\n                // Zero out the scrollbars if we don't have any items\n                if (mImageListView.Items.Count == 0)\n                {\n                    mImageListView.hScrollBar.Minimum = 0;\n                    mImageListView.hScrollBar.Maximum = 0;\n                    mImageListView.hScrollBar.Value = 0;\n                    mImageListView.vScrollBar.Minimum = 0;\n                    mImageListView.vScrollBar.Maximum = 0;\n                    mImageListView.vScrollBar.Value = 0;\n                    mImageListView.ViewOffset = new Point(0, 0);\n                }\n\n                // Horizontal scrollbar position\n                mImageListView.hScrollBar.Left = (mImageListView.BorderStyle == BorderStyle.None ? 0 : 1);\n                mImageListView.hScrollBar.Top = mImageListView.ClientRectangle.Bottom - (mImageListView.BorderStyle == BorderStyle.None ? 0 : 1) - mImageListView.hScrollBar.Height;\n                mImageListView.hScrollBar.Width = mImageListView.ClientRectangle.Width - (mImageListView.BorderStyle == BorderStyle.None ? 0 : 2) - (mImageListView.vScrollBar.Visible ? mImageListView.vScrollBar.Width : 0);\n                // Vertical scrollbar position\n                mImageListView.vScrollBar.Left = mImageListView.ClientRectangle.Right - (mImageListView.BorderStyle == BorderStyle.None ? 0 : 1) - mImageListView.vScrollBar.Width;\n                mImageListView.vScrollBar.Top = (mImageListView.BorderStyle == BorderStyle.None ? 0 : 1);\n                mImageListView.vScrollBar.Height = mImageListView.ClientRectangle.Height - (mImageListView.BorderStyle == BorderStyle.None ? 0 : 2) - (mImageListView.hScrollBar.Visible ? mImageListView.hScrollBar.Height : 0);\n\n                // Find the first and last partially visible items\n                mFirstPartiallyVisible = (int)System.Math.Floor((float)mImageListView.ViewOffset.Y / (float)mItemSizeWithMargin.Height) * mCols;\n                mLastPartiallyVisible = System.Math.Min((int)System.Math.Ceiling((float)(mImageListView.ViewOffset.Y + mItemAreaBounds.Height) / (float)mItemSizeWithMargin.Height) * mCols - 1, mImageListView.Items.Count - 1);\n                if (mFirstPartiallyVisible < 0) mFirstPartiallyVisible = 0;\n                if (mFirstPartiallyVisible > mImageListView.Items.Count - 1) mFirstPartiallyVisible = mImageListView.Items.Count - 1;\n                if (mLastPartiallyVisible < 0) mLastPartiallyVisible = 0;\n                if (mLastPartiallyVisible > mImageListView.Items.Count - 1) mLastPartiallyVisible = mImageListView.Items.Count - 1;\n\n                // Find the first and last visible items\n                mFirstVisible = (int)System.Math.Ceiling((float)mImageListView.ViewOffset.Y / (float)mItemSizeWithMargin.Height) * mCols;\n                mLastVisible = System.Math.Min((int)System.Math.Floor((float)(mImageListView.ViewOffset.Y + mItemAreaBounds.Height) / (float)mItemSizeWithMargin.Height) * mCols - 1, mImageListView.Items.Count - 1);\n                if (mFirstVisible < 0) mFirstVisible = 0;\n                if (mFirstVisible > mImageListView.Items.Count - 1) mFirstVisible = mImageListView.Items.Count - 1;\n                if (mLastVisible < 0) mLastVisible = 0;\n                if (mLastVisible > mImageListView.Items.Count - 1) mLastVisible = mImageListView.Items.Count - 1;\n\n                // Cache visible items\n                if (mFirstPartiallyVisible >= 0 &&\n                    mLastPartiallyVisible >= 0 &&\n                    mFirstPartiallyVisible <= mImageListView.Items.Count - 1 &&\n                    mLastPartiallyVisible <= mImageListView.Items.Count - 1)\n                {\n                    for (int i = mFirstPartiallyVisible; i <= mLastPartiallyVisible; i++)\n                        cachedVisibleItems.Add(mImageListView.Items[i].Guid, false);\n                }\n            }\n            /// <summary>\n            /// Determines whether the item with the given guid is\n            /// (partially) visible.\n            /// </summary>\n            /// <param name=\"guid\">The guid of the item to check.</param>\n            public bool IsItemVisible(Guid guid)\n            {\n                return cachedVisibleItems.ContainsKey(guid);\n            }\n            #endregion\n        }\n        /// <summary>\n        /// Represents the designer of the image list view.\n        /// </summary>\n        internal class ImageListViewDesigner : ControlDesigner\n        {\n            #region Member Variables\n            DesignerActionListCollection actionLists;\n            #endregion\n\n            #region ControlDesigner Overrides\n            /// <summary>\n            /// Gets the design-time action lists supported by the component associated with the designer.\n            /// </summary>\n            public override DesignerActionListCollection ActionLists\n            {\n                get\n                {\n                    if (null == actionLists)\n                    {\n                        actionLists = base.ActionLists;\n                        actionLists.Add(new ImageListViewActionLists(this.Component));\n                    }\n                    return actionLists;\n                }\n            }\n            #endregion\n        }\n        /// <summary>\n        /// Defines smart tag entries for the image list view.\n        /// </summary>\n        internal class ImageListViewActionLists : DesignerActionList, IServiceProvider, IWindowsFormsEditorService, ITypeDescriptorContext\n        {\n            #region Member Variables\n            private SEImageListView imageListView;\n            private DesignerActionUIService designerService;\n\n            private PropertyDescriptor property;\n            #endregion\n\n            #region Constructor\n            public ImageListViewActionLists(IComponent component)\n                : base(component)\n            {\n                imageListView = (SEImageListView)component;\n                designerService = (DesignerActionUIService)GetService(typeof(DesignerActionUIService));\n            }\n            #endregion\n\n            #region Helper Methods\n            /// <summary>\n            /// Sets the specified ImageListView property.\n            /// </summary>\n            /// <param name=\"propName\">Name of the member property.</param>\n            /// <param name=\"value\">New value of the property.</param>\n            private void SetProperty(String propName, object value)\n            {\n                PropertyDescriptor prop;\n                prop = TypeDescriptor.GetProperties(imageListView)[propName];\n                if (prop == null)\n                    throw new ArgumentException(\"Unknown property.\", propName);\n                else\n                    prop.SetValue(imageListView, value);\n            }\n            #endregion\n\n            #region Properties\n            /// <summary>\n            /// Gets or sets the sort column of the designed ImageListView.\n            /// </summary>\n            public EnumColumnType SortColumn\n            {\n                get { return imageListView.SortColumn; }\n                set { SetProperty(\"SortColumn\", value); }\n            }\n            /// <summary>\n            /// Gets or sets the sort oerder of the designed ImageListView.\n            /// </summary>\n            public EnumSortOrder SortOrder\n            {\n                get { return imageListView.SortOrder; }\n                set { SetProperty(\"SortOrder\", value); }\n            }\n            /// <summary>\n            /// Gets or sets the view mode of the designed ImageListView.\n            /// </summary>\n            public EnumView View\n            {\n                get { return imageListView.View; }\n                set { SetProperty(\"View\", value); }\n            }\n            #endregion\n\n            #region Instance Methods\n            /// <summary>\n            /// Invokes the editor for the columns of the designed ImageListView.\n            /// </summary>\n            public void EditColumns()\n            {\n                property = TypeDescriptor.GetProperties(imageListView)[\"Columns\"];\n                UITypeEditor editor = (UITypeEditor)property.GetEditor(typeof(UITypeEditor));\n                object value = property.GetValue(imageListView);\n                value = editor.EditValue(this, this, value);\n                imageListView.SetColumnsInternal((ImageListViewColumnHeaderCollection)value);\n                designerService.Refresh(Component);\n            }\n            #endregion\n\n            #region DesignerActionList Overrides\n            /// <summary>\n            /// Returns the collection of <see cref=\"T:System.ComponentModel.Design.DesignerActionItem\"/> objects contained in the list.\n            /// </summary>\n            public override DesignerActionItemCollection GetSortedActionItems()\n            {\n                DesignerActionItemCollection items = new DesignerActionItemCollection();\n\n                items.Add(new DesignerActionMethodItem(this, \"EditColumns\", \"Edit Columns\", true));\n\n                items.Add(new DesignerActionPropertyItem(\"View\", \"View\"));\n                items.Add(new DesignerActionPropertyItem(\"SortColumn\", \"SortColumn\"));\n                items.Add(new DesignerActionPropertyItem(\"SortOrder\", \"SortOrder\"));\n\n                return items;\n            }\n            #endregion\n\n            #region IServiceProvider Members\n            /// <summary>\n            /// Returns an object that represents a service provided by the component associated with the <see cref=\"T:System.ComponentModel.Design.DesignerActionList\"/>.\n            /// </summary>\n            object IServiceProvider.GetService(Type serviceType)\n            {\n                if (serviceType.Equals(typeof(IWindowsFormsEditorService)))\n                {\n                    return this;\n                }\n                return GetService(serviceType);\n            }\n            #endregion\n\n            #region IWindowsFormsEditorService Members\n            /// <summary>\n            /// Closes any previously opened drop down control area.\n            /// </summary>\n            void IWindowsFormsEditorService.CloseDropDown()\n            {\n                throw new NotSupportedException(\"Only modal dialogs are supported.\");\n            }\n            /// <summary>\n            /// Displays the specified control in a drop down area below a value field of the property grid that provides this service.\n            /// </summary>\n            void IWindowsFormsEditorService.DropDownControl(Control control)\n            {\n                throw new NotSupportedException(\"Only modal dialogs are supported.\");\n            }\n            /// <summary>\n            /// Shows the specified <see cref=\"T:System.Windows.Forms.Form\"/>.\n            /// </summary>\n            DialogResult IWindowsFormsEditorService.ShowDialog(Form dialog)\n            {\n                return (dialog.ShowDialog());\n            }\n            #endregion\n\n            #region ITypeDescriptorContext Members\n            /// <summary>\n            /// Gets the container representing this <see cref=\"T:System.ComponentModel.TypeDescriptor\"/> request.\n            /// </summary>\n            IContainer ITypeDescriptorContext.Container\n            {\n                get { return null; }\n            }\n            /// <summary>\n            /// Gets the object that is connected with this type descriptor request.\n            /// </summary>\n            object ITypeDescriptorContext.Instance\n            {\n                get { return imageListView; }\n            }\n            /// <summary>\n            /// Raises the <see cref=\"E:System.ComponentModel.Design.IComponentChangeService.ComponentChanged\"/> event.\n            /// </summary>\n            void ITypeDescriptorContext.OnComponentChanged()\n            {\n                ;\n            }\n            /// <summary>\n            /// Raises the <see cref=\"E:System.ComponentModel.Design.IComponentChangeService.ComponentChanging\"/> event.\n            /// </summary>\n            bool ITypeDescriptorContext.OnComponentChanging()\n            {\n                return true;\n            }\n            /// <summary>\n            /// Gets the <see cref=\"T:System.ComponentModel.PropertyDescriptor\"/> that is associated with the given context item.\n            /// </summary>\n            PropertyDescriptor ITypeDescriptorContext.PropertyDescriptor\n            {\n                get { return property; }\n            }\n            #endregion\n        }\n        /// <summary>\n        /// Provides a type converter for the column header collection.\n        /// </summary>\n        internal class ColumnHeaderCollectionTypeConverter : TypeConverter\n        {\n            #region TypeConverter Overrides\n            /// <summary>\n            /// Returns whether this converter can convert the object to the specified type, using the specified context.\n            /// </summary>\n            public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)\n            {\n                if (destinationType == typeof(string))\n                    return true;\n\n                return base.CanConvertTo(context, destinationType);\n            }\n            /// <summary>\n            /// Converts the given value object to the specified type, using the specified context and culture information.\n            /// </summary>\n            public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)\n            {\n                if (value is ImageListViewColumnHeaderCollection && (destinationType == typeof(string)))\n                    return \"(Collection)\";\n\n                return base.ConvertTo(context, culture, value, destinationType);\n            }\n            #endregion\n        }\n        /// <summary>\n        /// Provides an editor for the column header collection.\n        /// </summary>\n        internal class ColumnHeaderCollectionEditor : CollectionEditor\n        {\n            #region Constructor\n            public ColumnHeaderCollectionEditor()\n                : base(typeof(ImageListViewColumnHeaderCollection))\n            {\n            }\n            #endregion\n\n            #region CollectionEditor Overrides\n            /// <summary>\n            /// Indicates whether original members of the collection can be removed.\n            /// </summary>\n            protected override bool CanRemoveInstance(object value)\n            {\n                // Disable the Remove button\n                return false;\n            }\n            /// <summary>\n            /// Gets the data types that this collection editor can contain.\n            /// </summary>\n            protected override Type[] CreateNewItemTypes()\n            {\n                // Disable the Add button\n                return new Type[0];\n            }\n            /// <summary>\n            /// Retrieves the display text for the given list item.\n            /// </summary>\n            protected override string GetDisplayText(object value)\n            {\n                return ((ImageListViewColumnHeader)value).Type.ToString();\n            }\n            /// <summary>\n            /// Indicates whether multiple collection items can be selected at once.\n            /// </summary>\n            protected override bool CanSelectMultipleInstances()\n            {\n                return false;\n            }\n            /// <summary>\n            /// Gets an array of objects containing the specified collection.\n            /// </summary>\n            protected override object[] GetItems(object editValue)\n            {\n                ImageListViewColumnHeaderCollection columns = (ImageListViewColumnHeaderCollection)editValue;\n                object[] list = new object[columns.Count];\n                for (int i = 0; i < columns.Count; i++)\n                    list[i] = columns[i];\n                return list;\n            }\n            /// <summary>\n            /// Creates a new form to display and edit the current collection.\n            /// </summary>\n            protected override CollectionEditor.CollectionForm CreateCollectionForm()\n            {\n                return base.CreateCollectionForm();\n            }\n            #endregion\n        }\n        /// <summary>\n        /// Adds serialization code for the column headers as a collection of CodeDom statements.\n        /// </summary>\n        internal class SEImageListViewSerializer : CodeDomSerializer\n        {\n            #region CodeDomSerializer Overrides\n            /// <summary>\n            /// Deserializes the specified serialized CodeDOM object into an object.\n            /// </summary>\n            public override object Deserialize(IDesignerSerializationManager manager, object codeObject)\n            {\n                CodeDomSerializer baseSerializer = (CodeDomSerializer)manager.GetSerializer(typeof(SEImageListView).BaseType, typeof(CodeDomSerializer));\n                return baseSerializer.Deserialize(manager, codeObject);\n            }\n            /// <summary>\n            /// Serializes the specified object into a CodeDOM object.\n            /// </summary>\n            public override object Serialize(IDesignerSerializationManager manager, object value)\n            {\n                CodeDomSerializer baseSerializer = (CodeDomSerializer)manager.GetSerializer(typeof(SEImageListView).BaseType, typeof(CodeDomSerializer));\n                object codeObject = baseSerializer.Serialize(manager, value);\n\n                if (codeObject is CodeStatementCollection)\n                {\n                    CodeStatementCollection statements = (CodeStatementCollection)codeObject;\n                    CodeExpression imageListViewCode = base.SerializeToExpression(manager, value);\n                    if (imageListViewCode != null && value is SEImageListView)\n                    {\n                        int index = 0;\n                        foreach (ImageListViewColumnHeader column in ((SEImageListView)value).Columns)\n                        {\n                            if (!(column.Text == column.DefaultText && column.Width == SEImageListView.DefaultColumnWidth && column.DisplayIndex == index && ((index < 4) == column.Visible)))\n                            {\n                                CodeMethodInvokeExpression columnSetCode = new CodeMethodInvokeExpression(imageListViewCode,\n                                    \"SetColumnHeader\",\n                                    new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(EnumColumnType)), Enum.GetName(typeof(EnumColumnType), column.Type)),\n                                    new CodePrimitiveExpression(column.Text),\n                                    new CodePrimitiveExpression(column.Width),\n                                    new CodePrimitiveExpression(column.DisplayIndex),\n                                    new CodePrimitiveExpression(column.Visible)\n                                    );\n                                if (column.Text == column.DefaultText)\n                                    columnSetCode.Parameters.RemoveAt(1);\n                                statements.Add(columnSetCode);\n                            }\n                            index++;\n                        }\n                    }\n\n                    return codeObject;\n                }\n\n                return base.Serialize(manager, value);\n            }\n            #endregion\n        }\n        /// <summary>\n        /// Represents details of keyboard and mouse navigation events.\n        /// </summary>\n        internal class NavInfo\n        {\n            #region Properties\n            public bool DraggingSeperator { get; set; }\n            public bool Dragging { get; set; }\n            public int DragIndex { get; set; }\n            public bool DragCaretOnRight { get; set; }\n            public bool ShiftDown { get; set; }\n            public bool ControlDown { get; set; }\n            public EnumColumnType SelSeperator { get; set; }\n            public int SelStartKey { get; set; }\n            public int SelEndKey { get; set; }\n            public Point SelStart { get; set; }\n            public Point SelEnd { get; set; }\n            public Dictionary<ImageListViewItem, bool> Highlight { get; private set; }\n            public EnumColumnType HoveredColumn { get; set; }\n            public ImageListViewItem ClickedItem { get; set; }\n            public ImageListViewItem HoveredItem { get; set; }\n            public bool SelfDragging { get; set; }\n            public EnumColumnType HoveredSeparator { get; set; }\n            public bool MouseInColumnArea { get; set; }\n            public bool MouseInItemArea { get; set; }\n            public bool MouseClicked { get; set; }\n            #endregion\n\n            #region Constructor\n            public NavInfo()\n            {\n                ShiftDown = false;\n                ControlDown = false;\n                DragIndex = -1;\n                SelStartKey = -1;\n                SelEndKey = -1;\n                Highlight = new Dictionary<ImageListViewItem, bool>();\n                HoveredColumn = (EnumColumnType)(-1);\n                ClickedItem = null;\n                HoveredItem = null;\n                SelfDragging = false;\n                HoveredSeparator = (EnumColumnType)(-1);\n                MouseInColumnArea = false;\n                MouseInItemArea = false;\n                MouseClicked = false;\n            }\n            #endregion\n        }\n        #endregion\n\n        #region Virtual Functions\n        /// <summary>\n        /// Raises the ColumnWidthChanged event.\n        /// </summary>\n        /// <param name=\"e\">A ColumnEventArgs that contains event data.</param>\n        protected virtual void OnColumnWidthChanged(ColumnEventArgs e)\n        {\n            if (ColumnWidthChanged != null)\n                ColumnWidthChanged(this, e);\n        }\n        /// <summary>\n        /// Raises the ColumnClick event.\n        /// </summary>\n        /// <param name=\"e\">A ColumnClickEventArgs that contains event data.</param>\n        protected virtual void OnColumnClick(ColumnClickEventArgs e)\n        {\n            if (ColumnClick != null)\n                ColumnClick(this, e);\n        }\n        /// <summary>\n        /// Raises the ItemClick event.\n        /// </summary>\n        /// <param name=\"e\">A ItemClickEventArgs that contains event data.</param>\n        protected virtual void OnItemClick(ItemClickEventArgs e)\n        {\n            if (ItemClick != null)\n                ItemClick(this, e);\n        }\n        /// <summary>\n        /// Raises the ItemDoubleClick event.\n        /// </summary>\n        /// <param name=\"e\">A ItemClickEventArgs that contains event data.</param>\n        protected virtual void OnItemDoubleClick(ItemClickEventArgs e)\n        {\n            if (ItemDoubleClick != null)\n                ItemDoubleClick(this, e);\n        }\n        /// <summary>\n        /// Raises the SelectionChanged event.\n        /// </summary>\n        /// <param name=\"e\">A EventArgs that contains event data.</param>\n        protected virtual void OnSelectionChanged(EventArgs e)\n        {\n            if (SelectionChanged != null)\n                SelectionChanged(this, e);\n        }\n        /// <summary>\n        /// Raises the SelectionChanged event.\n        /// </summary>\n        /// <param name=\"e\">A EventArgs that contains event data.</param>\n        internal void OnSelectionChangedInternal()\n        {\n            OnSelectionChanged(new EventArgs());\n        }\n        /// <summary>\n        /// Raises the ThumbnailCached event.\n        /// </summary>\n        /// <param name=\"e\">A ItemEventArgs that contains event data.</param>\n        protected virtual void OnThumbnailCached(ItemEventArgs e)\n        {\n            if (ThumbnailCached != null)\n                ThumbnailCached(this, e);\n        }\n        /// <summary>\n        /// Raises the ThumbnailCached event.\n        /// This method is invoked from the thumbnail thread.\n        /// </summary>\n        /// <param name=\"e\">The guid of the item whose thumbnail is cached.</param>\n        internal void OnThumbnailCachedInternal(Guid guid)\n        {\n            int itemIndex = Items.IndexOf(guid);\n            if (itemIndex != -1)\n                OnThumbnailCached(new ItemEventArgs(Items[itemIndex]));\n        }\n        /// <summary>\n        /// Raises the ThumbnailCaching event.\n        /// </summary>\n        /// <param name=\"e\">A ItemEventArgs that contains event data.</param>\n        protected virtual void OnThumbnailCaching(ItemEventArgs e)\n        {\n            if (ThumbnailCaching != null)\n                ThumbnailCaching(this, e);\n        }\n        #endregion\n\n        #region Exposed Events\n        /// <summary>\n        /// Occurs after the user successfully resized a column header.\n        /// </summary>\n        [Category(\"Action\"), Browsable(true), Description(\"Occurs after the user successfully resized a column header.\")]\n        public event ColumnWidthChangedEventHandler ColumnWidthChanged;\n        /// <summary>\n        /// Occurs when the user clicks a column header.\n        /// </summary>\n        [Category(\"Action\"), Browsable(true), Description(\"Occurs when the user clicks a column header.\")]\n        public event ColumnClickEventHandler ColumnClick;\n        /// <summary>\n        /// Occurs when the user clicks an item.\n        /// </summary>\n        [Category(\"Action\"), Browsable(true), Description(\"Occurs when the user clicks an item.\")]\n        public event ItemClickEventHandler ItemClick;\n        /// <summary>\n        /// Occurs when the user double-clicks an item.\n        /// </summary>\n        [Category(\"Action\"), Browsable(true), Description(\"Occurs when the user double-clicks an item.\")]\n        public event ItemDoubleClickEventHandler ItemDoubleClick;\n        /// <summary>\n        /// Occurs when the selected items collection changes.\n        /// </summary>\n        [Category(\"Behavior\"), Browsable(true), Description(\"Occurs when the selected items collection changes.\")]\n        public event EventHandler SelectionChanged;\n        /// <summary>\n        /// Occurs after an item thumbnail is cached.\n        /// </summary>\n        [Category(\"Behavior\"), Browsable(true), Description(\"Occurs after an item thumbnail is cached.\")]\n        public event ThumbnailCachedEventHandler ThumbnailCached;\n        /// <summary>\n        /// Occurs before an item thumbnail is cached.\n        /// </summary>\n        [Category(\"Behavior\"), Browsable(true), Description(\"Occurs before an item thumbnail is cached.\")]\n        public event ThumbnailCachingEventHandler ThumbnailCaching;\n        #endregion\n\n\n        #region Public Enums\n        /// <summary>\n        /// Represents the embedded thumbnail extraction behavior.\n        /// </summary>\n        public enum EnumUseEmbeddedThumbnails\n        {\n            Auto,\n            Always,\n            Never,\n        }\n        /// <summary>\n        /// Represents the cache state of a thumbnail image.\n        /// </summary>\n        public enum EnumCacheState\n        {\n            Unknown,\n            InQueue,\n            Cached,\n            Error,\n        }\n        /// <summary>\n        /// Represents the view mode of the image list view.\n        /// </summary>\n        public enum EnumView\n        {\n            Details,\n            Thumbnails,\n        }\n        /// <summary>\n        /// Represents the type of information displayed in an image list view column.\n        /// </summary>\n        public enum EnumColumnType\n        {\n            Name,\n            DateAccessed,\n            DateCreated,\n            DateModified,\n            FileType,\n            FileName,\n            FilePath,\n            FileSize,\n            Dimension,\n            Resolution,\n        }\n        /// <summary>\n        /// Represents the sort order of am image list view column.\n        /// </summary>\n        public enum EnumSortOrder\n        {\n            None = 0,\n            Ascending = 1,\n            Descending = -1,\n        }\n        /// <summary>\n        /// Determines the visibility of an item.\n        /// </summary>\n        public enum EnumItemVisibility\n        {\n            NotVisible = 0,\n            Visible = 1,\n            PartiallyVisible = 2,\n        }\n        /// <summary>\n        /// Represents the visual state of an image list view item.\n        /// </summary>\n        [Flags]\n        public enum EnumItemState\n        {\n            None = 0,\n            Selected = 1,\n            Focused = 2,\n            Hovered = 4,\n        }\n        /// <summary>\n        /// Represents the visual state of an image list column.\n        /// </summary>\n        [Flags]\n        public enum EnumColumnState\n        {\n            None = 0,\n            Hovered = 1,\n            SeparatorHovered = 2,\n            SeparatorSelected = 4,\n        }\n        #endregion\n\n        #region Public Classes\n        /// <summary>\n        /// Represents an item in the image list view.\n        /// </summary>\n        public class ImageListViewItem\n        {\n            #region Member Variables\n            internal int mIndex;\n            private Color mBackColor;\n            private Color mForeColor;\n            private Guid mGuid;\n            internal SEImageListView mImageListView;\n            protected internal bool mSelected;\n            private string mText;\n            internal string defaultText;\n            // File info\n            internal DateTime mDateAccessed;\n            internal DateTime mDateCreated;\n            internal DateTime mDateModified;\n            internal string mFileType;\n            private string mFileName;\n            internal string mFilePath;\n            internal long mFileSize;\n            internal Size mDimension;\n            internal SizeF mResolution;\n\n            internal SEImageListView.ImageListViewItemCollection owner;\n            internal bool isDirty;\n            #endregion\n\n            #region Properties\n            /// <summary>\n            /// Gets or sets the background color of the item.\n            /// </summary>\n            [Category(\"Appearance\"), Browsable(true), Description(\"Gets or sets the background color of the item.\"), DefaultValue(typeof(Color), \"Transparent\")]\n            public Color BackColor\n            {\n                get\n                {\n                    return mBackColor;\n                }\n                set\n                {\n                    if (value != mBackColor)\n                    {\n                        mBackColor = value;\n                        if (mImageListView != null)\n                            mImageListView.Refresh();\n                    }\n                }\n            }\n            /// <summary>\n            /// Gets the cache state of the item thumbnail.\n            /// </summary>\n            [Category(\"Behavior\"), Browsable(false), Description(\"Gets the cache state of the item thumbnail.\")]\n            public EnumCacheState ThumbnailCacheState { get { return mImageListView.cacheManager.GetCacheState(Guid); } }\n            /// <summary>\n            /// Gets a value determining if the item is focused.\n            /// </summary>\n            [Category(\"Appearance\"), Browsable(false), Description(\"Gets a value determining if the item is focused.\")]\n            public bool Focused\n            {\n                get\n                {\n                    if (owner == null || owner.FocusedItem == null) return false;\n                    return (this == owner.FocusedItem);\n                }\n                set\n                {\n                    if (owner != null)\n                        owner.FocusedItem = this;\n                }\n            }\n            /// <summary>\n            /// Gets or sets the foreground color of the item.\n            /// </summary>\n            [Category(\"Appearance\"), Browsable(true), Description(\"Gets or sets the foreground color of the item.\"), DefaultValue(typeof(Color), \"WindowText\")]\n            public Color ForeColor\n            {\n                get\n                {\n                    return mForeColor;\n                }\n                set\n                {\n                    if (value != mForeColor)\n                    {\n                        mForeColor = value;\n                        if (mImageListView != null)\n                            mImageListView.Refresh();\n                    }\n                }\n            }\n            /// <summary>\n            /// Gets the unique identifier for this item.\n            /// </summary>\n            [Category(\"Behavior\"), Browsable(false), Description(\"Gets the unique identifier for this item.\")]\n            internal Guid Guid { get { return mGuid; } private set { mGuid = value; } }\n            /// <summary>\n            /// Determines whether the mouse is currently hovered over the item.\n            /// </summary>\n            [Category(\"Appearance\"), Browsable(false), Description(\"Determines whether the mouse is currently hovered over the item.\")]\n            public bool Hovered { get { return (mImageListView.nav.HoveredItem == this); } }\n            /// <summary>\n            /// Gets the ImageListView owning this item.\n            /// </summary>\n            [Category(\"Behavior\"), Browsable(false), Description(\"Gets the ImageListView owning this item.\")]\n            public SEImageListView ImageListView { get { return mImageListView; } private set { mImageListView = value; } }\n            /// <summary>\n            /// Gets the index of the item.\n            /// </summary>\n            [Category(\"Behavior\"), Browsable(false), Description(\"Gets the index of the item.\"), EditorBrowsable(EditorBrowsableState.Advanced)]\n            public int Index { get { return mIndex; } }\n            /// <summary>\n            /// Gets or sets a value determining if the item is selected.\n            /// </summary>\n            [Category(\"Appearance\"), Browsable(true), Description(\"Gets or sets a value determining if the item is selected.\"), DefaultValue(false)]\n            public bool Selected\n            {\n                get\n                {\n                    return mSelected;\n                }\n                set\n                {\n                    if (value != mSelected)\n                    {\n                        mSelected = value;\n                        if (mImageListView != null)\n                            mImageListView.OnSelectionChangedInternal();\n                    }\n                }\n            }\n            /// <summary>\n            /// Gets or sets the user-defined data associated with the item.\n            /// </summary>\n            [Category(\"Data\"), Browsable(true), Description(\"Gets or sets the user-defined data associated with the item.\")]\n            public object Tag { get; set; }\n            /// <summary>\n            /// Gets or sets the text associated with this item. If left blank, item Text \n            /// reverts to the name of the image file.\n            /// </summary>\n            [Category(\"Appearance\"), Browsable(true), Description(\"Gets or sets the text associated with this item. If left blank, item Text reverts to the name of the image file.\")]\n            public string Text\n            {\n                get\n                {\n                    if (string.IsNullOrEmpty(mText))\n                    {\n                        UpdateFileInfo();\n                        return defaultText;\n                    }\n                    else\n                        return mText;\n                }\n                set\n                {\n                    mText = value;\n                    if (mImageListView != null)\n                        mImageListView.Refresh();\n                }\n            }\n            /// <summary>\n            /// Gets the thumbnail image. If the thumbnail image is not cached, it will be \n            /// added to the cache queue and DefaultImage of the owner image list view will\n            /// be returned. If the thumbnail could not be cached ErrorImage of the owner\n            /// image list view will be returned.\n            /// </summary>\n            [Category(\"Appearance\"), Browsable(false), Description(\"Gets the thumbnail image.\")]\n            public Image ThumbnailImage\n            {\n                get\n                {\n                    if (mImageListView == null)\n                        throw new InvalidOperationException(\"Owner control is null.\");\n\n                    EnumCacheState state = ThumbnailCacheState;\n                    if (state == EnumCacheState.Error)\n                        return mImageListView.ErrorImage;\n                    else if (state == EnumCacheState.InQueue)\n                        return mImageListView.DefaultImage;\n                    else if (state == EnumCacheState.Cached)\n                    {\n                        Image img = mImageListView.cacheManager.GetImage(Guid);\n                        if (img != null)\n                            return img;\n                        else\n                        {\n                            mImageListView.cacheManager.AddToCache(Guid, FileName);\n                            return mImageListView.DefaultImage;\n                        }\n                    }\n                    else\n                    {\n                        mImageListView.cacheManager.AddToCache(Guid, FileName);\n                        return mImageListView.DefaultImage;\n                    }\n                }\n            }\n            /// <summary>\n            /// Gets the last access date of the image file represented by this item.\n            /// </summary>\n            [Category(\"Data\"), Browsable(false), Description(\"Gets the last access date of the image file represented by this item.\")]\n            public DateTime DateAccessed { get { UpdateFileInfo(); return mDateAccessed; } }\n            /// <summary>\n            /// Gets the creation date of the image file represented by this item.\n            /// </summary>\n            [Category(\"Data\"), Browsable(false), Description(\"Gets the creation date of the image file represented by this item.\")]\n            public DateTime DateCreated { get { UpdateFileInfo(); return mDateCreated; } }\n            /// <summary>\n            /// Gets the modification date of the image file represented by this item.\n            /// </summary>\n            [Category(\"Data\"), Browsable(false), Description(\"Gets the modification date of the image file represented by this item.\")]\n            public DateTime DateModified { get { UpdateFileInfo(); return mDateModified; } }\n            /// <summary>\n            /// Gets the shell type of the image file represented by this item.\n            /// </summary>\n            [Category(\"Data\"), Browsable(false), Description(\"Gets the shell type of the image file represented by this item.\")]\n            public string FileType { get { UpdateFileInfo(); return mFileType; } }\n            /// <summary>\n            /// Gets or sets the name of the image fie represented by this item.\n            /// </summary>        \n            [Category(\"Data\"), Browsable(false), Description(\"Gets or sets the name of the image fie represented by this item.\")]\n            public string FileName\n            {\n                get\n                {\n                    return mFileName;\n                }\n                set\n                {\n                    if (mFileName != value)\n                    {\n                        mFileName = value;\n                        isDirty = true;\n                        if (mImageListView != null)\n                        {\n                            mImageListView.itemCacheManager.AddToCache(this);\n                            if (mImageListView.cacheManager.RemoveFromCache(Guid))\n                                mImageListView.Refresh();\n                        }\n                    }\n                }\n            }\n            /// <summary>\n            /// Gets the path of the image fie represented by this item.\n            /// </summary>        \n            [Category(\"Data\"), Browsable(false), Description(\"Gets the path of the image fie represented by this item.\")]\n            public string FilePath { get { UpdateFileInfo(); return mFilePath; } }\n            /// <summary>\n            /// Gets file size in bytes.\n            /// </summary>\n            [Category(\"Data\"), Browsable(false), Description(\"Gets file size in bytes.\")]\n            public long FileSize { get { UpdateFileInfo(); return mFileSize; } }\n            /// <summary>\n            /// Gets image dimensions.\n            /// </summary>\n            [Category(\"Data\"), Browsable(false), Description(\"Gets image dimensions.\")]\n            public Size Dimension { get { UpdateFileInfo(); return mDimension; } }\n            /// <summary>\n            /// Gets image resolution in pixels per inch.\n            /// </summary>\n            [Category(\"Data\"), Browsable(false), Description(\"Gets image resolution in pixels per inch.\")]\n            public SizeF Resolution { get { UpdateFileInfo(); return mResolution; } }\n            #endregion\n\n            #region Constructors\n            public ImageListViewItem()\n            {\n                mIndex = -1;\n                owner = null;\n\n                mBackColor = Color.Transparent;\n                mForeColor = SystemColors.WindowText;\n\n                Guid = Guid.NewGuid();\n                ImageListView = null;\n                Selected = false;\n\n                isDirty = true;\n                defaultText = null;\n            }\n            public ImageListViewItem(string filename)\n                : this()\n            {\n                mFileName = filename;\n            }\n            #endregion\n\n            #region Helper Methods\n            /// <summary>\n            /// Updates file info for the image file represented by this item.\n            /// </summary>\n            private void UpdateFileInfo()\n            {\n                if (!isDirty) return;\n                isDirty = false;\n\n                Utility.ShellFileInfo info = new Utility.ShellFileInfo(mFileName);\n                if (info.Error) return;\n\n                mDateAccessed = info.LastAccessTime;\n                mDateCreated = info.CreationTime;\n                mDateModified = info.LastWriteTime;\n                mFileSize = info.Size;\n                mFileType = info.TypeName;\n                mFilePath = Path.GetDirectoryName(FileName);\n                defaultText = Path.GetFileName(FileName);\n\n                using (FileStream stream = new FileStream(mFileName, FileMode.Open, FileAccess.Read))\n                {\n                    try\n                    {\n                        //cxs\n                        //捕获参数错误\n                        using (Image img = Image.FromStream(stream, false, false))\n                        {\n                            mDimension = img.Size;\n                            mResolution = new SizeF(img.HorizontalResolution, img.VerticalResolution);\n                        }\n                    }\n                    catch { }\n                }\n            }\n            /// <summary>\n            /// Return the sub item item text corresponding to the specified column type.\n            /// </summary>\n            /// <param name=\"type\"></param>\n            /// <returns></returns>\n            protected internal string GetSubItemText(EnumColumnType type)\n            {\n                switch (type)\n                {\n                    case EnumColumnType.DateAccessed:\n                        return DateAccessed.ToString(\"g\");\n                    case EnumColumnType.DateCreated:\n                        return DateCreated.ToString(\"g\");\n                    case EnumColumnType.DateModified:\n                        return DateModified.ToString(\"g\");\n                    case EnumColumnType.FileName:\n                        return FileName;\n                    case EnumColumnType.Name:\n                        return Text;\n                    case EnumColumnType.FilePath:\n                        return FilePath;\n                    case EnumColumnType.FileSize:\n                        return Utility.FormatSize(FileSize);\n                    case EnumColumnType.FileType:\n                        return FileType;\n                    case EnumColumnType.Dimension:\n                        return string.Format(\"{0} x {1}\", Dimension.Width, Dimension.Height);\n                    case EnumColumnType.Resolution:\n                        return string.Format(\"{0} x {1}\", Resolution.Width, Resolution.Height);\n                    default:\n                        throw new ArgumentException(\"Unknown column type\", \"type\");\n                }\n            }\n            /// <summary>\n            /// Invoked by the worker thread to update item details.\n            /// </summary>\n            internal void UpdateDetailsInternal(DateTime dateAccessed, DateTime dateCreated, DateTime dateModified,\n                long fileSize, string fileType, string filePath, string name, Size dimension, SizeF resolution)\n            {\n                if (!isDirty) return;\n                isDirty = false;\n                mDateAccessed = dateAccessed;\n                mDateCreated = dateCreated;\n                mDateModified = dateModified;\n                mFileSize = fileSize;\n                mFileType = fileType;\n                mFilePath = filePath;\n                defaultText = name;\n                mDimension = dimension;\n                mResolution = resolution;\n            }\n            #endregion\n        }\n        #endregion\n\n        #region Event Delegates\n        /// <summary>\n        /// Represents the method that will handle the ColumnClick event. \n        /// </summary>\n        /// <param name=\"sender\">The ImageListView object that is the source of the event.</param>\n        /// <param name=\"e\">A ColumnClickEventArgs that contains event data.</param>\n        public delegate void ColumnClickEventHandler(object sender, ColumnClickEventArgs e);\n        /// <summary>\n        /// Represents the method that will handle the ColumnWidthChanged event. \n        /// </summary>\n        /// <param name=\"sender\">The ImageListView object that is the source of the event.</param>\n        /// <param name=\"e\">A ColumnEventArgs that contains event data.</param>\n        public delegate void ColumnWidthChangedEventHandler(object sender, ColumnEventArgs e);\n        /// <summary>\n        /// Represents the method that will handle the ItemClick event. \n        /// </summary>\n        /// <param name=\"sender\">The ImageListView object that is the source of the event.</param>\n        /// <param name=\"e\">A ItemClickEventArgs that contains event data.</param>\n        public delegate void ItemClickEventHandler(object sender, ItemClickEventArgs e);\n        /// <summary>\n        /// Represents the method that will handle the ItemDoubleClick event. \n        /// </summary>\n        /// <param name=\"sender\">The ImageListView object that is the source of the event.</param>\n        /// <param name=\"e\">A ItemClickEventArgs that contains event data.</param>\n        public delegate void ItemDoubleClickEventHandler(object sender, ItemClickEventArgs e);\n        /// <summary>\n        /// Represents the method that will handle the ThumbnailCaching event. \n        /// </summary>\n        /// <param name=\"sender\">The ImageListView object that is the source of the event.</param>\n        /// <param name=\"e\">A ItemEventArgs that contains event data.</param>\n        public delegate void ThumbnailCachingEventHandler(object sender, ItemEventArgs e);\n        /// <summary>\n        /// Represents the method that will handle the ThumbnailCached event. \n        /// </summary>\n        /// <param name=\"sender\">The ImageListView object that is the source of the event.</param>\n        /// <param name=\"e\">A ItemEventArgs that contains event data.</param>\n        public delegate void ThumbnailCachedEventHandler(object sender, ItemEventArgs e);\n        /// <summary>\n        /// Represents the method that will handle the ThumbnailCached event. \n        /// </summary>\n        /// <param name=\"guid\">The guid of the item whose thumbnail is cached.</param>\n        internal delegate void ThumbnailCachedEventHandlerInternal(Guid guid);\n        /// <summary>\n        /// Represents the method that will handle the Refresh event. \n        /// </summary>\n        internal delegate void RefreshEventHandlerInternal();\n        /// <summary>\n        /// Determines if the given item is visible.\n        /// </summary>\n        /// <param name=\"guid\">The guid of the item to check visibility.</param>\n        internal delegate bool CheckItemVisibleInternal(Guid guid);\n        #endregion\n\n        #region Event Arguments\n        /// <summary>\n        /// Represents the event arguments for the column related events.\n        /// </summary>\n        [Serializable, ComVisible(true)]\n        public class ColumnEventArgs\n        {\n            private SEImageListView.ImageListViewColumnHeader mColumn;\n\n            /// <summary>\n            /// Gets the ImageListViewColumnHeader that is the target of the event.\n            /// </summary>\n            public SEImageListView.ImageListViewColumnHeader Column { get { return mColumn; } }\n\n            public ColumnEventArgs(SEImageListView.ImageListViewColumnHeader column)\n            {\n                mColumn = column;\n            }\n        }\n        /// <summary>\n        /// Represents the event arguments for the column related events.\n        /// </summary>\n        [Serializable, ComVisible(true)]\n        public class ColumnClickEventArgs\n        {\n            private SEImageListView.ImageListViewColumnHeader mColumn;\n            private Point mLocation;\n            private MouseButtons mButtons;\n\n            /// <summary>\n            /// Gets the ImageListViewColumnHeader that is the target of the event.\n            /// </summary>\n            public SEImageListView.ImageListViewColumnHeader Column { get { return mColumn; } }\n            /// <summary>\n            /// Gets the coordinates of the cursor.\n            /// </summary>\n            public Point Location { get { return mLocation; } }\n            /// <summary>\n            /// Gets the x-coordinates of the cursor.\n            /// </summary>\n            public int X { get { return mLocation.X; } }\n            /// <summary>\n            /// Gets the y-coordinates of the cursor.\n            /// </summary>\n            public int Y { get { return mLocation.Y; } }\n            /// <summary>\n            /// Gets the state of the mouse buttons.\n            /// </summary>\n            public MouseButtons Buttons { get { return mButtons; } }\n\n            public ColumnClickEventArgs(SEImageListView.ImageListViewColumnHeader column, Point location, MouseButtons buttons)\n            {\n                mColumn = column;\n                mLocation = location;\n                mButtons = buttons;\n            }\n        }\n        /// <summary>\n        /// Represents the event arguments for the item related events.\n        /// </summary>\n        [Serializable, ComVisible(true)]\n        public class ItemEventArgs\n        {\n            private ImageListViewItem mItem;\n\n            /// <summary>\n            /// Gets the ImageListViewItem that is the target of the event.\n            /// </summary>\n            public ImageListViewItem Item { get { return mItem; } }\n\n            public ItemEventArgs(ImageListViewItem item)\n            {\n                mItem = item;\n            }\n        }\n        /// <summary>\n        /// Represents the event arguments for the item related events.\n        /// </summary>\n        [Serializable, ComVisible(true)]\n        public class ItemClickEventArgs\n        {\n            private ImageListViewItem mItem;\n            private Point mLocation;\n            private MouseButtons mButtons;\n\n            /// <summary>\n            /// Gets the ImageListViewItem that is the target of the event.\n            /// </summary>\n            public ImageListViewItem Item { get { return mItem; } }\n            /// <summary>\n            /// Gets the coordinates of the cursor.\n            /// </summary>\n            public Point Location { get { return mLocation; } }\n            /// <summary>\n            /// Gets the x-coordinates of the cursor.\n            /// </summary>\n            public int X { get { return mLocation.X; } }\n            /// <summary>\n            /// Gets the y-coordinates of the cursor.\n            /// </summary>\n            public int Y { get { return mLocation.Y; } }\n            /// <summary>\n            /// Gets the state of the mouse buttons.\n            /// </summary>\n            public MouseButtons Buttons { get { return mButtons; } }\n\n            public ItemClickEventArgs(ImageListViewItem item, Point location, MouseButtons buttons)\n            {\n                mItem = item;\n                mLocation = location;\n                mButtons = buttons;\n            }\n        }\n        #endregion\n\n        #region Utility Functions\n        /// <summary>\n        /// Contains utility functions.\n        /// </summary>\n        public static class Utility\n        {\n            #region Platform Invoke\n            // GetFileAttributesEx\n            [DllImport(\"kernel32.dll\", SetLastError = true, CharSet = CharSet.Unicode)]\n            [return: MarshalAs(UnmanagedType.Bool)]\n            private static extern bool GetFileAttributesEx(string lpFileName,\n                GET_FILEEX_INFO_LEVELS fInfoLevelId,\n                out WIN32_FILE_ATTRIBUTE_DATA fileData);\n\n            private enum GET_FILEEX_INFO_LEVELS\n            {\n                GetFileExInfoStandard,\n                GetFileExMaxInfoLevel\n            }\n            [StructLayout(LayoutKind.Sequential)]\n            private struct WIN32_FILE_ATTRIBUTE_DATA\n            {\n                public FileAttributes dwFileAttributes;\n                public FILETIME ftCreationTime;\n                public FILETIME ftLastAccessTime;\n                public FILETIME ftLastWriteTime;\n                public uint nFileSizeHigh;\n                public uint nFileSizeLow;\n            }\n            [StructLayout(LayoutKind.Sequential)]\n            struct FILETIME\n            {\n                public uint dwLowDateTime;\n                public uint dwHighDateTime;\n\n                public DateTime Value\n                {\n                    get\n                    {\n                        long longTime = (((long)dwHighDateTime) << 32) | ((uint)dwLowDateTime);\n                        return DateTime.FromFileTimeUtc(longTime);\n                    }\n                }\n            }\n            // SHGetFileInfo\n            [DllImport(\"shell32.dll\", CharSet = CharSet.Auto)]\n            private static extern IntPtr SHGetFileInfo(string pszPath, FileAttributes dwFileAttributes, out SHFILEINFO psfi, uint cbFileInfo, SHGFI uFlags);\n            [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]\n            private struct SHFILEINFO\n            {\n                public IntPtr hIcon;\n                public int iIcon;\n                public uint dwAttributes;\n                [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)]\n                public string szDisplayName;\n                [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_TYPE)]\n                public string szTypeName;\n            };\n            private const int MAX_PATH = 260;\n            private const int MAX_TYPE = 80;\n            [Flags]\n            private enum SHGFI : uint\n            {\n                Icon = 0x000000100,\n                DisplayName = 0x000000200,\n                TypeName = 0x000000400,\n                Attributes = 0x000000800,\n                IconLocation = 0x000001000,\n                ExeType = 0x000002000,\n                SysIconIndex = 0x000004000,\n                LinkOverlay = 0x000008000,\n                Selected = 0x000010000,\n                Attr_Specified = 0x000020000,\n                LargeIcon = 0x000000000,\n                SmallIcon = 0x000000001,\n                OpenIcon = 0x000000002,\n                ShellIconSize = 0x000000004,\n                PIDL = 0x000000008,\n                UseFileAttributes = 0x000000010,\n                AddOverlays = 0x000000020,\n                OverlayIndex = 0x000000040,\n            }\n            /// <summary>\n            /// Creates a value for use as an lParam parameter in a message.\n            /// </summary>\n            /// <param name=\"low\">the low-order word of the new value.</param>\n            /// <param name=\"high\">the high-order word of the new value.</param>\n            /// <returns>Concatenation of low and high as an IntPtr.</returns>\n            public static IntPtr MakeLParam(short low, short high)\n            {\n                return (IntPtr)((((int)low) & 0xffff) | ((((int)high) & 0xffff) << 16));\n            }\n            /// <summary>\n            /// Creates a quadword value from the given low and high-order double words.\n            /// </summary>\n            /// <param name=\"low\">the low-order dword of the new value.</param>\n            /// <param name=\"high\">the high-order dword of the new value.</param>\n            /// <returns></returns>\n            public static long MakeQWord(int lowPart, int highPart)\n            {\n                return (long)(((long)lowPart) | (long)(highPart << 32));\n            }\n            /// <summary>\n            /// Creates a quadword value from the given low and high-order double words.\n            /// </summary>\n            /// <param name=\"low\">the low-order dword of the new value.</param>\n            /// <param name=\"high\">the high-order dword of the new value.</param>\n            /// <returns></returns>\n            public static ulong MakeQWord(uint lowPart, uint highPart)\n            {\n                return (ulong)(((ulong)lowPart) | (ulong)(highPart << 32));\n            }\n            #endregion\n\n            #region Text Utilities\n            /// <summary>\n            /// Formats the given file size in bytes as a human readable string.\n            /// </summary>\n            public static string FormatSize(long size)\n            {\n                double mod = 1024;\n                double sized = size;\n\n                // string[] units = new string[] { \"B\", \"KiB\", \"MiB\", \"GiB\", \"TiB\", \"PiB\" };\n                string[] units = new string[] { \"B\", \"KB\", \"MB\", \"GB\", \"TB\", \"PB\" };\n                int i;\n                for (i = 0; sized > mod; i++)\n                {\n                    sized /= mod;\n                }\n\n                return string.Format(\"{0} {1}\", System.Math.Round(sized, 2), units[i]);\n            }\n            #endregion\n\n            #region Shell Utilities\n            /// <summary>\n            /// A utility class combining FileInfo with SHGetFileInfo.\n            /// </summary>\n            public class ShellFileInfo\n            {\n                private static Dictionary<string, string> cachedFileTypes;\n                private uint structSize = 0;\n\n                public bool Error { get; private set; }\n                public FileAttributes FileAttributes { get; private set; }\n                public DateTime CreationTime { get; private set; }\n                public DateTime LastAccessTime { get; private set; }\n                public DateTime LastWriteTime { get; private set; }\n                public string Extension { get; private set; }\n                public string DirectoryName { get; private set; }\n                public string DisplayName { get; private set; }\n                public long Size { get; private set; }\n                public string TypeName { get; private set; }\n\n                public ShellFileInfo(string path)\n                {\n                    if (cachedFileTypes == null)\n                        cachedFileTypes = new Dictionary<string, string>();\n\n                    try\n                    {\n                        FileInfo info = new FileInfo(path);\n                        FileAttributes = info.Attributes;\n                        CreationTime = info.CreationTime;\n                        LastAccessTime = info.LastAccessTime;\n                        LastWriteTime = info.LastWriteTime;\n                        Size = info.Length;\n                        DirectoryName = info.DirectoryName;\n                        DisplayName = info.Name;\n                        Extension = info.Extension;\n\n                        string typeName;\n                        if (!cachedFileTypes.TryGetValue(Extension, out typeName))\n                        {\n                            SHFILEINFO shinfo = new SHFILEINFO();\n                            if (structSize == 0) structSize = (uint)Marshal.SizeOf(shinfo);\n                            SHGetFileInfo(path, (FileAttributes)0, out shinfo, structSize, SHGFI.TypeName);\n                            typeName = shinfo.szTypeName;\n                            cachedFileTypes.Add(Extension, typeName);\n                        }\n                        TypeName = typeName;\n\n                        Error = false;\n                    }\n                    catch\n                    {\n                        Error = true;\n                    }\n                }\n            }\n            #endregion\n\n            #region Graphics Extensions\n            /// <summary>\n            /// Creates a new image from the given base 64 string.\n            /// </summary>\n            public static Image ImageFromBase64String(string base64String)\n            {\n                byte[] imageData = Convert.FromBase64String(base64String);\n                MemoryStream memory = new MemoryStream(imageData);\n                Image image = Image.FromStream(memory);\n                memory.Close();\n                return image;\n            }\n            /// <summary>\n            /// Returns the base 64 string representation of the given image.\n            /// </summary>\n            public static string ImageToBase64String(Image image)\n            {\n                MemoryStream memory = new MemoryStream();\n                image.Save(memory, System.Drawing.Imaging.ImageFormat.Png);\n                string base64String = Convert.ToBase64String(memory.ToArray());\n                memory.Close();\n                return base64String;\n            }\n            /// <summary>\n            /// Gets a path representing a rounded rectangle.\n            /// </summary>\n            private static GraphicsPath GetRoundedRectanglePath(int x, int y, int width, int height, int radius)\n            {\n                GraphicsPath path = new GraphicsPath();\n                path.AddLine(x + radius, y, x + width - radius, y);\n                if (radius > 0)\n                    path.AddArc(x + width - 2 * radius, y, 2 * radius, 2 * radius, 270.0f, 90.0f);\n                path.AddLine(x + width, y + radius, x + width, y + height - radius);\n                if (radius > 0)\n                    path.AddArc(x + width - 2 * radius, y + height - 2 * radius, 2 * radius, 2 * radius, 0.0f, 90.0f);\n                path.AddLine(x + width - radius, y + height, x + radius, y + height);\n                if (radius > 0)\n                    path.AddArc(x, y + height - 2 * radius, 2 * radius, 2 * radius, 90.0f, 90.0f);\n                path.AddLine(x, y + height - radius, x, y + radius);\n                if (radius > 0)\n                    path.AddArc(x, y, 2 * radius, 2 * radius, 180.0f, 90.0f);\n                return path;\n            }\n            /// <summary>\n            /// Fills the interior of a rounded rectangle.\n            /// </summary>\n            public static void FillRoundedRectangle(System.Drawing.Graphics graphics, Brush brush, int x, int y, int width, int height, int radius)\n            {\n                using (GraphicsPath path = GetRoundedRectanglePath(x, y, width, height, radius))\n                {\n                    graphics.FillPath(brush, path);\n                }\n            }\n\n            /// <summary>\n            /// Fills the interior of a rounded rectangle.\n            /// </summary>\n            public static void FillRoundedRectangle(System.Drawing.Graphics graphics, Brush brush, float x, float y, float width, float height, float radius)\n            {\n                FillRoundedRectangle(graphics, brush, (int)x, (int)y, (int)width, (int)height, (int)radius);\n            }\n\n            /// <summary>\n            /// Fills the interior of a rounded rectangle.\n            /// </summary>\n            public static void FillRoundedRectangle(System.Drawing.Graphics graphics, Brush brush, Rectangle rect, int radius)\n            {\n                FillRoundedRectangle(graphics, brush, rect.Left, rect.Top, rect.Width, rect.Height, radius);\n            }\n\n            /// <summary>\n            /// Fills the interior of a rounded rectangle.\n            /// </summary>\n            public static void FillRoundedRectangle(System.Drawing.Graphics graphics, Brush brush, RectangleF rect, float radius)\n            {\n                FillRoundedRectangle(graphics, brush, (int)rect.Left, (int)rect.Top, (int)rect.Width, (int)rect.Height, (int)radius);\n            }\n\n            /// <summary>\n            /// Draws the outline of a rounded rectangle.\n            /// </summary>\n            public static void DrawRoundedRectangle(System.Drawing.Graphics graphics, Pen pen, int x, int y, int width, int height, int radius)\n            {\n                using (GraphicsPath path = GetRoundedRectanglePath(x, y, width, height, radius))\n                {\n                    graphics.DrawPath(pen, path);\n                }\n            }\n\n            /// <summary>\n            /// Draws the outline of a rounded rectangle.\n            /// </summary>\n            public static void DrawRoundedRectangle(System.Drawing.Graphics graphics, Pen pen, float x, float y, float width, float height, float radius)\n            {\n                DrawRoundedRectangle(graphics, pen, (int)x, (int)y, (int)width, (int)height, (int)radius);\n            }\n\n            /// <summary>\n            /// Draws the outline of a rounded rectangle.\n            /// </summary>\n            public static void DrawRoundedRectangle(System.Drawing.Graphics graphics, Pen pen, Rectangle rect, int radius)\n            {\n                DrawRoundedRectangle(graphics, pen, rect.Left, rect.Top, rect.Width, rect.Height, radius);\n            }\n\n            /// <summary>\n            /// Draws the outline of a rounded rectangle.\n            /// </summary>\n            public static void DrawRoundedRectangle(System.Drawing.Graphics graphics, Pen pen, RectangleF rect, float radius)\n            {\n                DrawRoundedRectangle(graphics, pen, (int)rect.Left, (int)rect.Top, (int)rect.Width, (int)rect.Height, (int)radius);\n            }\n            #endregion\n        }\n        #endregion\n    }\n\n\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/Sheng.Winform.Controls.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\" ToolsVersion=\"4.0\">\r\n  <PropertyGroup>\r\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\r\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\r\n    <ProductVersion>9.0.30729</ProductVersion>\r\n    <SchemaVersion>2.0</SchemaVersion>\r\n    <ProjectGuid>{8947FDAE-9F4B-4D77-91AA-0704ACD83DBD}</ProjectGuid>\r\n    <OutputType>Library</OutputType>\r\n    <AppDesignerFolder>Properties</AppDesignerFolder>\r\n    <RootNamespace>Sheng.Winform.Controls</RootNamespace>\r\n    <AssemblyName>Sheng.Winform.Controls</AssemblyName>\r\n    <FileUpgradeFlags>\r\n    </FileUpgradeFlags>\r\n    <OldToolsVersion>3.5</OldToolsVersion>\r\n    <UpgradeBackupLocation>\r\n    </UpgradeBackupLocation>\r\n    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>\r\n    <IsWebBootstrapper>true</IsWebBootstrapper>\r\n    <PublishUrl>http://localhost/SEControl/</PublishUrl>\r\n    <Install>true</Install>\r\n    <InstallFrom>Web</InstallFrom>\r\n    <UpdateEnabled>true</UpdateEnabled>\r\n    <UpdateMode>Foreground</UpdateMode>\r\n    <UpdateInterval>7</UpdateInterval>\r\n    <UpdateIntervalUnits>Days</UpdateIntervalUnits>\r\n    <UpdatePeriodically>false</UpdatePeriodically>\r\n    <UpdateRequired>false</UpdateRequired>\r\n    <MapFileExtensions>true</MapFileExtensions>\r\n    <ApplicationRevision>0</ApplicationRevision>\r\n    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>\r\n    <UseApplicationTrust>false</UseApplicationTrust>\r\n    <BootstrapperEnabled>true</BootstrapperEnabled>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\r\n    <DebugSymbols>true</DebugSymbols>\r\n    <DebugType>full</DebugType>\r\n    <Optimize>false</Optimize>\r\n    <OutputPath>bin\\Debug\\</OutputPath>\r\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\r\n    <ErrorReport>prompt</ErrorReport>\r\n    <WarningLevel>4</WarningLevel>\r\n    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\r\n    <DebugType>pdbonly</DebugType>\r\n    <Optimize>true</Optimize>\r\n    <OutputPath>bin\\Release\\</OutputPath>\r\n    <DefineConstants>TRACE</DefineConstants>\r\n    <ErrorReport>prompt</ErrorReport>\r\n    <WarningLevel>4</WarningLevel>\r\n    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <ItemGroup>\r\n    <Reference Include=\"PresentationCore\" />\r\n    <Reference Include=\"System\" />\r\n    <Reference Include=\"System.Core\">\r\n      <RequiredTargetFramework>3.5</RequiredTargetFramework>\r\n    </Reference>\r\n    <Reference Include=\"System.Data\" />\r\n    <Reference Include=\"System.Design\" />\r\n    <Reference Include=\"System.Drawing\" />\r\n    <Reference Include=\"System.Windows.Forms\" />\r\n    <Reference Include=\"System.Xml\" />\r\n    <Reference Include=\"WindowsBase\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <Compile Include=\"BrowserDisplayBinding\\BrowserPane.cs\" />\r\n    <Compile Include=\"BrowserDisplayBinding\\DefaultHtmlViewSchemeExtension.cs\" />\r\n    <Compile Include=\"BrowserDisplayBinding\\ExtendedWebBrowser.cs\" />\r\n    <Compile Include=\"BrowserDisplayBinding\\HtmlViewPane.cs\">\r\n      <SubType>UserControl</SubType>\r\n    </Compile>\r\n    <Compile Include=\"BrowserDisplayBinding\\HtmlViewPaneEvents.cs\" />\r\n    <Compile Include=\"BrowserDisplayBinding\\IHtmlViewSchemeExtension.cs\" />\r\n    <Compile Include=\"ShengDataGridView\\ShengDataGridViewImageBinderCell.cs\" />\r\n    <Compile Include=\"ShengDataGridView\\ShengDataGridViewImageBinderColumn.cs\" />\r\n    <Compile Include=\"ShengDataGridView\\Renderer\\ShengDataGridViewCheckBoxCellRenderer.cs\" />\r\n    <Compile Include=\"ShengDataGridView\\Renderer\\ShengDataGridViewImageCellRenderer.cs\" />\r\n    <Compile Include=\"ShengDataGridView\\Renderer\\ShengDataGridViewRenderer.cs\" />\r\n    <Compile Include=\"ShengDataGridView\\Renderer\\ShengDataGridViewRendererTheme.cs\" />\r\n    <Compile Include=\"ShengDataGridView\\Renderer\\IShengDataGridViewCellRenderer.cs\" />\r\n    <Compile Include=\"DragHelper.cs\" />\r\n    <Compile Include=\"IconResource.Designer.cs\">\r\n      <AutoGen>True</AutoGen>\r\n      <DesignTime>True</DesignTime>\r\n      <DependentUpon>IconResource.resx</DependentUpon>\r\n    </Compile>\r\n    <Compile Include=\"ShengImageListView\\Enums.cs\">\r\n      <SubType>Code</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengImageListView\\Events.cs\">\r\n      <SubType>Code</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengImageListView\\ShengImageListView.cs\">\r\n      <SubType>Component</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengImageListView\\ShengImageListViewCollection.cs\">\r\n      <SubType>Code</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengImageListView\\ShengImageListViewColor.cs\">\r\n      <SubType>Code</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengImageListView\\ShengImageListViewHitInfo.cs\" />\r\n    <Compile Include=\"ShengImageListView\\ShengImageListViewItem.cs\">\r\n      <SubType>Code</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengImageListView\\ShengImageListViewItemThumbnailsCache.cs\">\r\n      <SubType>Code</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengImageListView\\ShengImageListViewLayoutManager.cs\">\r\n      <SubType>Code</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengImageListView\\ShengImageListViewRenderer.cs\">\r\n      <SubType>Code</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengImageListView\\ShengImageListViewStandardRenderer.cs\">\r\n      <SubType>Code</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengImageListView\\ShengImageListViewTheme.cs\">\r\n      <SubType>Code</SubType>\r\n    </Compile>\r\n    <Compile Include=\"LocalizedDescription.cs\" />\r\n    <Compile Include=\"PopupControl\\GripBounds.cs\" />\r\n    <Compile Include=\"PopupControl\\NativeMethods.cs\" />\r\n    <Compile Include=\"PopupControl\\Popup.cs\">\r\n      <SubType>Component</SubType>\r\n    </Compile>\r\n    <Compile Include=\"PopupControl\\Popup.Designer.cs\">\r\n      <DependentUpon>Popup.cs</DependentUpon>\r\n    </Compile>\r\n    <Compile Include=\"PopupControl\\PopupAnimation.cs\" />\r\n    <Compile Include=\"PopupControl\\PopupComboBox.cs\">\r\n      <SubType>Component</SubType>\r\n    </Compile>\r\n    <Compile Include=\"PopupControl\\PopupComboBox.Designer.cs\">\r\n      <DependentUpon>PopupComboBox.cs</DependentUpon>\r\n    </Compile>\r\n    <Compile Include=\"PopupControl\\PopupControlComboBoxBase.cs\">\r\n      <SubType>Component</SubType>\r\n    </Compile>\r\n    <Compile Include=\"PopupControl\\PopupControlComboBoxBase.Designer.cs\">\r\n      <DependentUpon>PopupControlComboBoxBase.cs</DependentUpon>\r\n    </Compile>\r\n    <Compile Include=\"Renderer\\Office2010Renderer.cs\" />\r\n    <Compile Include=\"Renderer\\ToolStripRenders.cs\" />\r\n    <Compile Include=\"ShengAreoMainMenuStrip.cs\">\r\n      <SubType>Component</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengComboSelector2\\ShengComboSelector2.cs\">\r\n      <SubType>Component</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengComboSelector2\\Enums.cs\" />\r\n    <Compile Include=\"ShengComboSelector2\\ShengComboSelectorTheme.cs\" />\r\n    <Compile Include=\"ShengAdressBar\\ShengFileSystemNode.cs\" />\r\n    <Compile Include=\"ShengAdressBar\\IShengAddressNode.cs\" />\r\n    <Compile Include=\"ShengAdressBar\\ShengAddressBar.cs\">\r\n      <SubType>UserControl</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengAdressBar\\ShengAddressBar.Designer.cs\">\r\n      <DependentUpon>ShengAddressBar.cs</DependentUpon>\r\n    </Compile>\r\n    <Compile Include=\"ShengAdressBar\\ShengAddressBarStrip.cs\">\r\n      <SubType>Component</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengAdressBar\\ShengAddressBarButton.cs\">\r\n      <SubType>Component</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengAdressBar\\ShengAddressBarDropDown.cs\">\r\n      <SubType>Component</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengAdressBar\\ShengAddressBarDropDownButton.cs\">\r\n      <SubType>Component</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengAdressBar\\ShengAddressBarDropDownItem.cs\">\r\n      <SubType>Component</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengComboSelector\\ShengComboSelector.cs\">\r\n      <SubType>UserControl</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengComboSelector\\ShengComboSelector.Designer.cs\">\r\n      <DependentUpon>ShengComboSelector.cs</DependentUpon>\r\n    </Compile>\r\n    <Compile Include=\"ShengComboSelector\\ShengComboSelectorItem.cs\" />\r\n    <Compile Include=\"ShengComboSelector\\ShengComboSelectorItemCollection.cs\" />\r\n    <Compile Include=\"ShengComboSelector\\ShengComboSelectorItemContainer.cs\">\r\n      <SubType>UserControl</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengComboSelector\\ShengComboSelectorItemContainer.Designer.cs\">\r\n      <DependentUpon>ShengComboSelectorItemContainer.cs</DependentUpon>\r\n    </Compile>\r\n    <Compile Include=\"IShengValidate.cs\" />\r\n    <Compile Include=\"ShengNavigationTreeView\\ShengNavigationTreeNode.cs\" />\r\n    <Compile Include=\"ShengNavigationTreeView\\ShengNavigationTreeView.cs\">\r\n      <SubType>Component</SubType>\r\n    </Compile>\r\n    <Compile Include=\"IShengForm.cs\" />\r\n    <Compile Include=\"Properties\\Resources.Designer.cs\">\r\n      <AutoGen>True</AutoGen>\r\n      <DesignTime>True</DesignTime>\r\n      <DependentUpon>Resources.resx</DependentUpon>\r\n    </Compile>\r\n    <Compile Include=\"Renderer\\SEToolStripRender.cs\" />\r\n    <Compile Include=\"ShengAdvComboBox.cs\">\r\n      <SubType>Component</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengAdvComboBoxDropdownBase.cs\">\r\n      <SubType>UserControl</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengAdvComboBoxDropdownBase.Designer.cs\">\r\n      <DependentUpon>ShengAdvComboBoxDropdownBase.cs</DependentUpon>\r\n    </Compile>\r\n    <Compile Include=\"ShengAdvLabel.cs\">\r\n      <SubType>Component</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengColorChooseComboBox.cs\">\r\n      <SubType>UserControl</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengColorChooseComboBox.Designer.cs\">\r\n      <DependentUpon>ShengColorChooseComboBox.cs</DependentUpon>\r\n    </Compile>\r\n    <Compile Include=\"ShengColorChooseComboBoxDropDown.cs\">\r\n      <SubType>UserControl</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengColorChooseComboBoxDropDown.Designer.cs\">\r\n      <DependentUpon>ShengColorChooseComboBoxDropDown.cs</DependentUpon>\r\n    </Compile>\r\n    <Compile Include=\"ShengDataGridView\\ShengDataGridViewCheckBoxColumn.cs\" />\r\n    <Compile Include=\"ShengFlatButton.cs\">\r\n      <SubType>UserControl</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengFlatButton.Designer.cs\">\r\n      <DependentUpon>ShengFlatButton.cs</DependentUpon>\r\n    </Compile>\r\n    <Compile Include=\"ShengListView\\Enums.cs\" />\r\n    <Compile Include=\"ShengListView\\Events.cs\" />\r\n    <Compile Include=\"ShengListView\\Layout\\IShengListViewExtendMember.cs\" />\r\n    <Compile Include=\"ShengListView\\Layout\\ShengListViewDescriptiveLayoutManager.cs\" />\r\n    <Compile Include=\"ShengListView\\Layout\\ShengListViewDescriptiveMembers.cs\" />\r\n    <Compile Include=\"ShengListView\\Layout\\ShengListViewDescriptiveRenderer.cs\" />\r\n    <Compile Include=\"ShengListView\\Layout\\ShengListViewLayoutManager.cs\" />\r\n    <Compile Include=\"ShengListView\\Layout\\ShengListViewRenderer.cs\" />\r\n    <Compile Include=\"ShengListView\\Layout\\ShengListViewStandardLayoutManager.cs\" />\r\n    <Compile Include=\"ShengListView\\Layout\\ShengListViewStandardRenderer.cs\" />\r\n    <Compile Include=\"ShengListView\\Layout\\ShengListViewTheme.cs\" />\r\n    <Compile Include=\"ShengListView\\ShengListView.cs\">\r\n      <SubType>Component</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengListView\\ShengListViewColor.cs\" />\r\n    <Compile Include=\"ShengListView\\ShengListViewHitInfo.cs\" />\r\n    <Compile Include=\"ShengListView\\ShengListViewItem.cs\" />\r\n    <Compile Include=\"ShengListView\\ShengListViewItemCollection.cs\" />\r\n    <Compile Include=\"ShengLoadingCircle.cs\">\r\n      <SubType>Component</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengPad.cs\">\r\n      <SubType>Component</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengPaginationDataGridView.cs\">\r\n      <SubType>UserControl</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengPaginationDataGridView.Designer.cs\">\r\n      <DependentUpon>ShengPaginationDataGridView.cs</DependentUpon>\r\n    </Compile>\r\n    <Compile Include=\"ShengSimpleCheckBox.cs\">\r\n      <SubType>Component</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengDataGridView\\ShengDataGridView.cs\">\r\n      <SubType>Component</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengForm.cs\">\r\n      <SubType>Form</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengForm.Designer.cs\">\r\n      <DependentUpon>ShengForm.cs</DependentUpon>\r\n    </Compile>\r\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\r\n    <Compile Include=\"ShengComboBox.cs\">\r\n      <SubType>Component</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengDatetimePicker.cs\">\r\n      <SubType>Component</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengGroupBox.cs\">\r\n      <SubType>Component</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengLine.cs\">\r\n      <SubType>Component</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengPanel.cs\">\r\n      <SubType>Component</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengTabControl.cs\">\r\n      <SubType>Component</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengTextBox.cs\">\r\n      <SubType>Component</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengToolStrip.cs\" />\r\n    <Compile Include=\"ShengToolStripMenuItem.cs\">\r\n      <SubType>Component</SubType>\r\n    </Compile>\r\n    <Compile Include=\"Renderer\\SEToolStripProfessionalRenderer_Gary.cs\" />\r\n    <Compile Include=\"ShengToolStripSeparator.cs\">\r\n      <SubType>Component</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengTreeView.cs\">\r\n      <SubType>Component</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengUserControl.cs\">\r\n      <SubType>UserControl</SubType>\r\n    </Compile>\r\n    <Compile Include=\"ShengUserControl.Designer.cs\">\r\n      <DependentUpon>ShengUserControl.cs</DependentUpon>\r\n    </Compile>\r\n    <Compile Include=\"ShengValidateHelper.cs\" />\r\n    <Compile Include=\"ShengThumbnailImageListView.cs\">\r\n      <SubType>Component</SubType>\r\n    </Compile>\r\n    <Compile Include=\"Wizard\\IWizardView.cs\" />\r\n    <Compile Include=\"Wizard\\WizardView.cs\">\r\n      <SubType>Form</SubType>\r\n    </Compile>\r\n    <Compile Include=\"Wizard\\WizardView.Designer.cs\">\r\n      <DependentUpon>WizardView.cs</DependentUpon>\r\n    </Compile>\r\n    <Compile Include=\"Wizard\\WizardPanelBase.cs\">\r\n      <SubType>UserControl</SubType>\r\n    </Compile>\r\n    <Compile Include=\"Wizard\\WizardPanelBase.Designer.cs\">\r\n      <DependentUpon>WizardPanelBase.cs</DependentUpon>\r\n    </Compile>\r\n    <Service Include=\"{94E38DFF-614B-4cbd-B67C-F211BB35CE8B}\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <BootstrapperPackage Include=\"Microsoft.Net.Client.3.5\">\r\n      <Visible>False</Visible>\r\n      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>\r\n      <Install>false</Install>\r\n    </BootstrapperPackage>\r\n    <BootstrapperPackage Include=\"Microsoft.Net.Framework.2.0\">\r\n      <Visible>False</Visible>\r\n      <ProductName>.NET Framework 2.0 %28x86%29</ProductName>\r\n      <Install>true</Install>\r\n    </BootstrapperPackage>\r\n    <BootstrapperPackage Include=\"Microsoft.Net.Framework.3.0\">\r\n      <Visible>False</Visible>\r\n      <ProductName>.NET Framework 3.0 %28x86%29</ProductName>\r\n      <Install>false</Install>\r\n    </BootstrapperPackage>\r\n    <BootstrapperPackage Include=\"Microsoft.Net.Framework.3.5\">\r\n      <Visible>False</Visible>\r\n      <ProductName>.NET Framework 3.5</ProductName>\r\n      <Install>false</Install>\r\n    </BootstrapperPackage>\r\n    <BootstrapperPackage Include=\"Microsoft.Net.Framework.3.5.SP1\">\r\n      <Visible>False</Visible>\r\n      <ProductName>.NET Framework 3.5 SP1</ProductName>\r\n      <Install>false</Install>\r\n    </BootstrapperPackage>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ProjectReference Include=\"..\\Sheng.Winform.Controls.Localisation\\Sheng.Winform.Controls.Localisation.csproj\">\r\n      <Project>{e0b8ad36-cc90-41f5-bd00-ec614569c9f9}</Project>\r\n      <Name>Sheng.Winform.Controls.Localisation</Name>\r\n    </ProjectReference>\r\n    <ProjectReference Include=\"..\\Sheng.Winform.Controls.Drawing\\Sheng.Winform.Controls.Drawing.csproj\">\r\n      <Project>{BCD80096-7B6F-4273-A031-186A610C84E5}</Project>\r\n      <Name>Sheng.Winform.Controls.Drawing</Name>\r\n    </ProjectReference>\r\n    <ProjectReference Include=\"..\\Sheng.Winform.Controls.Kernal\\Sheng.Winform.Controls.Kernal.csproj\">\r\n      <Project>{125FB802-2C83-47DC-BA57-910064355CCD}</Project>\r\n      <Name>Sheng.Winform.Controls.Kernal</Name>\r\n    </ProjectReference>\r\n    <ProjectReference Include=\"..\\Sheng.Winform.Controls.Win32\\Sheng.Winform.Controls.Win32.csproj\">\r\n      <Project>{946FFB43-4864-4967-8D69-8716CDA83F7A}</Project>\r\n      <Name>Sheng.Winform.Controls.Win32</Name>\r\n    </ProjectReference>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <EmbeddedResource Include=\"Properties\\Resources.resx\">\r\n      <Generator>ResXFileCodeGenerator</Generator>\r\n      <LastGenOutput>Resources.Designer.cs</LastGenOutput>\r\n    </EmbeddedResource>\r\n    <EmbeddedResource Include=\"ShengAdvComboBoxDropdownBase.resx\">\r\n      <DependentUpon>ShengAdvComboBoxDropdownBase.cs</DependentUpon>\r\n    </EmbeddedResource>\r\n    <EmbeddedResource Include=\"ShengColorChooseComboBoxDropDown.resx\">\r\n      <DependentUpon>ShengColorChooseComboBoxDropDown.cs</DependentUpon>\r\n    </EmbeddedResource>\r\n    <EmbeddedResource Include=\"ShengForm.resx\">\r\n      <DependentUpon>ShengForm.cs</DependentUpon>\r\n    </EmbeddedResource>\r\n    <EmbeddedResource Include=\"Wizard\\WizardView.resx\">\r\n      <DependentUpon>WizardView.cs</DependentUpon>\r\n    </EmbeddedResource>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"Resources\\Arrow_right_green.png\" />\r\n    <None Include=\"Resources\\Browser.png\" />\r\n    <None Include=\"Resources\\Browser_Back.png\" />\r\n    <None Include=\"Resources\\Browser_Forward.png\" />\r\n    <None Include=\"Resources\\Browser_Home.png\" />\r\n    <None Include=\"Resources\\Browser_Refresh.png\" />\r\n    <None Include=\"Resources\\Browser_Stop.png\" />\r\n    <None Include=\"Resources\\FolderClosed.bmp\" />\r\n    <None Include=\"Resources\\Folder.bmp\" />\r\n    <None Include=\"Resources\\Check.bmp\" />\r\n    <None Include=\"Resources\\Unknown.bmp\" />\r\n    <None Include=\"Resources\\Uncheck.bmp\" />\r\n    <None Include=\"Resources\\Leaf.bmp\" />\r\n    <None Include=\"Resources\\Minus2.png\" />\r\n    <None Include=\"Resources\\Plus2.png\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <EmbeddedResource Include=\"IconResource.resx\">\r\n      <Generator>ResXFileCodeGenerator</Generator>\r\n      <LastGenOutput>IconResource.Designer.cs</LastGenOutput>\r\n    </EmbeddedResource>\r\n    <EmbeddedResource Include=\"ShengAdressBar\\ShengAddressBar.resx\">\r\n      <DependentUpon>ShengAddressBar.cs</DependentUpon>\r\n    </EmbeddedResource>\r\n    <EmbeddedResource Include=\"ShengComboSelector\\ShengComboSelector.resx\">\r\n      <DependentUpon>ShengComboSelector.cs</DependentUpon>\r\n    </EmbeddedResource>\r\n    <EmbeddedResource Include=\"ShengComboSelector\\ShengComboSelectorItemContainer.resx\">\r\n      <DependentUpon>ShengComboSelectorItemContainer.cs</DependentUpon>\r\n    </EmbeddedResource>\r\n    <EmbeddedResource Include=\"ShengFlatButton.resx\">\r\n      <DependentUpon>ShengFlatButton.cs</DependentUpon>\r\n    </EmbeddedResource>\r\n    <EmbeddedResource Include=\"ShengPaginationDataGridView.resx\">\r\n      <DependentUpon>ShengPaginationDataGridView.cs</DependentUpon>\r\n    </EmbeddedResource>\r\n    <EmbeddedResource Include=\"ShengUserControl.resx\">\r\n      <DependentUpon>ShengUserControl.cs</DependentUpon>\r\n    </EmbeddedResource>\r\n    <EmbeddedResource Include=\"Wizard\\WizardPanelBase.resx\">\r\n      <DependentUpon>WizardPanelBase.cs</DependentUpon>\r\n    </EmbeddedResource>\r\n  </ItemGroup>\r\n  <ItemGroup />\r\n  <Import Project=\"$(MSBuildBinPath)\\Microsoft.CSharp.targets\" />\r\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\r\n</Project>"
  },
  {
    "path": "Sheng.Winform.Controls/Sheng.Winform.Controls.csproj.user",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <PropertyGroup>\r\n    <PublishUrlHistory>\r\n    </PublishUrlHistory>\r\n    <InstallUrlHistory>\r\n    </InstallUrlHistory>\r\n    <SupportUrlHistory>\r\n    </SupportUrlHistory>\r\n    <UpdateUrlHistory>\r\n    </UpdateUrlHistory>\r\n    <BootstrapperUrlHistory>\r\n    </BootstrapperUrlHistory>\r\n    <ErrorReportUrlHistory>\r\n    </ErrorReportUrlHistory>\r\n    <FallbackCulture>zh-CN</FallbackCulture>\r\n    <VerifyUploadedFiles>true</VerifyUploadedFiles>\r\n    <ProjectView>ProjectFiles</ProjectView>\r\n  </PropertyGroup>\r\n</Project>"
  },
  {
    "path": "Sheng.Winform.Controls/ShengAdressBar/IShengAddressNode.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Drawing;\n\nnamespace Sheng.Winform.Controls\n{\n    public interface IShengAddressNode\n    {\n        /// <summary>\n        /// Gets/Sets the parent of this node\n        /// </summary>\n        IShengAddressNode Parent\n        {\n            get;\n            set;\n        }\n\n        /// <summary>\n        /// Gets/Sets the Display name of this node\n        /// </summary>\n        String DisplayName\n        {\n            get;\n        }\n\n        /// <summary>\n        /// Gets the Icon that represents this node type.\n        /// </summary>\n        Bitmap Icon\n        {\n            get;\n        }\n\n        /// <summary>\n        /// Gets the Unique ID for this node\n        /// </summary>\n        string UniqueID\n        {\n            get;\n        }\n\n        /// <summary>\n        /// 此节点所包含的子级节点的下拉面板\n        /// </summary>\n        ShengAddressBarDropDown DropDownMenu\n        {\n            get;\n            set;\n        }\n\n        /// <summary>\n        /// Gets an array of Child Nodes\n        /// </summary>\n        IShengAddressNode[] Children\n        {\n            get;\n        }\n\n        /// <summary>\n        /// Method that updates this node to gather all relevant detail.\n        /// 创建子节点\n        /// 主要作用是初始化子节点，目前也就初始化根节点和添加一个新的子节点的时候调用一下\n        /// </summary>\n        void CreateChildNodes();\n\n        /// <summary>\n        /// 刷新（重新创建）子节点\n        /// </summary>\n        void UpdateChildNodes();\n\n        /// <summary>\n        /// Returns a given child, based on a unique ID\n        /// </summary>\n        /// <param name=\"uniqueID\">Unique ID to identify the child</param>\n        /// <param name=\"recursive\">Indicates if the search should recurse through childrens children..</param>\n        /// <returns>Returns the child node</returns>\n        IShengAddressNode GetChild(string uniqueID);\n\n        /// <summary>\n        /// Clones a node.\n        /// </summary>\n        /// <returns>Clone of this node.</returns>\n        IShengAddressNode Clone();\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengAdressBar/ShengAddressBar.Designer.cs",
    "content": "﻿namespace Sheng.Winform.Controls.SEAdressBar\n{\n    partial class ShengAddressBar\n    {\n        /// <summary> \n        /// 必需的设计器变量。\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary> \n        /// 清理所有正在使用的资源。\n        /// </summary>\n        /// <param name=\"disposing\">如果应释放托管资源，为 true；否则为 false。</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region 组件设计器生成的代码\n\n        /// <summary> \n        /// 设计器支持所需的方法 - 不要\n        /// 使用代码编辑器修改此方法的内容。\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.addressBarStrip = new Sheng.Winform.Controls.ShengAddressBarStrip();\n            this.SuspendLayout();\n            // \n            // addressBarStrip\n            // \n            this.addressBarStrip.CurrentNode = null;\n            this.addressBarStrip.Dock = System.Windows.Forms.DockStyle.Fill;\n            this.addressBarStrip.DropDownRenderer = null;\n            this.addressBarStrip.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden;\n            this.addressBarStrip.Location = new System.Drawing.Point(0, 0);\n            this.addressBarStrip.Name = \"addressBarStrip\";\n            this.addressBarStrip.RenderMode = System.Windows.Forms.ToolStripRenderMode.System;\n            this.addressBarStrip.RootNode = null;\n            this.addressBarStrip.Size = new System.Drawing.Size(466, 28);\n            this.addressBarStrip.TabIndex = 0;\n            this.addressBarStrip.Text = \"seAddressBarStrip1\";\n            // \n            // SEAddressBar\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.Controls.Add(this.addressBarStrip);\n            this.Name = \"SEAddressBar\";\n            this.Size = new System.Drawing.Size(466, 28);\n            this.ResumeLayout(false);\n            this.PerformLayout();\n\n        }\n\n        #endregion\n\n        private ShengAddressBarStrip addressBarStrip;\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengAdressBar/ShengAddressBar.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Drawing;\nusing System.Data;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\n\nnamespace Sheng.Winform.Controls.SEAdressBar\n{\n    /*\n     * 加用户控件有几个原因\n     * 1.如果不加用户控件，从ToolStrip继承下来的控件，要么Dock，如果不Dock，不能调整宽度\n     * 2.没有边框，不能设置边框\n     */\n\n    public partial class ShengAddressBar : UserControl\n    {\n        public override Color BackColor\n        {\n            get\n            {\n                return base.BackColor;\n            }\n            set\n            {\n                base.BackColor = value;\n                this.addressBarStrip.BackColor = value;\n            }\n        }\n\n        public ToolStripRenderer Renderer\n        {\n            get { return this.addressBarStrip.Renderer; }\n            set\n            {\n                this.addressBarStrip.Renderer = value;\n\n                //这样写没用的，或者说不保险，因为designer.cs里会生成一个默认的...\n                //如果下拉菜单的绘制没有设置，一起设置成相同的Renderer\n                //if (DropDownRenderer == null)\n                //    DropDownRenderer = value;\n            }\n        }\n\n        public ToolStripRenderer DropDownRenderer\n        {\n            get { return this.addressBarStrip.DropDownRenderer; }\n            set { this.addressBarStrip.DropDownRenderer = value; }\n        }\n\n        public IShengAddressNode CurrentNode\n        {\n            get { return addressBarStrip.CurrentNode; ; }\n            set { addressBarStrip.CurrentNode = value; }\n        }\n\n        public ShengAddressBar()\n        {\n            InitializeComponent();\n        }\n\n        public void InitializeRoot(IShengAddressNode rootNode)\n        {\n            addressBarStrip.InitializeRoot(rootNode);\n        }\n\n        public void SetAddress(string path)\n        {\n            addressBarStrip.SetAddress(path);\n        }\n\n        public void SetAddress(IShengAddressNode addressNode)\n        {\n            addressBarStrip.SetAddress(addressNode);\n        }\n\n        public void UpdateNode()\n        {\n            addressBarStrip.UpdateNode();\n        }\n\n        public event ShengAddressBarStrip.SelectionChanged SelectionChange\n        {\n            add { addressBarStrip.SelectionChange += value; }\n            remove { addressBarStrip.SelectionChange -= value; }\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengAdressBar/ShengAddressBar.resx",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <metadata name=\"addressBarStrip.TrayLocation\" type=\"System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\">\n    <value>17, 17</value>\n  </metadata>\n</root>"
  },
  {
    "path": "Sheng.Winform.Controls/ShengAdressBar/ShengAddressBarButton.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Drawing;\n\nnamespace Sheng.Winform.Controls\n{\n    class ShengAddressBarButton : ToolStripButton\n    {\n        public IShengAddressNode AddressNode\n        {\n            get;\n            set;\n        }\n\n        /// <summary>\n        /// 所关联的向下箭头\n        /// </summary>\n        public ShengAddressBarDropDownButton DropDownButton\n        {\n            get;\n            set;\n        }\n\n        public ShengAddressBarButton(string text, Image image, EventHandler onClick)\n            : base(text, image, onClick)\n        {\n\n        }\n\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengAdressBar/ShengAddressBarDropDown.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.ComponentModel;\n\nnamespace Sheng.Winform.Controls\n{\n    [ToolboxItem(false)]\n    public class ShengAddressBarDropDown : ToolStripDropDownMenu\n    {\n        public IShengAddressNode AddressNode\n        {\n            get;\n            set;\n        }\n    }\n}"
  },
  {
    "path": "Sheng.Winform.Controls/ShengAdressBar/ShengAddressBarDropDownButton.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Drawing;\n\nnamespace Sheng.Winform.Controls\n{\n    /// <summary>\n    /// 向下箭头\n    /// </summary>\n    public class ShengAddressBarDropDownButton : ToolStripDropDownButton\n    {\n        public ShengAddressBarDropDownButton()\n            : base()\n        {\n\n        }\n\n        public ShengAddressBarDropDownButton(string text)\n            : base(text)\n        {\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengAdressBar/ShengAddressBarDropDownItem.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Drawing;\n\nnamespace Sheng.Winform.Controls\n{\n    /// <summary>\n    /// 下拉菜单中的项目\n    /// </summary>\n    class ShengAddressBarDropDownItem : ToolStripMenuItem\n    {\n        private IShengAddressNode _addressNode;\n        public IShengAddressNode AddressNode\n        {\n            get { return _addressNode; }\n            set { _addressNode = value; }\n        }\n\n        public ShengAddressBarDropDownItem(string text, Image image, EventHandler onClick) :\n            base(text, image, onClick)\n        {\n\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengAdressBar/ShengAddressBarStrip.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Drawing;\nusing System.ComponentModel;\n\nnamespace Sheng.Winform.Controls\n{\n    /*\n     * 在使用前一定要先初始化根节点\n     * 然后如果设置当前路径的话，就设置一个由唯一ID组成的Path\n     * 然后此方法内部解释这个Path。\n     * 原先是设置一个IAddressNode对象，再根据Parent向上加载\n     * 这样的坏处是会创建很多新的对象浪费资源，改成由根节点解释路径好些\n     */\n\n    [ToolboxItem(false)]\n    public class ShengAddressBarStrip : ToolStrip\n    {\n        #region 公开事件\n\n        /// <summary>\n        /// Delegate for handling when a new node is selected\n        /// </summary>\n        /// <param name=\"sender\">Sender of this event</param>\n        /// <param name=\"nca\">Event Arguments</param>\n        public delegate void SelectionChanged(object sender, NodeChangedArgs e);\n\n        /// <summary>\n        /// Delegate for handling a node double click event.\n        /// </summary>\n        /// <param name=\"sender\">Sender of this event</param>\n        /// <param name=\"nca\">Event arguments</param>\n        public delegate void NodeDoubleClicked(object sender, NodeChangedArgs e);\n\n        /// <summary>\n        /// Stores the callback function for when the selected node changes\n        /// </summary>\n        public event SelectionChanged SelectionChange = null;\n\n        /// <summary>\n        /// Stores the callback function for when the selected node changes\n        /// </summary>\n        public event NodeDoubleClicked NodeDoubleClick = null;\n\n        #endregion\n\n        #region 私有成员\n\n        /// <summary>\n        /// Stores the root node.\n        /// </summary>\n        private IShengAddressNode _rootNode = null;\n\n        /// <summary>\n        /// Node contains the currently selected node (e.g. previous node)\n        /// </summary>\n        private IShengAddressNode _currentNode = null;\n\n        /// <summary>\n        /// Stores the default font for this control\n        /// </summary>\n        private Font _baseFont = null;\n\n        /// <summary>\n        /// Holds the font style that is used when an item is selected\n        /// </summary>\n        private FontStyle _selectedStyle = FontStyle.Bold;\n\n        /// <summary>\n        /// Drop down menu that contains the overflow menu\n        /// </summary>\n        ShengAddressBarDropDownButton _overflowButton = new ShengAddressBarDropDownButton(\"<<\")\n        {\n            ShowDropDownArrow = false\n        };\n\n        ShengAddressBarDropDown _overflowDropDown = new ShengAddressBarDropDown();\n\n        /// <summary>\n        /// 当前显示在地址栏中的Button集合\n        /// </summary>\n        List<ShengAddressBarButton> _buttonList = new List<ShengAddressBarButton>();\n\n        #endregion\n\n        #region 公开属性\n\n        ///// <summary>\n        ///// Gets/Sets the font style for when a node is selected\n        ///// </summary>\n        //public FontStyle SelectedStyle\n        //{\n        //    get { return this._selectedStyle; }\n        //    set { this._selectedStyle = value; }\n        //}\n\n        /// <summary>\n        /// Gets/Sets the currently selected node. Validates upon set and updates the bar\n        /// </summary>\n        public IShengAddressNode CurrentNode\n        {\n            get { return this._currentNode; }\n            set\n            {\n                this._currentNode = value;\n                ResetBar();\n\n                //fire the change event\n                if (SelectionChange != null)\n                {\n                    NodeChangedArgs nca = new NodeChangedArgs(_currentNode.UniqueID);\n                    SelectionChange(this, nca);\n                }\n            }\n        }\n\n        /// <summary>\n        /// Gets/Sets the root node. Upon setting the root node, it resets the hierarchy.\n        /// </summary>\n        public IShengAddressNode RootNode\n        {\n            get { return this._rootNode; }\n            set { InitializeRoot(value); }\n        }\n\n        private ToolStripRenderer _dropDownRenderer;\n        /// <summary>\n        /// 下拉菜单的绘制功能\n        /// </summary>\n        public ToolStripRenderer DropDownRenderer\n        {\n            get { return _dropDownRenderer; }\n            set { _dropDownRenderer = value; }\n        }\n\n        #endregion\n\n        #region 构造\n\n        /// <summary>\n        /// Base contructor for the AddressBarExt Control.\n        /// </summary>\n        public ShengAddressBarStrip()\n        {\n            //get the basic font\n            this._baseFont = this.Font;\n\n            //_overflowButton.DropDown.MaximumSize = new Size(1000, 400);\n            _overflowDropDown.MaximumSize = new Size(1000, 400);\n            _overflowButton.DropDown = _overflowDropDown;\n\n            this.RenderMode = ToolStripRenderMode.System;\n            this.GripStyle = ToolStripGripStyle.Hidden;\n        }\n\n        #endregion\n\n        #region 私有方法\n\n        private ShengAddressBarDropDown GetButtonDropDown(IShengAddressNode addressNode)\n        {\n            ShengAddressBarDropDown dropDown = new ShengAddressBarDropDown();\n\n            if (this.DropDownRenderer != null)\n            {\n                dropDown.Renderer = this.DropDownRenderer;\n            }\n\n            dropDown.LayoutStyle = ToolStripLayoutStyle.Table;\n            dropDown.MaximumSize = new Size(1000, 400);\n            dropDown.Opening += new CancelEventHandler(DropDown_Opening);\n\n            /*\n             * This is the primary bottleneck for this app, creating all the necessary drop-down menu items.\n             * \n             * To optimize performance of this control, this is the main area that needs tuning.\n             */\n\n            IShengAddressNode curNode = null;\n            for (int i = 0; i < addressNode.Children.Length; i++)\n            {\n                curNode = (IShengAddressNode)addressNode.Children.GetValue(i);\n\n                ShengAddressBarDropDownItem tsb = null;\n\n                tsb = new ShengAddressBarDropDownItem(curNode.DisplayName, curNode.Icon, NodeButtonClicked);\n\n                tsb.AddressNode = curNode;\n\n                tsb.Overflow = ToolStripItemOverflow.AsNeeded;\n\n                dropDown.Items.Add(tsb); //THIS IS THE BIGGEST BOTTLENECK. LOTS OF TIME SPENT IN/CALLING THIS METHOD!\n            }\n\n            addressNode.DropDownMenu = dropDown;\n\n            dropDown.LayoutStyle = ToolStripLayoutStyle.Table;\n            dropDown.MaximumSize = new Size(1000, 400);\n\n            dropDown.AddressNode = addressNode;\n\n            //不起作用\n            dropDown.MouseWheel += new MouseEventHandler(ScrollDropDownMenu);\n            dropDown.MouseEnter += new EventHandler(GiveToolStripDropDownMenuFocus);\n\n            return dropDown;\n        }\n\n        /// <summary>\n        /// 创建指定地址栏项的子级（如果需要）\n        /// </summary>\n        /// <param name=\"button\"></param>\n        private void BuildChildItem(ShengAddressBarButton button)\n        {\n            IShengAddressNode addressNode = button.AddressNode;\n\n            ShengAddressBarDropDownButton dropDownButton = null;\n            //SEAddressBarDropDown dropDown = null;\n\n            if (addressNode.Children != null && addressNode.Children.Length > 0)\n            {\n                dropDownButton = new ShengAddressBarDropDownButton(String.Empty);\n                button.DropDownButton = dropDownButton;\n\n                //check if we have any tag data (we cache already built drop down items in the node TAG data.\n                if (addressNode.DropDownMenu == null)\n                {\n                    addressNode.DropDownMenu = GetButtonDropDown(addressNode);\n                }\n                else\n                {\n                    if (addressNode.DropDownMenu.GetType() == typeof(ShengAddressBarDropDown))\n                    {\n                        //dropDown = (SEAddressBarDropDown)addressNode.DropDownMenu;\n\n                        foreach (ShengAddressBarDropDownItem tsmi in addressNode.DropDownMenu.Items)\n                        {\n                            if (tsmi.Font.Style != _baseFont.Style)\n                                tsmi.Font = _baseFont;\n                        }\n                    }\n                }\n\n                dropDownButton.DropDown = addressNode.DropDownMenu;\n                dropDownButton.DisplayStyle = ToolStripItemDisplayStyle.None;\n                dropDownButton.ImageAlign = ContentAlignment.MiddleCenter;\n\n            }\n        }\n\n        /// <summary>\n        /// 添加一个地址栏项\n        /// </summary>\n        /// <param name=\"button\"></param>\n        /// <param name=\"position\"></param>\n        private void AddAddressBarButton(ShengAddressBarButton button, ButtonPosition position)\n        {\n            //如果当前显示了最左下拉菜单，就需要直接加在最左下拉菜单下\n            //如果直接加左边，可能整个地址条是够显示的，就造成这一项出现在最左下拉前面\n            //并且如果直接加在最左下拉下面，就不用去管是否还有子级了，因为不需要显示那个向下箭头了\n            if (this.Items.Contains(_overflowButton))\n            {\n                ShengAddressBarDropDownItem dropDownItem = new ShengAddressBarDropDownItem(button.Text, button.Image, NodeButtonClicked);\n                dropDownItem.AddressNode = button.AddressNode;\n                //_overflowButton.DropDown.Items.Add(dropDownItem);\n                _overflowDropDown.Items.Add(dropDownItem);\n            }\n            else\n            {\n                //处理子级，如果需要，需要显示一个向下箭头\n                BuildChildItem(button);\n\n                if (position == ButtonPosition.Behind)\n                {\n                    this.Items.Add(button);\n                    if (button.DropDownButton != null)\n                        this.Items.Add(button.DropDownButton);\n\n                    _buttonList.Add(button);\n                }\n                else\n                {\n                    this.Items.Insert(0, button);\n                    if (button.DropDownButton != null)\n                        this.Items.Insert(1, button.DropDownButton);\n\n                    _buttonList.Insert(0, button);\n                }\n            }\n        }\n\n        /// <summary>\n        /// 根据IAddressNode地址栏对象，创建并添加一个地址栏按钮\n        /// </summary>\n        /// <param name=\"node\">The node to base the item on</param>\n        /// <returns>Built SEAddressBarDropDownItem. Returns Null if method failed</returns>\n        private void AddToolStripItemUpdate(IShengAddressNode node, ButtonPosition position)\n        {\n            ShengAddressBarButton tsButton = null;\n\n            node.CreateChildNodes();\n\n            tsButton = new ShengAddressBarButton(node.DisplayName, node.Icon, NodeButtonClicked);\n\n            tsButton.AddressNode = node;\n            tsButton.ImageAlign = ContentAlignment.MiddleCenter;\n            tsButton.DoubleClickEnabled = true;\n            tsButton.DoubleClick += new EventHandler(NodeDoubleClickHandler);\n\n            AddAddressBarButton(tsButton, position);\n\n            if (IsManyNodes())\n            {\n                CreateOverflowDropDown();\n            }\n        }\n\n        /// <summary>\n        /// 刷新（重新加载）整个地址栏\n        /// </summary>\n        private void ResetBar()\n        {\n            _buttonList.Clear();\n\n            this.Items.Clear();\n\n            //check we have a valid root\n            if (_currentNode == null && _rootNode == null)\n                return;\n\n            //update the current node, if it doesn't exist\n            if (_currentNode == null)\n                _currentNode = _rootNode;\n\n            IShengAddressNode tempNode = _currentNode;\n\n            //从当前节点向上逐级添加\n            //while (tempNode.Parent != null)\n            while (tempNode != null)\n            {\n                AddToolStripItemUpdate(tempNode, ButtonPosition.Front);\n\n                if (tempNode.Parent == null)\n                    _rootNode = tempNode;\n\n                tempNode = tempNode.Parent;\n            }\n\n            //添加根节点\n            //if (_rootNode != null && _rootNode.UniqueID != tempNode.UniqueID)\n            //    AddToolStripItemUpdate(_rootNode, ButtonPosition.Front);\n        }\n\n        private string AdjustTextForDisplay(string text, int colWidth, Font font)\n        {\n            // Calculate the dimensions of the text with the current font\n            SizeF textSize = TextRenderer.MeasureText(text, font);\n            // Compare the size with the column's width \n            if (textSize.Width > colWidth)\n            {\n                // Get the exceeding pixels \n                int delta = (int)(textSize.Width - colWidth);\n\n                // Calculate the average width of the characters (approx)\n                int avgCharWidth = (int)(textSize.Width / text.Length);\n\n                // Calculate the number of chars to trim to stay in the fixed width (approx)\n                int chrToTrim = (int)(delta / avgCharWidth);\n\n                // Get the proper substring + the ellipsis\n                // Trim 2 more chars (approx) to make room for the ellipsis\n                if (text.Length - (chrToTrim + 2) <= 0)\n                    return String.Empty;\n\n                string rawText = text.Substring(0, text.Length - (chrToTrim + 2)) + \"\";\n\n                // Format to add a tooltip\n                string fmt = \"{1}\";\n                return String.Format(fmt, text, rawText);\n            }\n            return text;\n        }\n\n        /// <summary>\n        /// 创建最左下拉菜单\n        /// </summary>\n        private void CreateOverflowDropDown()\n        {\n            //在最左边添加下拉菜单\n            if (this.Items.Contains(_overflowButton) == false)\n            {\n                this.Items.Insert(0, _overflowButton);\n                _overflowButton.OwnerChanged += new EventHandler(OverflowDestroyed);\n\n                if (this.DropDownRenderer != null)\n                {\n                    _overflowDropDown.Renderer = this.DropDownRenderer;\n                }\n            }\n            /*\n             * 把第一项移到前下拉里，然后测试是否还是不够显示，如果还是不够\n             * 再次把第一项移到前下拉里，如此反复\n             * 但有一点，需判断第一项是否就是当前项，如果就是当前项，则表示是当前项显示文本太长\n             * 所以不够显示，需要截断当前项的显示文本\n             */\n\n            _overflowDropDown.Items.Clear();\n\n            while (true)\n            {\n                ShengAddressBarButton frontButton = _buttonList[0];\n\n                //如果当前节点已经是最右边的节点了\n                if (_currentNode == frontButton.AddressNode)\n                {\n                    //计算可以显示的宽度\n                    int itemWidth = 0;\n                    foreach (ToolStripItem item in frontButton.Owner.Items)\n                    {\n                        if (item == frontButton)\n                            continue;\n\n                        itemWidth += item.Width;\n                    }\n                    itemWidth = frontButton.Owner.Width - itemWidth - 40;\n\n                    frontButton.Text = AdjustTextForDisplay(frontButton.Text, itemWidth, frontButton.Font);\n                    break;\n\n\n                    ////通过截断显示字符串的方式以让它能显示得下\n                    ////简单起见，直接截一半，暂时不去测量文本了，截完以后需继续判断，不行再截一半，直到截到最后个字符\n                    //if (frontButton.Text.Length <= 1)\n                    //{\n                    //    break;\n                    //}\n                    //else\n                    //{\n                    //    frontButton.Text = frontButton.Text.Substring(0, frontButton.Text.Length / 2) + \"...\";\n                    //    if (IsManyNodes())\n                    //    {\n                    //        CreateOverflowDropDown();\n                    //    }\n                    //    break;\n                    //}\n                }\n                else\n                {\n                    ShengAddressBarDropDownItem dropDownItem = null;\n                    dropDownItem = new ShengAddressBarDropDownItem(frontButton.Text, frontButton.Image, NodeButtonClicked);\n                    dropDownItem.AddressNode = frontButton.AddressNode;\n\n                    //把靠左边的第一个项移入最左下拉菜单的顶部\n                    _overflowDropDown.Items.Insert(0, dropDownItem);\n\n                    this.Items.Remove(frontButton);\n                    if (frontButton.DropDownButton != null)\n                        this.Items.Remove(frontButton.DropDownButton);\n\n                    _buttonList.Remove(frontButton);\n                }\n\n                if (IsManyNodes() == false)\n                {\n                    break;\n                }\n            }\n        }\n\n        /// <summary>\n        /// 测试是否有过多的地址栏对象导致地址栏不够显示了\n        /// </summary>\n        /// <returns>Boolean indicating </returns>\n        private bool IsManyNodes()\n        {\n            //check if the last item has overflowed\n            if (this.Items.Count == 0)\n                return false;\n\n            return this.Items[this.Items.Count - 1].IsOnOverflow;\n        }\n\n        #endregion\n\n        #region 公开方法\n\n        /// <summary>\n        /// 初始化根节点\n        /// </summary>\n        /// <param name=\"rootNode\"></param>\n        public void InitializeRoot(IShengAddressNode rootNode)\n        {\n            //remove all items\n            this.Items.Clear();\n            this._rootNode = null;\n\n            if (rootNode != null)\n            {\n                //create the root node\n                this._rootNode = rootNode.Clone();\n\n                //force update the node\n                this._rootNode.CreateChildNodes();\n\n                //set the current node to be the root\n                this._currentNode = this._rootNode;\n\n                //update the address bar\n                ResetBar();\n            }\n        }\n\n        /// <summary>\n        /// 通过这种方式设置路径的前提是有（初始化过）根节点\n        /// </summary>\n        /// <param name=\"path\"></param>\n        public void SetAddress(string path)\n        {\n            if (_rootNode == null)\n                return;\n\n            if (String.IsNullOrEmpty(path))\n            {\n                _currentNode = null;\n                ResetBar();\n                return;\n            }\n\n            //解释path找到当前节点，然后调用RestBar方法就可以了\n            string[] pathArray = path.Split('/');\n            _currentNode =  _rootNode;\n            for (int i = 0; i < pathArray.Length; i++)\n            {\n\n                foreach (IShengAddressNode node in _currentNode.Children)\n                {\n                    if (node.UniqueID == pathArray[i])\n                    {\n                        _currentNode = node;\n                        break;\n                    }\n                }\n            }\n            ResetBar();\n        }\n\n        public void SetAddress(IShengAddressNode addressNode)\n        {\n            _currentNode = addressNode;\n            ResetBar();\n        }\n\n        public void UpdateNode()\n        {\n            foreach (ShengAddressBarButton button in _buttonList)\n            {\n                button.AddressNode.UpdateChildNodes();\n\n                if (button.AddressNode.Children != null && button.AddressNode.Children.Length > 0)\n                    button.AddressNode.DropDownMenu = GetButtonDropDown(button.AddressNode);\n\n                if (button.DropDownButton != null)\n                    button.DropDownButton.DropDown = button.AddressNode.DropDownMenu;\n            }\n        }\n\n        #endregion\n\n        #region 事件处理\n\n        private void DropDown_Opening(object sender, CancelEventArgs e)\n        {\n            ShengAddressBarDropDown dropDown = sender as ShengAddressBarDropDown;\n            //dropDown.Left = dropDown.Left - 20;\n\n            #region 把当前选中项加粗\n\n            IShengAddressNode nextAddressNode = null;\n            for (int i = 0; i < _buttonList.Count; i++)\n            {\n                //如果是当前点击的向下箭头\n                if (_buttonList[i].DropDownButton != null && _buttonList[i].DropDownButton.DropDown == dropDown)\n                {\n                    //拿出当前点的地址栏按钮向下箭头的下一个地址栏项目\n                    //如果为空，则表示当前点的是最右边的了，那就不去匹配了，也没得匹配\n                    if ((i + 1) < _buttonList.Count)\n                    {\n                        nextAddressNode = _buttonList[i + 1].AddressNode;\n                        break;\n                    }\n                }\n            }\n\n            if (nextAddressNode != null)\n            {\n                foreach (ShengAddressBarDropDownItem item in dropDown.Items)\n                {\n                    //在使用SetAddress逆向初始化节点时\n                    //会出现item.AddressNode 和 nextAddressNode不是一个对象的情况\n                    //所以需要UniqueID来判断\n                    if (item.AddressNode.UniqueID.Equals(nextAddressNode.UniqueID))\n                    {\n                        item.Font = new Font(item.Font, this._selectedStyle);\n                        break;\n                    }\n                }\n            }\n\n            #endregion\n        }\n\n        /// <summary>\n        /// Method to handle when a child has been selected from a node\n        /// </summary>\n        /// <param name=\"sender\">Sender of this Event</param>\n        /// <param name=\"e\">Event Arguments</param>\n        private void NodeButtonClicked(Object sender, EventArgs e)\n        {\n            if (sender.GetType() == typeof(ShengAddressBarDropDownItem) || sender.GetType() == typeof(ShengAddressBarButton))\n            {\n                IShengAddressNode addressNode;\n\n                if (sender.GetType() == typeof(ShengAddressBarDropDownItem))\n                {\n                    ShengAddressBarDropDownItem tsb = (ShengAddressBarDropDownItem)sender;\n                    addressNode = tsb.AddressNode;\n                }\n                else\n                {\n                    ShengAddressBarButton tsb = (ShengAddressBarButton)sender;\n                    addressNode = tsb.AddressNode;\n                }\n\n                //set the current node\n                _currentNode = addressNode;\n\n                //cxs\n                //用不着整个都重新加载，在当前最后一个Item后面加上点的这个就行了\n                //但是要额外考虑点击的是哪个下拉按钮，如果是中间的，还是要整个刷\n                ResetBar();\n                //if (sender.GetType().Equals(typeof(SEAddressBarButton)))\n                //{\n                //    UpdateBar();\n                //}\n                //else\n                //{\n                //    AddToolStripItemUpdate(ref _currentNode,ButtonPosition.Behind);\n                //}\n\n                //if the selection changed event is handled\n                if (SelectionChange != null)\n                {\n                    NodeChangedArgs args = new NodeChangedArgs(_currentNode.UniqueID);\n                    SelectionChange(this, args);\n                }\n\n                return;\n            }\n        }\n\n        /// <summary>\n        /// Method to handle when a mode is double clicked\n        /// </summary>\n        /// <param name=\"sender\">Sender of this event</param>\n        /// <param name=\"e\">Event arguments</param>\n        private void NodeDoubleClickHandler(Object sender, EventArgs e)\n        {\n            //check we are handlign the double click event\n            if (NodeDoubleClick != null && sender.GetType() == typeof(ShengAddressBarButton))\n            {\n                //get the node from the tag\n                _currentNode = ((ShengAddressBarDropDownItem)sender).AddressNode;\n\n                //create the node changed event arguments\n                NodeChangedArgs nca = new NodeChangedArgs(_currentNode.UniqueID);\n\n                //fire the event\n                NodeDoubleClick(this, nca);\n            }\n        }\n\n        /// <summary>\n        /// Handles when the overflow menu should be entirely destroyed\n        /// </summary>\n        /// <param name=\"sender\">Sender of this Event</param>\n        /// <param name=\"e\">Event arguments</param>\n        private void OverflowDestroyed(Object sender, EventArgs e)\n        {\n            //check we have the right type\n            if (sender.GetType() == typeof(ShengAddressBarDropDownButton))\n            {\n                //get the button as the right type\n                ShengAddressBarDropDownButton tsddb = (ShengAddressBarDropDownButton)sender;\n\n                //if the button is no longer visible\n                if (tsddb.Visible == false)\n                {\n                    //clear all items from the overflow\n                    //this._overflowButton.DropDown.Items.Clear();\n                    this._overflowDropDown.Items.Clear();\n                }\n            }\n        }\n\n        /// <summary>\n        /// Method handler using the middle mouse wheel to scroll the drop down menus\n        /// </summary>\n        /// <param name=\"sender\">Sender of this event</param>\n        /// <param name=\"e\">Event arguments</param>\n        private void ScrollDropDownMenu(Object sender, MouseEventArgs e)\n        {\n            //if we have the right type\n            if (sender.GetType() == typeof(ToolStripDropDownMenu))\n            {\n                //This doesn't work :(\n\n                Point prev = ((ToolStripDropDownMenu)sender).AutoScrollOffset;\n                prev.Y += (e.Delta);\n                ((ToolStripDropDownMenu)sender).AutoScrollOffset = prev;\n\n            }\n        }\n\n        /// <summary>\n        /// Method that puts focus onto a given ToolStripDropDownMenu\n        /// </summary>\n        /// <param name=\"sender\">Sender of this event</param>\n        /// <param name=\"e\">Event Arguments</param>\n        private void GiveToolStripDropDownMenuFocus(Object sender, EventArgs e)\n        {\n            if (sender.GetType() == typeof(ToolStripDropDownMenu))\n            {\n                //focus on the item\n                ((ToolStripDropDownMenu)sender).Focus();\n            }\n        }\n\n        protected override void OnSizeChanged(EventArgs e)\n        {\n            base.OnSizeChanged(e);\n\n            ResetBar();\n\n            if (IsManyNodes())\n            {\n                CreateOverflowDropDown();\n            }\n        }\n\n        #endregion\n\n        #region NodeChangedArgs\n\n        /// <summary>\n        /// Custom Event Arguments for when a node has been changed\n        /// </summary>\n        public class NodeChangedArgs : EventArgs\n        {\n            #region Class Variables\n\n            /// <summary>\n            /// Stores the Unique ID of the newly opened node\n            /// </summary>\n            private string _uniqueId = null;\n\n            #endregion\n\n            #region Properties\n\n            /// <summary>\n            /// Gets the UniqueID from the newly opened node\n            /// </summary>\n            public string UniqueID\n            {\n                get { return this._uniqueId; }\n            }\n\n            #endregion\n\n            #region Constructor\n\n            /// <summary>\n            /// Base constructor for when a node selection is changed\n            /// </summary>\n            /// <param name=\"uniqueId\">Unique Identifier for this node. Controled by IAddressNode implementation used.</param>\n            public NodeChangedArgs(string uniqueId)\n            {\n                //set the values for the args\n                this._uniqueId = uniqueId;\n            }\n\n            #endregion\n        }\n\n        #endregion\n\n        #region Enum\n\n        /// <summary>\n        /// 地址按钮的位置\n        /// </summary>\n        private enum ButtonPosition\n        {\n            /// <summary>\n            /// 前\n            /// </summary>\n            Front = 0,\n            /// <summary>\n            /// 后\n            /// </summary>\n            Behind = 1\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengAdressBar/ShengFileSystemNode.cs",
    "content": "﻿using System;\nusing System.Drawing;\nusing System.IO;\nusing System.Runtime.InteropServices;\nusing System.Text.RegularExpressions;\n\nnamespace Sheng.Winform.Controls\n{\n    /// <summary>\n    /// 提供一个表示文件夹结构的IAddressNode的默认实现\n    /// </summary>\n    public class ShengFileSystemNode : IShengAddressNode\n    {\n        #region Class Variables\n\n        /// <summary>\n        /// Stores the parent node to this node\n        /// </summary>\n        private IShengAddressNode parent = null;\n\n        /// <summary>\n        /// Stores the display name of this Node\n        /// </summary>\n        private String szDisplayName = null;\n\n        /// <summary>\n        /// Stores the full path to this node (Unique ID)\n        /// </summary>\n        private String fullPath = null;\n\n        /// <summary>\n        /// Stores the Icon for this node\n        /// </summary>\n        private Icon icon = null;\n\n        /// <summary>\n        /// Stores the child nodes\n        /// </summary>\n        private IShengAddressNode[] children = null;\n\n        /// <summary>\n        /// Stores user defined data for this node\n        /// </summary>\n        private ShengAddressBarDropDown _dropDownMenu = null;\n\n        #endregion\n\n        #region Properties\n\n        /// <summary>\n        /// Gets/Sets the parent node to this node\n        /// </summary>\n        public IShengAddressNode Parent\n        {\n            get { return this.parent; }\n            set { this.parent = value; }\n        }\n\n        /// <summary>\n        /// Gets/Sets the Display name of this node\n        /// </summary>\n        public String DisplayName\n        {\n            get { return this.szDisplayName; }\n            set { this.szDisplayName = value; }\n        }\n\n        /// <summary>\n        /// Gets the Icon that represents this node type.\n        /// </summary>\n        public Bitmap Icon\n        {\n            get { return this.icon.ToBitmap(); }\n        }\n\n        /// <summary>\n        /// Returns the Unique Id for this node\n        /// </summary>\n        public string UniqueID\n        {\n            get { return this.fullPath; }\n        }\n\n        /// <summary>\n        /// Gets/Sets user defined data for this object\n        /// </summary>\n        public ShengAddressBarDropDown DropDownMenu\n        {\n            get { return this._dropDownMenu; }\n            set { this._dropDownMenu = value; }\n        }\n\n        /// <summary>\n        /// Gets the children of this node\n        /// </summary>\n        public IShengAddressNode[] Children\n        {\n            get { return this.children; }\n        }\n\n        #endregion\n\n        #region Constructor\n\n        /// <summary>\n        /// Basic Constructor, initializes this node to start at the root of the first drive found on the disk. ONLY USE THIS FOR ROOT NODES\n        /// </summary>\n        public ShengFileSystemNode()\n        {\n            GenerateRootNode();\n        }\n\n        /// <summary>\n        /// Creates a File System node with a given path\n        /// </summary>\n        /// <param name=\"path\">Path that this node represents</param>\n        /// <param name=\"depth\">Integer represnting how deep in the hierarchy this node is</param>\n        public ShengFileSystemNode(string path, ShengFileSystemNode parent)\n        {\n            //fill in the relevant details\n            fullPath = path;\n            this.parent = parent;\n\n            //get the icon\n            GenerateNodeDisplayDetails();\n        }\n\n        #endregion\n\n        #region Destructor\n\n        ~ShengFileSystemNode()\n        {\n            if (children != null)\n            {\n                for (int i = 0; i < this.children.Length; i++)\n                    this.children.SetValue(null, i);\n\n                this.children = null;\n            }\n\n            if (icon != null)\n                this.icon.Dispose();\n\n            this.icon = null;\n        }\n\n        #endregion\n\n        #region Node Update\n\n        /// <summary>\n        /// Updates the contents of this node.\n        /// </summary>\n        public void CreateChildNodes()\n        {\n            //if we have not allocated our children yet\n            if (children == null)\n            {\n                InitChild();\n            }\n        }\n\n        public void UpdateChildNodes()\n        {\n            InitChild();\n        }\n\n        private void InitChild()\n        {\n            try\n            {\n                //get sub-folders for this folder\n                Array subFolders = System.IO.Directory.GetDirectories(fullPath);\n\n                //create space for the children\n                children = new ShengFileSystemNode[subFolders.Length];\n\n                for (int i = 0; i < subFolders.Length; i++)\n                {\n                    //create the child value\n                    children[i] = new ShengFileSystemNode(subFolders.GetValue(i).ToString(), this);\n                }\n            }\n            /**\n           * This is just a sample, so has bad error handling ;)\n           * \n           **/\n            catch (System.Exception ioex)\n            {\n                //write a message to stderr\n                System.Console.Error.WriteLine(ioex.Message);\n            }\n        }\n\n        #endregion\n\n        #region General\n\n        /// <summary>\n        /// Returns an individual child node, based on a given unique ID. NOT IMPLEMENTED.\n        /// </summary>\n        /// <param name=\"uniqueID\">Unique Object to identify the child</param>\n        /// <param name=\"recursive\">Indicates whether we should recursively search child nodes</param>\n        /// <returns>Returns a child node. Returns null if method fails.</returns>\n        public IShengAddressNode GetChild(string uniqueID)\n        {\n            //sample version doesn't support recursive search ;)\n            //if (recursive)\n            //    return null;\n\n            foreach (IShengAddressNode node in this.children)\n            {\n                if (node.UniqueID.ToString() == uniqueID.ToString())\n                    return node;\n            }\n\n            return null;\n        }\n\n        /// <summary>\n        /// Creates a clone of this node\n        /// </summary>\n        /// <returns>Cloned Node</returns>\n        public IShengAddressNode Clone()\n        {\n            if (this.fullPath.Length == 0)\n                return new ShengFileSystemNode();\n            else\n                return new ShengFileSystemNode(this.fullPath, (ShengFileSystemNode)this.parent);\n        }\n\n        /// <summary>\n        /// Populates this node as a root node representing \"My Computer\"\n        /// </summary>\n        private void GenerateRootNode()\n        {\n            // if we have data, we can't become a root node.\n            if (children != null)\n                return;\n\n            //get the display name of the first logical drive\n            fullPath = \"\";\n            this.parent = null;\n\n            //get our drives\n            string[] drives = Environment.GetLogicalDrives();\n\n            //create space for the children\n            children = new ShengFileSystemNode[drives.Length];\n\n            for (int i = 0; i < drives.Length; i++)\n            {\n                //create the child value\n                children[i] = new ShengFileSystemNode(drives[i], this);\n            }\n\n            //get the icon\n            GenerateNodeDisplayDetails();\n        }\n\n        /// <summary>\n        /// Sets the icon for the given path\n        /// </summary>\n        private void GenerateNodeDisplayDetails()\n        {\n            //if the path exists\n            if (icon == null)\n            {\n                //needed to get a handle to our icon\n                SHFILEINFO shinfo = new SHFILEINFO();\n\n                //If we have an actual path, then we pass a string\n                if (fullPath.Length > 0)\n                {\n                    //get the icon and display name\n                    Win32.SHGetFileInfo(fullPath, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), Win32.SHGFI_ICON | Win32.SHGFI_SMALLICON | Win32.SHGFI_DISPLAYNAME);\n                }\n                else\n                {\n                    //If we get a blank path we assume the root of our file system, so we get a pidl to My \"Computer\"\n\n                    //Get a pidl to my computer\n                    IntPtr tempPidl = System.IntPtr.Zero;\n                    Win32.SHGetSpecialFolderLocation(0, Win32.CSIDL_DRIVES, ref tempPidl);\n\n                    //get the icon and display name\n                    Win32.SHGetFileInfo(tempPidl, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), Win32.SHGFI_PIDL | Win32.SHGFI_ICON | Win32.SHGFI_SMALLICON | Win32.SHGFI_DISPLAYNAME);\n\n                    //free our pidl\n                    Marshal.FreeCoTaskMem(tempPidl);\n                }\n\n                //create the managed icon\n                this.icon = (Icon)System.Drawing.Icon.FromHandle(shinfo.hIcon).Clone();\n                this.szDisplayName = shinfo.szDisplayName;\n\n                //dispose of the old icon\n                Win32.DestroyIcon(shinfo.hIcon);\n            }\n        }\n\n        #endregion\n\n        #region Win32 Interop for Icons\n\n        [StructLayout(LayoutKind.Sequential)]\n        public struct SHFILEINFO\n        {\n            public IntPtr hIcon;\n            public int iIcon;\n            public uint dwAttributes;\n            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]\n            public string szDisplayName;\n            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]\n            public string szTypeName;\n        };\n\n        class Win32\n        {\n            public const uint SHGFI_ICON = 0x100;\n            public const uint SHGFI_SMALLICON = 0x1;\n            public const uint SHGFI_DISPLAYNAME = 0x200;\n            public const uint SHGFI_PIDL = 0x8;\n\n\n            public const uint CSIDL_DRIVES = 0x11;\n\n\n            [DllImport(\"shell32.dll\")]\n            public static extern IntPtr SHGetFileInfo(string pszPath,\n                                        uint dwFileAttributes,\n                                        ref SHFILEINFO psfi,\n                                        uint cbSizeFileInfo,\n                                        uint uFlags);\n\n            [DllImport(\"shell32.dll\")]\n            public static extern IntPtr SHGetFileInfo(IntPtr pidl,\n                                        uint dwFileAttributes,\n                                        ref SHFILEINFO psfi,\n                                        uint cbSizeFileInfo,\n                                        uint uFlags);\n\n            [DllImport(\"shell32.dll\")]\n            public static extern int SHGetSpecialFolderLocation(int hwndOwner,\n                                        uint nSpecialFolder,\n                                        ref IntPtr pidl);\n\n            [DllImport(\"user32.dll\")]\n            public static extern bool DestroyIcon(IntPtr hIcon);\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengAdvComboBox.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Drawing;\nusing System.ComponentModel;\n\nnamespace Sheng.Winform.Controls\n{\n    public class ShengAdvComboBox:Control\n    {\n        /// <summary>\n        /// (文本框里显示的)值发生了改变\n        /// </summary>\n        public event EventHandler OnValueChange;\n\n        private TextBox txtBack;\n        private TextBox txtValue;\n        private Button btnComboButton;\n        private Form formDropDown;\n\n        private ShengAdvComboBoxDropdownBase dropUserControl;\n        public ShengAdvComboBoxDropdownBase DropUserControl\n        {\n            get\n            {\n                return this.dropUserControl;\n            }\n            set\n            {\n                this.dropUserControl = value;\n            }\n        }\n\n        public ShengAdvComboBox()\n        {\n\n            SetStyle(ControlStyles.DoubleBuffer, true);\n            SetStyle(ControlStyles.ResizeRedraw, true);\n\n            this.txtValue = new TextBox();\n            this.txtValue.TabStop = false;\n            this.txtValue.BorderStyle = BorderStyle.None;\n            this.txtValue.ReadOnly = true;\n            this.txtValue.BackColor = SystemColors.Window;\n            this.txtValue.TextChanged += new EventHandler(txtValue_TextChanged);\n\n            this.btnComboButton = new Button();\n            this.btnComboButton.Text = \"\";\n            this.btnComboButton.Click += new EventHandler(ToggleTreeView);\n            //this.btnComboButton.FlatStyle = FlatStyle.Flat;\n\n            this.formDropDown = new Form();\n            this.formDropDown.FormBorderStyle = FormBorderStyle.None;\n            this.formDropDown.BringToFront();\n            this.formDropDown.StartPosition = FormStartPosition.Manual;\n            this.formDropDown.ShowInTaskbar = false;\n            this.formDropDown.BackColor = SystemColors.Control;\n\n            this.formDropDown.Deactivate += new EventHandler(frmTreeView_Deactivate);\n\n            //放一个文本框做背景用于统一外观\n            txtBack = new TextBox();\n            txtBack.TabStop = false;\n            this.Controls.Add(txtBack);\n\n            this.Controls.AddRange(new Control[] { btnComboButton, txtValue });\n        }\n\n        /// <summary>\n        /// 是否显示文本框的边框\n        /// </summary>\n        public bool TextBoxBorder\n        {\n            set\n            {\n                this.txtBack.Visible = value;\n            }\n        }\n\n        public Color TextForeColor\n        {\n            set { this.txtValue.ForeColor = value; }\n        }\n\n        public Color TextBackColor\n        {\n            set { this.txtValue.BackColor = value; }\n        }\n\n        /// <summary> \n        /// 文本只读属性 \n        /// </summary> \n        public bool TextReadOnly\n        {\n            set { this.txtValue.ReadOnly = value; }\n        }\n\n        /// <summary> \n        /// 显示的文本 \n        /// </summary> \n        public override string Text\n        {\n            get { return this.txtValue.Text; }\n            set { this.txtValue.Text = value; }\n        }\n\n        private object value;\n        /// <summary>\n        /// 选择的项的值\n        /// </summary>\n        public object Value\n        {\n            get { return this.value; }\n            set { this.value = value; }\n        }\n\n        /// <summary>\n        /// 弹出窗体被隐藏\n        /// </summary>\n        /// <param name=\"sender\"></param>\n        /// <param name=\"e\"></param>\n        private void frmTreeView_Deactivate(object sender, EventArgs e)\n        {\n            if (!this.btnComboButton.RectangleToScreen(this.btnComboButton.ClientRectangle).Contains(Cursor.Position))\n                this.formDropDown.Hide();\n\n            this.txtValue.Text = this.DropUserControl.GetText();\n            this.Value = this.DropUserControl.GetValue();\n        }\n\n        /// <summary> \n        /// 点击三角按钮，显示Form \n        /// </summary> \n        /// <param name=\"sender\"></param> \n        /// <param name=\"e\"></param> \n        private void ToggleTreeView(object sender, EventArgs e)\n        {\n            if (!this.formDropDown.Visible)\n            {\n                if (this.formDropDown.Controls.Count == 0)\n                {\n                    this.DropUserControl.Dock = DockStyle.Fill;\n                    //this.formDropDown.Width = this.Width;\n                    this.formDropDown.Width = this.DropUserControl.Width;\n                    this.formDropDown.Height = this.DropUserControl.Height;\n\n                    this.formDropDown.Controls.Add(this.DropUserControl);\n\n                    //this.formDropDown.Owner = this.FindForm();\n                }\n\n                Rectangle CBRect = this.RectangleToScreen(this.ClientRectangle);\n                this.formDropDown.BackColor = Color.White;\n\n                //this.formDropDown.Location = new Point(CBRect.X, CBRect.Y + this.txtBack.Height);\n                //设置弹出窗口的位置,默认显示在ComboBox的下部,但是如果下部不足以显示,调整位置到ComboBox的上方\n                Point formLocation = new Point(CBRect.X, CBRect.Y + this.txtBack.Height);\n                if (formLocation.Y + formDropDown.Height > Screen.PrimaryScreen.WorkingArea.Height)\n                {\n                    formLocation = new Point(CBRect.X, CBRect.Y - formDropDown.Height);\n                }\n                this.formDropDown.Location = formLocation;\n\n\n                this.DropUserControl.SetText(this.txtValue.Text);\n\n                this.formDropDown.Show();\n                this.formDropDown.BringToFront();\n            }\n            else\n            {\n                this.formDropDown.Hide();\n            }\n        }\n\n        private void TreeViewComboBox_Load(object sender, EventArgs e)\n        {\n            ReLayout();\n        }\n\n        protected override void OnSizeChanged(EventArgs e)\n        {\n            base.OnSizeChanged(e);\n\n            if (txtBack == null)\n            {\n                return;\n            }\n\n            ReLayout();\n        }\n\n        private void ReLayout()\n        {\n            this.txtBack.Size = this.Size;\n            this.txtBack.SendToBack();\n\n            this.btnComboButton.Size = new Size(20, this.txtBack.ClientRectangle.Height + 2);\n            this.btnComboButton.Location = new Point(this.Width - this.btnComboButton.Width - 1, 1);\n\n            this.txtValue.Height = this.txtBack.ClientRectangle.Height;\n            this.txtValue.Width = this.txtBack.Width - this.btnComboButton.Width - 8;\n            this.txtValue.Location = new Point(2, 3);\n        }\n\n        private void txtValue_TextChanged(object sender, EventArgs e)\n        {\n            if (this.OnValueChange != null)\n            {\n                OnValueChange(sender, e);\n            }\n        }\n\n        /// <summary>\n        /// 下拉选项按钮\n        /// 但是绘制的按钮没有xp样式的问题一时不好解决\n        /// </summary>\n        private class ComboButton : Button\n        {\n\n            ButtonState state;\n\n            /// <summary> \n            /// \n            /// </summary> \n            public ComboButton()\n            {\n                this.SetStyle(ControlStyles.UserPaint, true);\n                this.SetStyle(ControlStyles.DoubleBuffer, true);\n                this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);\n\n            }\n            /// <summary> \n            /// \n            /// </summary> \n            /// <param name=\"e\"></param> \n            protected override void OnMouseDown(MouseEventArgs e)\n            {\n                state = ButtonState.Pushed;\n                base.OnMouseDown(e);\n            }\n\n            /// <summary> \n            /// \n            /// </summary> \n            /// <param name=\"e\"></param> \n            protected override void OnMouseUp(MouseEventArgs e)\n            {\n                state = ButtonState.Normal;\n                base.OnMouseUp(e);\n            }\n\n            /// <summary> \n            /// \n            /// </summary> \n            /// <param name=\"e\"></param> \n            protected override void OnPaint(PaintEventArgs e)\n            {\n                base.OnPaint(e);\n                ControlPaint.DrawComboButton(e.Graphics, 0, 0, this.Width, this.Height, state);\n            }\n        }\n\n    }\n    \n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengAdvComboBoxDropdownBase.Designer.cs",
    "content": "﻿namespace Sheng.Winform.Controls\n{\n    partial class ShengAdvComboBoxDropdownBase\n    {\n        /// <summary> \n        /// 必需的设计器变量。\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary> \n        /// 清理所有正在使用的资源。\n        /// </summary>\n        /// <param name=\"disposing\">如果应释放托管资源，为 true；否则为 false。</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region 组件设计器生成的代码\n\n        /// <summary> \n        /// 设计器支持所需的方法 - 不要\n        /// 使用代码编辑器修改此方法的内容。\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.SuspendLayout();\n            // \n            // SEAdvComboBoxDropdownBase\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.Name = \"SEAdvComboBoxDropdownBase\";\n            this.Size = new System.Drawing.Size(127, 84);\n            this.ResumeLayout(false);\n\n        }\n\n        #endregion\n\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengAdvComboBoxDropdownBase.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Drawing;\nusing System.Data;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\n\nnamespace Sheng.Winform.Controls\n{\n    [ToolboxItem(false)]\n    public partial class ShengAdvComboBoxDropdownBase : UserControl\n    {\n        public ShengAdvComboBoxDropdownBase()\n        {\n            InitializeComponent();\n        }\n\n        public virtual string GetText()\n        {\n            return String.Empty; \n        }\n\n        public virtual object GetValue()\n        {\n            return null;\n        }\n\n        public virtual void SetText(object value)\n        {\n\n        }\n\n        protected void Close()\n        {\n            this.FindForm().Hide();\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengAdvComboBoxDropdownBase.resx",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n</root>"
  },
  {
    "path": "Sheng.Winform.Controls/ShengAdvLabel.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Drawing;\nusing System.Drawing.Drawing2D;\nusing System.ComponentModel;\n\nnamespace Sheng.Winform.Controls\n{\n    //TODO:拿到SEAdvLabel里面去\n    public enum FillStyle\n    {\n        Solid = 0,\n        LinearGradient = 1\n    }\n\n    \n    public class ShengAdvLabel : Control\n    {\n        // Specify the text is wrapped.\n        private TextFormatFlags textFlags;\n\n        public override string Text\n        {\n            get\n            {\n                return base.Text;\n            }\n            set\n            {\n                base.Text = value;\n                this.Refresh();\n            }\n        }\n\n        private Brush fillBrush;\n        /// <summary>\n        /// 填充对象\n        /// </summary>\n        public Brush FillBrush\n        {\n            get\n            {\n                return this.fillBrush;\n            }\n            set\n            {\n                this.fillBrush = value;\n                this.Invalidate();\n            }\n        }\n\n        private Pen borderPen;\n        /// <summary>\n        /// 边框画笔\n        /// </summary>\n        public Pen BorderPen\n        {\n            get\n            {\n                return this.borderPen;\n            }\n            set\n            {\n                this.borderPen = value;\n                this.Invalidate();\n            }\n        }\n\n        private FillStyle fillStyle = FillStyle.Solid;\n        /// <summary>\n        /// 填充样式\n        /// 纯色或渐变\n        /// </summary>\n        public FillStyle FillStyle\n        {\n            get\n            {\n                return this.fillStyle;\n            }\n            set\n            {\n                this.fillStyle = value;\n\n                InitBrush();\n            }\n        }\n\n        private LinearGradientMode fillMode;\n        /// <summary>\n        /// 填充模式\n        /// 如果是渐变,从四个方向的渐变中选一种\n        /// </summary>\n        public LinearGradientMode FillMode\n        {\n            get\n            {\n                return this.fillMode;\n            }\n            set\n            {\n                this.fillMode = value;\n\n                InitBrush();\n            }\n        }\n\n        private bool showBorder = false;\n        /// <summary>\n        /// 是否显示边框\n        /// </summary>\n        public bool ShowBorder\n        {\n            get\n            {\n                return this.showBorder;\n            }\n            set\n            {\n                this.showBorder = value;\n\n                InitBrush();\n                InitPen();\n\n                this.Invalidate();\n            }\n        }\n\n        private Color borderColor = Color.Black;\n        /// <summary>\n        /// 边框颜色\n        /// </summary>\n        public Color BorderColor\n        {\n            get\n            {\n                return this.borderColor;\n            }\n            set\n            {\n                this.borderColor = value;\n\n                InitPen();\n            }\n        }\n\n        private Color fillColorStart;\n        /// <summary>\n        /// 填充色(开始)\n        /// 如果是单色填充,使用此颜色\n        /// </summary>\n        public Color FillColorStart\n        {\n            get\n            {\n                if (this.fillColorStart == null)\n                {\n                    this.fillColorStart = this.Parent.BackColor;\n                }\n                return this.fillColorStart;\n            }\n            set\n            {\n                this.fillColorStart = value;\n\n                InitBrush();\n            }\n        }\n\n        private Color fillColorEnd;\n        /// <summary>\n        /// 填充色结束\n        /// </summary>\n        public Color FillColorEnd\n        {\n            get\n            {\n                if (this.fillColorEnd == null)\n                {\n                    this.fillColorEnd = this.Parent.BackColor;\n                }\n\n                return this.fillColorEnd;\n            }\n            set\n            {\n                this.fillColorEnd = value;\n\n                InitBrush();\n            }\n        }\n\n        private bool textVerticalCenter;\n        /// <summary>\n        /// 文本是否垂直居中\n        /// </summary>\n        public bool TextVerticalCenter\n        {\n            get\n            {\n                return this.textVerticalCenter;\n            }\n            set\n            {\n                this.textVerticalCenter = value;\n\n                //if (value)\n                //{\n                //    textFlags = (textFlags | TextFormatFlags.VerticalCenter);\n                //}\n                //else\n                //{\n                //    textFlags = (textFlags & TextFormatFlags.VerticalCenter);\n                //}\n\n                this.Invalidate();\n            }\n        }\n\n        private bool textHorizontalCenter;\n        /// <summary>\n        /// 文本是否水平居中\n        /// </summary>\n        public bool TextHorizontalCenter\n        {\n            get\n            {\n                return this.textHorizontalCenter;\n            }\n            set\n            {\n                this.textHorizontalCenter = value;\n\n                //if (value)\n                //{\n                //    textFlags = (textFlags | TextFormatFlags.HorizontalCenter);\n                //}\n                //else\n                //{\n                //    textFlags = (textFlags & TextFormatFlags.HorizontalCenter);\n                //}\n\n                this.Invalidate();\n            }\n        }\n\n        private bool singleLine;\n        /// <summary>\n        /// 文本是否保持单行显示\n        /// </summary>\n        public bool SingleLine\n        {\n            get\n            {\n                return this.singleLine;\n            }\n            set\n            {\n                this.singleLine = value;\n\n                if (this.SingleLine)\n                {\n                    textFlags = (textFlags & TextFormatFlags.WordBreak);\n                    textFlags = (textFlags | TextFormatFlags.SingleLine | TextFormatFlags.WordEllipsis);\n                }\n                else\n                {\n                    textFlags = (textFlags & TextFormatFlags.SingleLine & TextFormatFlags.WordEllipsis);\n                    textFlags = (textFlags | TextFormatFlags.WordBreak);\n                }\n\n                this.Invalidate();\n            }\n        }\n\n        /// <summary>\n        /// 填充Rectangle\n        /// </summary>\n        private Rectangle FillRectangle\n        {\n            get\n            {\n                if (this.ClientRectangle == new Rectangle())\n                {\n                    return new Rectangle(0, 0, 1, 1);\n                }\n\n                Rectangle rect;\n\n                if (this.ShowBorder)\n                {\n                    rect = new Rectangle(1, 1, this.ClientRectangle.Width - 1, this.ClientRectangle.Height - 1);\n                }\n                else\n                {\n                    rect = this.ClientRectangle;\n                }\n\n                if (rect.Width == 0)\n                {\n                    rect.Width++;\n                }\n                if (rect.Height == 0)\n                {\n                    rect.Height++;\n                }\n\n                return rect;\n            }\n        }\n\n        /// <summary>\n        /// 绘制Rectangle\n        /// </summary>\n        private Rectangle DrawRectangle\n        {\n            get\n            {\n                if (this.ClientRectangle == new Rectangle())\n                {\n                    return new Rectangle(0, 0, 1, 1);\n                }\n\n                return new Rectangle(0, 0, this.ClientRectangle.Width - 1, this.ClientRectangle.Height - 1);\n            }\n        }\n\n        /// <summary>\n        /// 绘制文本的Rectangle\n        /// </summary>\n        private Rectangle DrawStringRectangle\n        {\n            get\n            {\n                if (this.ClientRectangle == new Rectangle())\n                {\n                    return new Rectangle(0, 0, 1, 1);\n                }\n\n                Rectangle drawStringRectangle;\n\n                if (this.ShowBorder)\n                {\n                    drawStringRectangle = new Rectangle(1, 1, this.ClientRectangle.Width - 2, this.ClientRectangle.Height - 2);\n                }\n                else\n                {\n                    drawStringRectangle = this.ClientRectangle;\n                }\n\n                drawStringRectangle.X = drawStringRectangle.X + this.Padding.Left;\n                drawStringRectangle.Y = drawStringRectangle.Y + this.Padding.Top;\n                drawStringRectangle.Width = drawStringRectangle.Width - this.Padding.Left - this.Padding.Right;\n                drawStringRectangle.Height = drawStringRectangle.Height - this.Padding.Top - this.Padding.Bottom;\n\n                return drawStringRectangle;\n            }\n        }\n\n        /// <summary>\n        /// 构造\n        /// </summary>\n        public ShengAdvLabel()\n        {\n\n            EnableDoubleBuffering();\n\n            this.FillBrush = new SolidBrush(this.FillColorStart);\n            this.BorderPen = new Pen(this.BorderColor);\n\n\n            this.SingleLine = false;\n            this.TextHorizontalCenter = false;\n            this.TextVerticalCenter = true;\n        }\n\n        /// <summary>\n        /// 初始化Brush\n        /// </summary>\n        private void InitBrush()\n        {\n            if (this.FillStyle == FillStyle.Solid)\n            {\n                this.FillBrush = new SolidBrush(this.FillColorStart);\n            }\n            else\n            {\n                this.FillBrush = new LinearGradientBrush(this.FillRectangle, this.FillColorStart, this.FillColorEnd, this.FillMode);\n            }\n        }\n\n        /// <summary>\n        /// 初始化Pen\n        /// </summary>\n        private void InitPen()\n        {\n            if (this.ShowBorder)\n            {\n                this.BorderPen = new Pen(this.BorderColor);\n            }\n        }\n\n        /// <summary>\n        /// 开启双倍缓冲\n        /// </summary>\n        private void EnableDoubleBuffering()\n        {\n            // Set the value of the double-buffering style bits to true.\n            this.SetStyle(ControlStyles.DoubleBuffer |\n               ControlStyles.UserPaint |\n               ControlStyles.AllPaintingInWmPaint,\n               true);\n            this.UpdateStyles();\n        }\n\n        /// <summary>\n        /// 绘制控件\n        /// </summary>\n        /// <param name=\"e\"></param>\n        protected override void OnPaint(PaintEventArgs e)\n        {\n            //base.OnPaint(e);\n\n            e.Graphics.FillRectangle(this.FillBrush, this.FillRectangle);\n\n            if (this.ShowBorder)\n            {\n                e.Graphics.DrawRectangle(this.BorderPen, this.DrawRectangle);\n            }\n\n            textFlags = textFlags & TextFormatFlags.WordBreak;\n\n            if (this.TextHorizontalCenter)\n            {\n                textFlags = (textFlags | TextFormatFlags.HorizontalCenter);\n            }\n\n            if (this.TextVerticalCenter)\n            {\n                textFlags = (textFlags | TextFormatFlags.VerticalCenter);\n            }\n\n            if (this.SingleLine)\n            {\n                textFlags = (textFlags | TextFormatFlags.SingleLine);\n            }\n\n            TextRenderer.DrawText(e.Graphics, this.Text, this.Font, this.DrawStringRectangle, this.ForeColor, textFlags);\n        }\n\n        /// <summary>\n        /// 大小改变\n        /// </summary>\n        /// <param name=\"e\"></param>\n        protected override void OnResize(EventArgs e)\n        {\n\n            base.OnResize(e);\n\n            if (this.Height <= 0 || this.Width <= 0)\n            {\n                return;\n            }\n\n            InitBrush();\n            InitPen();\n\n            this.Invalidate();\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengAreoMainMenuStrip.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Drawing;\nusing System.Drawing.Drawing2D;\nusing System.ComponentModel;\nusing System.Drawing.Text;\nusing Sheng.Winform.Controls.Kernal;\n\nnamespace Sheng.Winform.Controls\n{\n    \n    public class ShengAreoMainMenuStrip : MenuStrip\n    {\n        public ShengAreoMainMenuStrip()\n        {\n         \n\n            this.Renderer = new SEAreoMainMenuStripRenderer();\n        }\n\n        protected override void OnPaintBackground(PaintEventArgs e)\n        {\n            //base.OnPaintBackground(e);\n\n            //表示画弧线时的矩形尺寸，弧线的圆心是矩形的正中\n            int curveSize = 8;\n\n            //绘图面的Y轴原点（与顶部的距离）\n            int heightSpace = 0;\n            //绘图面的X轴原点（与左侧的距离）\n            int widthSpace = 3;\n\n            if (this.Items.Count > 0)\n            {\n                widthSpace = this.Items[0].Padding.Left;\n            }\n\n            int xStart = -1;\n\n            //总高度\n            int height = this.Height;\n            //总宽度\n            int width = this.Width ;\n            //项的高度\n            int itemHeight = this.MaxItemSize.Height;\n            //项的总宽度\n            int itemWidth = 100;\n\n            if (this.Items.Count > 0)\n            {\n                ToolStripItem lastItem = this.Items[this.Items.Count - 1];\n                itemWidth = lastItem.Bounds.Location.X + lastItem.Width + lastItem.Padding.Right;\n            }\n\n            Graphics g = e.Graphics;\n\n            g.CompositingQuality = CompositingQuality.HighQuality;\n            g.SmoothingMode = SmoothingMode.HighQuality;\n\n            if (EnvironmentHelper.SupportAreo && EnvironmentHelper.DwmIsCompositionEnabled)\n            {\n                g.Clear(Color.Transparent);\n            }\n            else\n            {\n                g.Clear(SystemColors.Control);\n            }\n\n            GraphicsPath path = new GraphicsPath();\n\n            //curveSize / 2：表示弧线实际显示出来的大小，因为画半弧，实现上只占矩形大小的一半\n            //curveSize：表示画弧线用的矩形的大小，在定位矩形左上角坐标时，需要考虑到如果弧线在矩形的下半部分，Y坐标的设置要考虑到\n\n            path.AddArc(new Rectangle(widthSpace, heightSpace, curveSize, curveSize), 270, -90); //左上角的圆弧\n            path.AddLine(widthSpace, curveSize, widthSpace, itemHeight - curveSize / 2);//项左边线条\n            path.AddArc(new Rectangle(widthSpace - curveSize, itemHeight - curveSize, curveSize, curveSize), 0, 90);  //项左边竖线与横线的交接弧线\n            path.AddLine(widthSpace - curveSize / 2, itemHeight, xStart, itemHeight); //项左边的横线条\n            path.AddLine(xStart, itemHeight, xStart, height); //左侧线条\n            path.AddLine(xStart, height, width, height);//底部线条\n            path.AddLine(width, height, width, itemHeight); //右侧线条\n            path.AddLine(width, itemHeight, itemWidth + curveSize / 2, itemHeight); //项右边的横线条\n            path.AddArc(new Rectangle(itemWidth, itemHeight - curveSize, curveSize, curveSize), 90, 90);  //项右边竖线与横线的交接弧线\n            path.AddLine(itemWidth, itemHeight - curveSize / 2, itemWidth, curveSize); //项右边的竖线条\n            path.AddArc(new Rectangle(itemWidth - curveSize, heightSpace, curveSize, curveSize), 0, -90); //右上角的圆弧\n            path.AddLine(itemWidth - curveSize, heightSpace, curveSize / 2 + widthSpace, heightSpace);//项顶部线条\n\n            using (LinearGradientBrush brush = new LinearGradientBrush(\n                new Rectangle(widthSpace, heightSpace, width, height), Color.White, Color.White, LinearGradientMode.Vertical))\n            {\n                g.FillPath(brush, path);\n            }\n            using (Pen pen = new Pen(Color.FromArgb(66, 92, 119)))\n            {\n                g.DrawPath(pen, path);\n            }\n        }\n    }\n\n    public class SEAreoMainMenuStripRenderer : SEToolStripRender\n    {\n        StringFormat stringFormat = new StringFormat();\n\n        public SEAreoMainMenuStripRenderer()\n        {\n            stringFormat.HotkeyPrefix = HotkeyPrefix.Show;\n\n            //_mainMenu.Panels.BackgroundAngle = 0;\n            this.Panels.ContentPanelTop = SystemColors.Control;\n            //_mainMenu.Panels.ContentPanelBottom = Color.Yellow;\n\n            this.AlterColor = true;\n            this.OverrideColor = Color.Black;\n        }\n\n        /// <summary>\n        /// 自己画项目上的文字\n        /// 因为areo透明色的问题，系统原本画的文本会被透明\n        /// 只处理顶层菜单项即可\n        /// </summary>\n        /// <param name=\"e\"></param>\n        protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e)\n        {\n            if (e.Item.IsOnDropDown)\n            {\n                base.OnRenderItemText(e);\n            }\n            else\n            {\n\n                if (_smoothText)\n                    e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;\n\n                if (_overrideText)\n                    e.TextColor = _overrideColor;\n\n                Color colorMenuHighLight = ControlPaint.LightLight(SystemColors.MenuHighlight);\n\n                #region 定义\n\n                //显示图像的位置X坐标\n                int imageLocationX = 4;\n\n                //显示图像的位置Y坐标\n                int imageLocationY = 2;\n\n                //显示文本的位置X坐标\n                int textLocationX = 6;\n\n                //显示文本的位置Y坐标\n                //int textLocationY = 4;\n                int textLocationY = (int)Math.Round((e.Item.ContentRectangle.Height - e.Graphics.MeasureString(e.Item.Text, e.Item.Font).Height) / 2);\n\n                //文本填充\n                SolidBrush textBrush = new SolidBrush(e.TextColor);\n\n                //显示图像的Rectangle\n                Rectangle imageRect = new Rectangle(imageLocationX, imageLocationY, 16, 16);\n           \n                #endregion\n\n                #region 绘制图像和文本\n\n                //绘制图像和文本\n                if (e.Item.Image != null)\n                {\n                    if (e.Item.DisplayStyle == ToolStripItemDisplayStyle.ImageAndText)\n                    {\n                        if (e.Item.Enabled)\n                            e.Graphics.DrawImage(e.Item.Image, imageRect);\n                        else\n                            ControlPaint.DrawImageDisabled(e.Graphics, e.Item.Image, imageRect.X, imageRect.Y, e.Item.BackColor);\n\n                        e.Graphics.DrawString(e.Item.Text, e.Item.Font, textBrush, new Point(textLocationX + 14, textLocationY), stringFormat);\n                    }\n                    else if (e.Item.DisplayStyle == ToolStripItemDisplayStyle.Image)\n                    {\n                        if (e.Item.Enabled)\n                            e.Graphics.DrawImage(e.Item.Image, imageRect);\n                        else\n                            ControlPaint.DrawImageDisabled(e.Graphics, e.Item.Image, imageRect.X, imageRect.Y, e.Item.BackColor);\n                    }\n                    else if (e.Item.DisplayStyle == ToolStripItemDisplayStyle.Text)\n                    {\n                        e.Graphics.DrawString(e.Item.Text, e.Item.Font, textBrush, new Point(textLocationX, textLocationY), stringFormat);\n                    }\n                }\n                else\n                {\n                    e.Graphics.DrawString(e.Item.Text, e.Item.Font, textBrush, new Point(textLocationX, textLocationY), stringFormat);\n                }\n\n                #endregion\n\n                textBrush.Dispose();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengColorChooseComboBox.Designer.cs",
    "content": "﻿namespace Sheng.Winform.Controls\n{\n    partial class ShengColorChooseComboBox\n    {\n        /// <summary> \n        /// 必需的设计器变量。\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary> \n        /// 清理所有正在使用的资源。\n        /// </summary>\n        /// <param name=\"disposing\">如果应释放托管资源，为 true；否则为 false。</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region 组件设计器生成的代码\n\n        /// <summary> \n        /// 设计器支持所需的方法 - 不要\n        /// 使用代码编辑器修改此方法的内容。\n        /// </summary>\n        private void InitializeComponent()\n        {\n            components = new System.ComponentModel.Container();\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengColorChooseComboBox.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Drawing;\nusing System.Data;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Reflection;\nusing Sheng.Winform.Controls.Drawing;\n\nnamespace Sheng.Winform.Controls\n{\n\n\n    \n    public partial class ShengColorChooseComboBox : UserControl\n    {\n        private Bitmap showColorBitmap;\n        private Graphics showColorGraphics;\n\n        private TextBox txtBack;\n        private TextBox txtValue;\n        private Button btnComboButton;\n        private PictureBox picColor;\n        private Form formDropDown;\n\n        /// <summary>\n        /// 弹出框的所有者窗体\n        /// 主要是为了弹出框中的ColorDialog服务,可能会造成主窗体失去焦点而不能刷新选择的颜色\n        /// 把IDE主窗体设置过来以解决\n        /// </summary>\n        public Form OwnerForm\n        {\n            get;\n            set;\n        }\n\n        public event EventHandler OnSelectedChange;\n\n        /// <summary>\n        /// 颜色选取框\n        /// </summary>\n        private ShengColorChooseComboBoxDropDown dropUserControl = new ShengColorChooseComboBoxDropDown();\n\n        public ShengColorChooseComboBox()\n        {\n\n            InitializeComponent();\n\n            this.dropUserControl.ColorChooseComboBox = this;\n\n            SetStyle(ControlStyles.DoubleBuffer, true);\n            SetStyle(ControlStyles.ResizeRedraw, true);\n\n            this.txtValue = new TextBox();\n            this.txtValue.BorderStyle = BorderStyle.None;\n            this.txtValue.ReadOnly = true;\n            this.txtValue.BackColor = SystemColors.Window;\n            this.txtValue.ForeColor = SystemColors.ControlText;\n            this.txtValue.TextChanged+=new EventHandler(txtValue_TextChanged);\n\n            this.btnComboButton = new Button();\n            this.btnComboButton.Text = \"\";\n            this.btnComboButton.Click += new EventHandler(ToggleTreeView);\n            //this.btnComboButton.FlatStyle = FlatStyle.Flat;\n\n            this.formDropDown = new Form();\n            this.formDropDown.FormBorderStyle = FormBorderStyle.None;\n            this.formDropDown.BringToFront();\n            this.formDropDown.StartPosition = FormStartPosition.Manual;\n            this.formDropDown.ShowInTaskbar = false;\n            this.formDropDown.BackColor = SystemColors.Control;\n\n            this.formDropDown.Deactivate += new EventHandler(frmTreeView_Deactivate);\n\n            this.picColor = new PictureBox();\n            this.picColor.Width = 24;\n            this.picColor.BackColor = SystemColors.Window;\n\n\n            //放一个文本框做背景用于统一外观\n            this.txtBack = new TextBox();\n            this.txtBack.Enabled = false;\n            this.txtBack.BackColor = SystemColors.Window;\n            this.Controls.Add(txtBack);\n\n            this.Controls.AddRange(new Control[] { picColor, btnComboButton, txtValue });\n        }\n\n        /// <summary>\n        /// 是否显示文本框的边框\n        /// </summary>\n        public bool TextBoxBorder\n        {\n            set\n            {\n                this.txtBack.Visible = value;\n            }\n        }\n\n        public Color TextForeColor\n        {\n            set { this.txtValue.ForeColor = value; }\n        }\n\n        public Color TextBackColor\n        {\n            set { this.txtValue.BackColor = value; }\n        }\n\n        /// <summary> \n        /// 文本只读属性 \n        /// </summary> \n        public bool TextReadOnly\n        {\n            set { this.txtValue.ReadOnly = value; }\n        }\n\n        /// <summary> \n        /// 选择的颜色的显示名\n        /// </summary> \n        public override string Text\n        {\n            get\n            {\n                return this.txtValue.Text;\n            }\n            set\n            {\n                this.txtValue.Text = value;\n            }\n        }\n\n        private string value;\n        /// <summary>\n        /// 选择的颜色的定义值\n        /// </summary>\n        public string Value\n        {\n            get\n            {\n                if (this.value == null)\n                {\n                    return String.Empty;\n                }\n                return this.value;\n            }\n            set\n            {\n                this.value = value;\n                this.dropUserControl.SelectedColorValue = value;\n\n                if (value == null || value == String.Empty)\n                {\n                    this.picColor.Image = null;\n                    this.txtValue.Text = String.Empty;\n                    return;\n                }\n\n                this.Text = value.Split('.')[1];\n\n                this.dropUserControl.SelectedColor = ColorRepresentationHelper.GetColorByValue(value);\n\n                if (showColorBitmap == null)\n                {\n                    showColorBitmap = new Bitmap(this.picColor.Width, this.picColor.Height);\n                    showColorGraphics = Graphics.FromImage(showColorBitmap);\n                }\n\n                showColorGraphics.Clear(this.dropUserControl.SelectedColor);\n                showColorGraphics.DrawRectangle(Pens.Black, 0, 0, this.picColor.Width - 1, this.picColor.Height - 1);\n\n                this.picColor.Image = showColorBitmap;\n            }\n        }\n\n        private void frmTreeView_Deactivate(object sender, EventArgs e)\n        {\n            if (!this.btnComboButton.RectangleToScreen(this.btnComboButton.ClientRectangle).Contains(Cursor.Position))\n            {\n                this.formDropDown.Hide();\n            }\n\n            this.txtValue.Text = this.dropUserControl.SelectedColorName;\n            this.value = this.dropUserControl.SelectedColorValue;\n\n            if (this.dropUserControl.SelectedColorName != null && this.dropUserControl.SelectedColorName != String.Empty)\n            {\n                if (showColorBitmap == null)\n                {\n                    showColorBitmap = new Bitmap(this.picColor.Width, this.picColor.Height);\n                    showColorGraphics = Graphics.FromImage(showColorBitmap);\n                }\n\n                showColorGraphics.Clear(this.dropUserControl.SelectedColor);\n                showColorGraphics.DrawRectangle(Pens.Black, 0, 0, this.picColor.Width - 1, this.picColor.Height - 1);\n\n                this.picColor.Image = showColorBitmap;\n            }\n            else\n            {\n                this.picColor.Image = null;\n            }\n        }\n\n        /// <summary> \n        /// 点击三角按钮，显示Form \n        /// </summary> \n        /// <param name=\"sender\"></param> \n        /// <param name=\"e\"></param> \n        private void ToggleTreeView(object sender, EventArgs e)\n        {\n            if (!this.formDropDown.Visible)\n            {\n                if (this.formDropDown.Controls.Count == 0)\n                {\n                    this.formDropDown.Controls.Add(this.dropUserControl);\n                    this.formDropDown.Size = this.dropUserControl.Size;\n\n                    //this.formDropDown.Owner = this.FindForm();\n                }\n\n                Rectangle CBRect = this.RectangleToScreen(this.ClientRectangle);\n                //this.formDropDown.BackColor = Color.White;\n                //this.formDropDown.Location = new Point(CBRect.X, CBRect.Y + this.txtBack.Height);\n\n                //设置弹出窗口的位置,默认显示在ComboBox的下部,但是如果下部不足以显示,调整位置到ComboBox的上方\n                Point formLocation = new Point(CBRect.X, CBRect.Y + this.txtBack.Height);\n                if (formLocation.Y + formDropDown.Height > Screen.PrimaryScreen.WorkingArea.Height)\n                {\n                    formLocation = new Point(CBRect.X, CBRect.Y - formDropDown.Height);\n                }\n                this.formDropDown.Location = formLocation;\n\n                //this.DropUserControl.SetValue(this.txtValue.Text);\n\n                this.formDropDown.Show();\n                this.dropUserControl.ShowCurrentTabPage();\n                this.formDropDown.BringToFront();\n            }\n            else\n            {\n                this.formDropDown.Hide();\n            }\n        }\n\n        private void TreeViewComboBox_Load(object sender, EventArgs e)\n        {\n            ReLayout();\n        }\n\n        protected override void OnSizeChanged(EventArgs e)\n        {\n            base.OnSizeChanged(e);\n\n            if (txtBack == null)\n            {\n                return;\n            }\n\n            ReLayout();\n        }\n\n        private void ReLayout()\n        {\n            this.txtBack.Size = this.Size;\n            this.txtBack.SendToBack();\n\n            this.btnComboButton.Size = new Size(20, this.txtBack.ClientRectangle.Height + 2);\n            this.btnComboButton.Location = new Point(this.Width - this.btnComboButton.Width - 1, 1);\n\n            this.txtValue.Height = this.txtBack.ClientRectangle.Height;\n            this.txtValue.Width = this.txtBack.Width - this.btnComboButton.Width - 36;\n            //this.txtValue.Location = new Point(2, 3);\n            this.txtValue.Location = new Point(30, 4);\n\n            this.picColor.Height = this.txtBack.ClientRectangle.Height;\n            this.picColor.Location = new Point(2, 2);\n        }\n\n        public void SetDropDownFormOwner(bool ownerForm)\n        {\n            if (ownerForm)\n            {\n                if (this.OwnerForm != null)\n                {\n                    this.formDropDown.Owner = this.OwnerForm;\n                }\n                else\n                {\n                    this.formDropDown.Owner = this.FindForm();\n                }\n            }\n            else\n            {\n                this.formDropDown.Owner = null;\n                if (this.OwnerForm != null)\n                {\n                    this.OwnerForm.Select();\n                }\n                else\n                {\n                    this.FindForm().Select();\n                }\n            }\n        }\n\n        private void txtValue_TextChanged(object sender, EventArgs e)\n        {\n            if (this.OnSelectedChange != null)\n            {\n                OnSelectedChange(sender, e);\n            }\n        }\n\n\n        /// <summary>\n        /// 下拉选项按钮\n        /// 但是绘制的按钮没有xp样式的问题一时不好解决\n        /// </summary>\n        private class ComboButton : Button\n        {\n\n            ButtonState state;\n\n            /// <summary> \n            /// \n            /// </summary> \n            public ComboButton()\n            {\n                this.SetStyle(ControlStyles.UserPaint, true);\n                this.SetStyle(ControlStyles.DoubleBuffer, true);\n                this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);\n\n            }\n            /// <summary> \n            /// \n            /// </summary> \n            /// <param name=\"e\"></param> \n            protected override void OnMouseDown(MouseEventArgs e)\n            {\n                state = ButtonState.Pushed;\n                base.OnMouseDown(e);\n            }\n\n            /// <summary> \n            /// \n            /// </summary> \n            /// <param name=\"e\"></param> \n            protected override void OnMouseUp(MouseEventArgs e)\n            {\n                state = ButtonState.Normal;\n                base.OnMouseUp(e);\n            }\n\n            /// <summary> \n            /// \n            /// </summary> \n            /// <param name=\"e\"></param> \n            protected override void OnPaint(PaintEventArgs e)\n            {\n                base.OnPaint(e);\n                ControlPaint.DrawComboButton(e.Graphics, 0, 0, this.Width, this.Height, state);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengColorChooseComboBoxDropDown.Designer.cs",
    "content": "﻿namespace Sheng.Winform.Controls\n{\n    partial class ShengColorChooseComboBoxDropDown\n    {\n        /// <summary> \n        /// 必需的设计器变量。\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary> \n        /// 清理所有正在使用的资源。\n        /// </summary>\n        /// <param name=\"disposing\">如果应释放托管资源，为 true；否则为 false。</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region 组件设计器生成的代码\n\n        /// <summary> \n        /// 设计器支持所需的方法 - 不要\n        /// 使用代码编辑器修改此方法的内容。\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.tabControl1 = new System.Windows.Forms.TabControl();\n            this.tabPageCustom = new System.Windows.Forms.TabPage();\n            this.btnClearColor = new System.Windows.Forms.Button();\n            this.btnChooseColor = new System.Windows.Forms.Button();\n            this.tabPageDefine = new System.Windows.Forms.TabPage();\n            this.dataGridViewDefineColor = new System.Windows.Forms.DataGridView();\n            this.Column1 = new System.Windows.Forms.DataGridViewImageColumn();\n            this.Column2 = new System.Windows.Forms.DataGridViewTextBoxColumn();\n            this.ColumnNameDefineColor = new System.Windows.Forms.DataGridViewTextBoxColumn();\n            this.ColumnValueDefineColor = new System.Windows.Forms.DataGridViewTextBoxColumn();\n            this.tabPageSystem = new System.Windows.Forms.TabPage();\n            this.dataGridViewSystemColors = new System.Windows.Forms.DataGridView();\n            this.dataGridViewImageColumn1 = new System.Windows.Forms.DataGridViewImageColumn();\n            this.ColumnNameSystemColor = new System.Windows.Forms.DataGridViewTextBoxColumn();\n            this.ColumnValueSystemColor = new System.Windows.Forms.DataGridViewTextBoxColumn();\n            this.label1 = new System.Windows.Forms.Label();\n            this.label2 = new System.Windows.Forms.Label();\n            this.picCustomColor = new System.Windows.Forms.PictureBox();\n            this.tabControl1.SuspendLayout();\n            this.tabPageCustom.SuspendLayout();\n            this.tabPageDefine.SuspendLayout();\n            ((System.ComponentModel.ISupportInitialize)(this.dataGridViewDefineColor)).BeginInit();\n            this.tabPageSystem.SuspendLayout();\n            ((System.ComponentModel.ISupportInitialize)(this.dataGridViewSystemColors)).BeginInit();\n            ((System.ComponentModel.ISupportInitialize)(this.picCustomColor)).BeginInit();\n            this.SuspendLayout();\n            // \n            // tabControl1\n            // \n            this.tabControl1.Controls.Add(this.tabPageCustom);\n            this.tabControl1.Controls.Add(this.tabPageDefine);\n            this.tabControl1.Controls.Add(this.tabPageSystem);\n            this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill;\n            this.tabControl1.Location = new System.Drawing.Point(0, 0);\n            this.tabControl1.Name = \"tabControl1\";\n            this.tabControl1.SelectedIndex = 0;\n            this.tabControl1.Size = new System.Drawing.Size(250, 220);\n            this.tabControl1.TabIndex = 1;\n            // \n            // tabPageCustom\n            // \n            this.tabPageCustom.Controls.Add(this.picCustomColor);\n            this.tabPageCustom.Controls.Add(this.label2);\n            this.tabPageCustom.Controls.Add(this.label1);\n            this.tabPageCustom.Controls.Add(this.btnClearColor);\n            this.tabPageCustom.Controls.Add(this.btnChooseColor);\n            this.tabPageCustom.Location = new System.Drawing.Point(4, 21);\n            this.tabPageCustom.Name = \"tabPageCustom\";\n            this.tabPageCustom.Padding = new System.Windows.Forms.Padding(3);\n            this.tabPageCustom.Size = new System.Drawing.Size(242, 195);\n            this.tabPageCustom.TabIndex = 0;\n            this.tabPageCustom.Text = \"自定义\";\n            this.tabPageCustom.UseVisualStyleBackColor = true;\n            // \n            // btnClearColor\n            // \n            this.btnClearColor.Location = new System.Drawing.Point(16, 94);\n            this.btnClearColor.Name = \"btnClearColor\";\n            this.btnClearColor.Size = new System.Drawing.Size(124, 23);\n            this.btnClearColor.TabIndex = 1;\n            this.btnClearColor.Text = \"清除颜色\";\n            this.btnClearColor.UseVisualStyleBackColor = true;\n            this.btnClearColor.Click += new System.EventHandler(this.btnClearColor_Click);\n            // \n            // btnChooseColor\n            // \n            this.btnChooseColor.Location = new System.Drawing.Point(16, 41);\n            this.btnChooseColor.Name = \"btnChooseColor\";\n            this.btnChooseColor.Size = new System.Drawing.Size(124, 23);\n            this.btnChooseColor.TabIndex = 0;\n            this.btnChooseColor.Text = \"选择颜色\";\n            this.btnChooseColor.UseVisualStyleBackColor = true;\n            this.btnChooseColor.Click += new System.EventHandler(this.btnChooseColor_Click);\n            // \n            // tabPageDefine\n            // \n            this.tabPageDefine.Controls.Add(this.dataGridViewDefineColor);\n            this.tabPageDefine.Location = new System.Drawing.Point(4, 21);\n            this.tabPageDefine.Name = \"tabPageDefine\";\n            this.tabPageDefine.Padding = new System.Windows.Forms.Padding(3);\n            this.tabPageDefine.Size = new System.Drawing.Size(242, 195);\n            this.tabPageDefine.TabIndex = 1;\n            this.tabPageDefine.Text = \"预置\";\n            this.tabPageDefine.UseVisualStyleBackColor = true;\n            // \n            // dataGridViewDefineColor\n            // \n            this.dataGridViewDefineColor.AllowUserToAddRows = false;\n            this.dataGridViewDefineColor.AllowUserToDeleteRows = false;\n            this.dataGridViewDefineColor.AllowUserToResizeColumns = false;\n            this.dataGridViewDefineColor.AllowUserToResizeRows = false;\n            this.dataGridViewDefineColor.BackgroundColor = System.Drawing.Color.White;\n            this.dataGridViewDefineColor.BorderStyle = System.Windows.Forms.BorderStyle.None;\n            this.dataGridViewDefineColor.CellBorderStyle = System.Windows.Forms.DataGridViewCellBorderStyle.None;\n            this.dataGridViewDefineColor.ClipboardCopyMode = System.Windows.Forms.DataGridViewClipboardCopyMode.Disable;\n            this.dataGridViewDefineColor.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.DisableResizing;\n            this.dataGridViewDefineColor.ColumnHeadersVisible = false;\n            this.dataGridViewDefineColor.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {\n            this.Column1,\n            this.Column2,\n            this.ColumnNameDefineColor,\n            this.ColumnValueDefineColor});\n            this.dataGridViewDefineColor.Dock = System.Windows.Forms.DockStyle.Fill;\n            this.dataGridViewDefineColor.Location = new System.Drawing.Point(3, 3);\n            this.dataGridViewDefineColor.MultiSelect = false;\n            this.dataGridViewDefineColor.Name = \"dataGridViewDefineColor\";\n            this.dataGridViewDefineColor.ReadOnly = true;\n            this.dataGridViewDefineColor.RowHeadersVisible = false;\n            this.dataGridViewDefineColor.RowTemplate.Height = 19;\n            this.dataGridViewDefineColor.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;\n            this.dataGridViewDefineColor.Size = new System.Drawing.Size(236, 189);\n            this.dataGridViewDefineColor.TabIndex = 0;\n            this.dataGridViewDefineColor.CellMouseClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.dataGridViewWebColor_CellMouseClick);\n            // \n            // Column1\n            // \n            this.Column1.DataPropertyName = \"Icon\";\n            this.Column1.HeaderText = \"Column1\";\n            this.Column1.Name = \"Column1\";\n            this.Column1.ReadOnly = true;\n            this.Column1.Resizable = System.Windows.Forms.DataGridViewTriState.True;\n            this.Column1.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic;\n            this.Column1.Width = 35;\n            // \n            // Column2\n            // \n            this.Column2.DataPropertyName = \"Order\";\n            this.Column2.HeaderText = \"Column2\";\n            this.Column2.Name = \"Column2\";\n            this.Column2.ReadOnly = true;\n            this.Column2.Visible = false;\n            // \n            // ColumnNameDefineColor\n            // \n            this.ColumnNameDefineColor.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;\n            this.ColumnNameDefineColor.DataPropertyName = \"Name\";\n            this.ColumnNameDefineColor.HeaderText = \"ColumnNameDefineColor\";\n            this.ColumnNameDefineColor.Name = \"ColumnNameDefineColor\";\n            this.ColumnNameDefineColor.ReadOnly = true;\n            // \n            // ColumnValueDefineColor\n            // \n            this.ColumnValueDefineColor.DataPropertyName = \"Value\";\n            this.ColumnValueDefineColor.HeaderText = \"ColumnValueDefineColor\";\n            this.ColumnValueDefineColor.Name = \"ColumnValueDefineColor\";\n            this.ColumnValueDefineColor.ReadOnly = true;\n            this.ColumnValueDefineColor.Visible = false;\n            // \n            // tabPageSystem\n            // \n            this.tabPageSystem.Controls.Add(this.dataGridViewSystemColors);\n            this.tabPageSystem.Location = new System.Drawing.Point(4, 21);\n            this.tabPageSystem.Name = \"tabPageSystem\";\n            this.tabPageSystem.Padding = new System.Windows.Forms.Padding(3);\n            this.tabPageSystem.Size = new System.Drawing.Size(242, 195);\n            this.tabPageSystem.TabIndex = 2;\n            this.tabPageSystem.Text = \"系统\";\n            this.tabPageSystem.UseVisualStyleBackColor = true;\n            // \n            // dataGridViewSystemColors\n            // \n            this.dataGridViewSystemColors.AllowUserToAddRows = false;\n            this.dataGridViewSystemColors.AllowUserToDeleteRows = false;\n            this.dataGridViewSystemColors.AllowUserToResizeColumns = false;\n            this.dataGridViewSystemColors.AllowUserToResizeRows = false;\n            this.dataGridViewSystemColors.BackgroundColor = System.Drawing.Color.White;\n            this.dataGridViewSystemColors.BorderStyle = System.Windows.Forms.BorderStyle.None;\n            this.dataGridViewSystemColors.CellBorderStyle = System.Windows.Forms.DataGridViewCellBorderStyle.None;\n            this.dataGridViewSystemColors.ClipboardCopyMode = System.Windows.Forms.DataGridViewClipboardCopyMode.Disable;\n            this.dataGridViewSystemColors.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.DisableResizing;\n            this.dataGridViewSystemColors.ColumnHeadersVisible = false;\n            this.dataGridViewSystemColors.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {\n            this.dataGridViewImageColumn1,\n            this.ColumnNameSystemColor,\n            this.ColumnValueSystemColor});\n            this.dataGridViewSystemColors.Dock = System.Windows.Forms.DockStyle.Fill;\n            this.dataGridViewSystemColors.Location = new System.Drawing.Point(3, 3);\n            this.dataGridViewSystemColors.MultiSelect = false;\n            this.dataGridViewSystemColors.Name = \"dataGridViewSystemColors\";\n            this.dataGridViewSystemColors.ReadOnly = true;\n            this.dataGridViewSystemColors.RowHeadersVisible = false;\n            this.dataGridViewSystemColors.RowTemplate.Height = 19;\n            this.dataGridViewSystemColors.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;\n            this.dataGridViewSystemColors.Size = new System.Drawing.Size(236, 189);\n            this.dataGridViewSystemColors.TabIndex = 1;\n            this.dataGridViewSystemColors.CellMouseClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.dataGridViewSystemColors_CellMouseClick);\n            // \n            // dataGridViewImageColumn1\n            // \n            this.dataGridViewImageColumn1.DataPropertyName = \"Icon\";\n            this.dataGridViewImageColumn1.HeaderText = \"Column1\";\n            this.dataGridViewImageColumn1.Name = \"dataGridViewImageColumn1\";\n            this.dataGridViewImageColumn1.ReadOnly = true;\n            this.dataGridViewImageColumn1.Resizable = System.Windows.Forms.DataGridViewTriState.True;\n            this.dataGridViewImageColumn1.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic;\n            this.dataGridViewImageColumn1.Width = 35;\n            // \n            // ColumnNameSystemColor\n            // \n            this.ColumnNameSystemColor.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;\n            this.ColumnNameSystemColor.DataPropertyName = \"Name\";\n            this.ColumnNameSystemColor.HeaderText = \"ColumnNameSystemColor\";\n            this.ColumnNameSystemColor.Name = \"ColumnNameSystemColor\";\n            this.ColumnNameSystemColor.ReadOnly = true;\n            // \n            // ColumnValueSystemColor\n            // \n            this.ColumnValueSystemColor.DataPropertyName = \"Value\";\n            this.ColumnValueSystemColor.HeaderText = \"ColumnValueSystemColor\";\n            this.ColumnValueSystemColor.Name = \"ColumnValueSystemColor\";\n            this.ColumnValueSystemColor.ReadOnly = true;\n            this.ColumnValueSystemColor.Visible = false;\n            // \n            // label1\n            // \n            this.label1.AutoSize = true;\n            this.label1.Location = new System.Drawing.Point(27, 67);\n            this.label1.Name = \"label1\";\n            this.label1.Size = new System.Drawing.Size(167, 12);\n            this.label1.TabIndex = 2;\n            this.label1.Text = \"使用 Windows 调色板选取颜色\";\n            // \n            // label2\n            // \n            this.label2.AutoSize = true;\n            this.label2.Location = new System.Drawing.Point(27, 120);\n            this.label2.Name = \"label2\";\n            this.label2.Size = new System.Drawing.Size(89, 12);\n            this.label2.TabIndex = 3;\n            this.label2.Text = \"清除选择的颜色\";\n            // \n            // picCustomColor\n            // \n            this.picCustomColor.Location = new System.Drawing.Point(16, 17);\n            this.picCustomColor.Name = \"picCustomColor\";\n            this.picCustomColor.Size = new System.Drawing.Size(25, 18);\n            this.picCustomColor.TabIndex = 4;\n            this.picCustomColor.TabStop = false;\n            // \n            // SEColorChooseComboBoxDropDown\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.Controls.Add(this.tabControl1);\n            this.Name = \"SEColorChooseComboBoxDropDown\";\n            this.Size = new System.Drawing.Size(250, 220);\n            this.Load += new System.EventHandler(this.SEColorChooseComboBoxDropDown_Load);\n            this.tabControl1.ResumeLayout(false);\n            this.tabPageCustom.ResumeLayout(false);\n            this.tabPageCustom.PerformLayout();\n            this.tabPageDefine.ResumeLayout(false);\n            ((System.ComponentModel.ISupportInitialize)(this.dataGridViewDefineColor)).EndInit();\n            this.tabPageSystem.ResumeLayout(false);\n            ((System.ComponentModel.ISupportInitialize)(this.dataGridViewSystemColors)).EndInit();\n            ((System.ComponentModel.ISupportInitialize)(this.picCustomColor)).EndInit();\n            this.ResumeLayout(false);\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.TabControl tabControl1;\n        private System.Windows.Forms.TabPage tabPageCustom;\n        private System.Windows.Forms.Button btnClearColor;\n        private System.Windows.Forms.Button btnChooseColor;\n        private System.Windows.Forms.TabPage tabPageDefine;\n        private System.Windows.Forms.DataGridView dataGridViewDefineColor;\n        private System.Windows.Forms.TabPage tabPageSystem;\n        private System.Windows.Forms.DataGridView dataGridViewSystemColors;\n        private System.Windows.Forms.DataGridViewImageColumn dataGridViewImageColumn1;\n        private System.Windows.Forms.DataGridViewTextBoxColumn ColumnNameSystemColor;\n        private System.Windows.Forms.DataGridViewTextBoxColumn ColumnValueSystemColor;\n        private System.Windows.Forms.DataGridViewImageColumn Column1;\n        private System.Windows.Forms.DataGridViewTextBoxColumn Column2;\n        private System.Windows.Forms.DataGridViewTextBoxColumn ColumnNameDefineColor;\n        private System.Windows.Forms.DataGridViewTextBoxColumn ColumnValueDefineColor;\n        private System.Windows.Forms.Label label2;\n        private System.Windows.Forms.Label label1;\n        private System.Windows.Forms.PictureBox picCustomColor;\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengColorChooseComboBoxDropDown.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Drawing;\nusing System.Data;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Reflection;\nusing Sheng.Winform.Controls.Drawing;\n\nnamespace Sheng.Winform.Controls\n{\n    [ToolboxItem(false)]\n    [LicenseProvider(typeof(ShengColorChooseComboBoxDropDown))]\n    internal partial class ShengColorChooseComboBoxDropDown : UserControl\n    {\n        private Bitmap customColorBitmap;\n        private Graphics customColorGraphics;\n\n        private ColorDialog colorDialog = new ColorDialog();\n\n        private ShengColorChooseComboBox colorChooseComboBox;\n        /// <summary>\n        /// 所在的ComboBox\n        /// </summary>\n        public ShengColorChooseComboBox ColorChooseComboBox\n        {\n            get\n            {\n                return this.colorChooseComboBox;\n            }\n            set\n            {\n                this.colorChooseComboBox = value;\n            }\n        }\n\n        private ChooseColorType selectedType;\n        /// <summary>\n        /// 选择的颜色类型\n        /// </summary>\n        public ChooseColorType SelectedType\n        {\n            get\n            {\n                return selectedType;\n            }\n            set\n            {\n                selectedType = value;\n            }\n        }\n\n        private Color selectedColor;\n        /// <summary>\n        /// 选择的颜色\n        /// </summary>\n        public Color SelectedColor\n        {\n            get\n            {\n                return selectedColor;\n            }\n            set\n            {\n                selectedColor = value;\n            }\n        }\n\n        private string selectedColorValue;\n        /// <summary>\n        /// 选择的颜色的 定义值\n        /// </summary>\n        public string SelectedColorValue\n        {\n            get\n            {\n                return selectedColorValue;\n            }\n            set\n            {\n                selectedColorValue = value;\n\n                if (value != null && value != String.Empty)\n                {\n                    this.SelectedColorName = value.Split('.')[1];\n                }\n                else\n                {\n                    this.SelectedColor = Color.Empty;\n                    this.selectedColorName = String.Empty;\n                }\n            }\n        }\n\n        private string selectedColorName;\n        /// <summary>\n        /// 选择的颜色的显示名\n        /// </summary>\n        public string SelectedColorName\n        {\n            get\n            {\n                return selectedColorName;\n            }\n            set\n            {\n                selectedColorName = value;\n            }\n        }\n\n        public ShengColorChooseComboBoxDropDown()\n        {\n\n            InitializeComponent();\n\n            this.dataGridViewDefineColor.AutoGenerateColumns = false;\n            this.dataGridViewSystemColors.AutoGenerateColumns = false;\n\n            DataTable dtKnownColor = new DataTable();\n            dtKnownColor.Columns.Add(\"Icon\", typeof(Bitmap));\n            dtKnownColor.Columns.Add(\"Name\");\n            dtKnownColor.Columns.Add(\"Value\");\n            dtKnownColor.Columns.Add(\"Order\");\n            dtKnownColor.Columns.Add(\"Order2\");\n\n            Type typeColor = typeof(System.Drawing.Color);\n            foreach (System.Reflection.PropertyInfo p in typeColor.GetProperties(BindingFlags.Static | BindingFlags.Public))\n            {\n                if (p.PropertyType.Equals(typeColor))\n                {\n                    DataRow dr = dtKnownColor.NewRow();\n                    Bitmap ico = new Bitmap(24, 14);\n                    Graphics g = Graphics.FromImage(ico);\n                    g.Clear((Color)p.GetValue(typeColor, null));\n                    g.DrawRectangle(Pens.Black, 0, 0, 23, 13);\n                    dr[\"Icon\"] = ico;\n                    dr[\"Name\"] = p.Name;\n                    dr[\"Value\"] = ((int)ChooseColorType.Define).ToString() +\n                        \".\" + p.Name + \".\" + ((Color)p.GetValue(typeColor, null)).ToArgb().ToString();\n                    dr[\"Order\"] = ((Color)p.GetValue(typeColor, null)).GetHue();\n                    dr[\"Order2\"] = ((Color)p.GetValue(typeColor, null)).GetSaturation();\n\n                    dtKnownColor.Rows.Add(dr);\n                }\n            }\n\n            DataView dvKnownColor = new DataView(dtKnownColor);\n            dvKnownColor.Sort = \"Order ASC,Order2 ASC\";\n            this.dataGridViewDefineColor.DataSource = dvKnownColor;\n\n            DataTable dtSystemColors = new DataTable();\n            dtSystemColors.Columns.Add(\"Icon\", typeof(Bitmap));\n            dtSystemColors.Columns.Add(\"Name\");\n            dtSystemColors.Columns.Add(\"Value\");\n\n\n            Type typeSystemColors = typeof(System.Drawing.SystemColors);\n            foreach (PropertyInfo p in typeSystemColors.GetProperties())\n            {\n                if (p.PropertyType.Equals(typeColor))\n                {\n                    DataRow dr = dtSystemColors.NewRow();\n                    Bitmap ico = new Bitmap(24, 14);\n                    Graphics g = Graphics.FromImage(ico);\n                    g.Clear((Color)p.GetValue(typeSystemColors, null));\n                    g.DrawRectangle(Pens.Black, 0, 0, 23, 13);\n                    dr[\"Icon\"] = ico;\n                    dr[\"Name\"] = p.Name;\n                    dr[\"Value\"] = ((int)ChooseColorType.System).ToString() + \".\" + p.Name;\n\n                    dtSystemColors.Rows.Add(dr);\n                }\n            }\n\n            this.dataGridViewSystemColors.DataSource = dtSystemColors;\n        }\n\n        /// <summary>\n        /// 定位到选中的颜色\n        /// </summary>\n        public void ShowCurrentTabPage()\n        {\n            #region 如果当前有选定颜色设置\n            if (this.SelectedColorValue != null && this.SelectedColorValue != String.Empty)\n            {\n                //定位到选中的颜色\n                ChooseColorType type =\n                   (ChooseColorType)Convert.ToInt32(this.SelectedColorValue.Split('.')[0]);\n\n                switch (type)\n                {\n                    case ChooseColorType.Custom:\n\n                        this.tabControl1.SelectedTab = tabPageCustom;\n                        if (this.customColorBitmap == null)\n                        {\n                            customColorBitmap = new Bitmap(this.picCustomColor.Width, this.picCustomColor.Height);\n                            customColorGraphics = Graphics.FromImage(customColorBitmap);\n                        }\n\n                        customColorGraphics.Clear(Color.FromArgb(Convert.ToInt32(this.SelectedColorValue.Split('.')[2])));\n                        customColorGraphics.DrawRectangle(Pens.Black, 0, 0, this.picCustomColor.Width - 1, this.picCustomColor.Height - 1);\n\n                        this.picCustomColor.Image = customColorBitmap;\n\n                        break;\n\n                    case ChooseColorType.Define:\n                        this.tabControl1.SelectedTab = tabPageDefine;\n                        foreach (DataGridViewRow dr in this.dataGridViewDefineColor.Rows)\n                        {\n                            if (dr.Cells[\"ColumnNameDefineColor\"].Value.ToString() == this.SelectedColorValue.Split('.')[1])\n                            {\n                                dr.Selected = true;\n                                this.dataGridViewDefineColor.FirstDisplayedScrollingRowIndex = dr.Index;\n                                break;\n                            }\n                        }\n                        break;\n\n                    case ChooseColorType.System:\n                        this.tabControl1.SelectedTab = tabPageSystem;\n                        foreach (DataGridViewRow dr in this.dataGridViewSystemColors.Rows)\n                        {\n                            if (dr.Cells[\"ColumnNameSystemColor\"].Value.ToString() == this.SelectedColorValue.Split('.')[1])\n                            {\n                                dr.Selected = true;\n                                this.dataGridViewSystemColors.FirstDisplayedScrollingRowIndex = dr.Index;\n                                break;\n                            }\n                        }\n                        break;\n                }\n            }\n            #endregion\n            #region 如果当前选择颜色设置为空\n            else\n            {\n          //      this.tabControl1.SelectedTab = tabPageCustom;\n            }\n            #endregion\n        }\n\n        /// <summary>\n        /// 控件载入\n        /// </summary>\n        /// <param name=\"sender\"></param>\n        /// <param name=\"e\"></param>\n        private void SEColorChooseComboBoxDropDown_Load(object sender, EventArgs e)\n        {\n            ShowCurrentTabPage();\n        }\n\n        private void dataGridViewWebColor_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)\n        {\n            this.SelectedType = ChooseColorType.Define;\n            this.SelectedColorValue = this.dataGridViewDefineColor.Rows[e.RowIndex].Cells[\"ColumnValueDefineColor\"].Value.ToString();\n            this.SelectedColorName = this.dataGridViewDefineColor.Rows[e.RowIndex].Cells[\"ColumnNameDefineColor\"].Value.ToString();\n\n            this.SelectedColor = Color.FromArgb(Convert.ToInt32(SelectedColorValue.Split('.')[2]));\n            this.FindForm().Hide();\n        }\n\n        private void dataGridViewSystemColors_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)\n        {\n            this.SelectedType = ChooseColorType.System;\n            this.SelectedColorValue = this.dataGridViewSystemColors.Rows[e.RowIndex].Cells[\"ColumnValueSystemColor\"].Value.ToString();\n            this.SelectedColorName = this.dataGridViewSystemColors.Rows[e.RowIndex].Cells[\"ColumnNameSystemColor\"].Value.ToString();\n\n            Type typeSystemColors = typeof(System.Drawing.SystemColors);\n            PropertyInfo p = typeSystemColors.GetProperty(this.SelectedColorName);\n            this.SelectedColor = (Color)p.GetValue(typeSystemColors, null);\n            this.FindForm().Hide();\n        }\n\n        private void btnClearColor_Click(object sender, EventArgs e)\n        {\n            this.picCustomColor.Image = null;\n\n            this.SelectedType = ChooseColorType.Custom;\n            this.SelectedColorValue = String.Empty;\n            this.SelectedColorName = String.Empty;\n\n            this.SelectedColor = Color.Empty;\n            this.FindForm().Hide();\n        }\n\n        private void btnChooseColor_Click(object sender, EventArgs e)\n        {\n            this.ColorChooseComboBox.SetDropDownFormOwner(true);\n\n            if (colorDialog.ShowDialog() == DialogResult.OK)\n            {\n                this.SelectedType = ChooseColorType.Custom;\n                this.SelectedColorName = \n                    colorDialog.Color.R.ToString() + \",\" +\n                    colorDialog.Color.G.ToString() + \",\" +\n                    colorDialog.Color.B.ToString();\n                this.SelectedColorValue = ((int)ChooseColorType.Custom).ToString()\n                    + \".\" + this.SelectedColorName + \".\" + colorDialog.Color.ToArgb();\n                this.SelectedColor = colorDialog.Color;\n\n                if (this.customColorBitmap == null)\n                {\n                    customColorBitmap = new Bitmap(this.picCustomColor.Width, this.picCustomColor.Height);\n                    customColorGraphics = Graphics.FromImage(customColorBitmap);\n                }\n\n                customColorGraphics.Clear(this.colorDialog.Color);\n                customColorGraphics.DrawRectangle(Pens.Black, 0, 0, this.picCustomColor.Width - 1, this.picCustomColor.Height - 1);\n\n                this.picCustomColor.Image = customColorBitmap;\n\n                this.ColorChooseComboBox.SetDropDownFormOwner(false);\n               // this.ColorChooseComboBox.Invalidate();\n            }\n            else\n            {\n                this.SelectedType = ChooseColorType.Custom;\n                this.SelectedColorValue = String.Empty;\n                this.SelectedColorName = String.Empty;\n\n                this.SelectedColor = Color.Empty;\n            }\n\n            this.ColorChooseComboBox.SetDropDownFormOwner(false);\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengColorChooseComboBoxDropDown.resx",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <metadata name=\"Column1.UserAddedColumn\" type=\"System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\">\n    <value>True</value>\n  </metadata>\n  <metadata name=\"Column2.UserAddedColumn\" type=\"System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\">\n    <value>True</value>\n  </metadata>\n  <metadata name=\"ColumnNameDefineColor.UserAddedColumn\" type=\"System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\">\n    <value>True</value>\n  </metadata>\n  <metadata name=\"ColumnValueDefineColor.UserAddedColumn\" type=\"System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\">\n    <value>True</value>\n  </metadata>\n  <metadata name=\"dataGridViewImageColumn1.UserAddedColumn\" type=\"System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\">\n    <value>True</value>\n  </metadata>\n  <metadata name=\"ColumnNameSystemColor.UserAddedColumn\" type=\"System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\">\n    <value>True</value>\n  </metadata>\n  <metadata name=\"ColumnValueSystemColor.UserAddedColumn\" type=\"System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\">\n    <value>True</value>\n  </metadata>\n</root>"
  },
  {
    "path": "Sheng.Winform.Controls/ShengComboBox.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.ComponentModel;\nusing Sheng.Winform.Controls.Win32;\nusing System.Drawing;\n\nnamespace Sheng.Winform.Controls\n{\n    \n    public class ShengComboBox : ComboBox, IShengValidate\n    {\n        #region \n\n        private bool allowEmpty = true;\n        /// <summary>\n        /// Ƿ\n        /// </summary>\n        [Description(\"Ƿ\")]\n        [Category(\"Sheng.Winform.Controls\")]\n        public bool AllowEmpty\n        {\n            get\n            {\n                return this.allowEmpty;\n            }\n            set\n            {\n                this.allowEmpty = value;\n            }\n        }\n\n        private string waterText = String.Empty;\n        /// <summary>\n        /// ˮӡı\n        /// </summary>\n        [Description(\"ˮӡı\")]\n        [Category(\"Sheng.Winform.Controls\")]\n        public string WaterText\n        {\n            get { return this.waterText; }\n            set\n            {\n                this.waterText = value;\n                this.Invalidate();\n            }\n        }\n\n        #endregion\n\n        #region \n\n        public ShengComboBox()\n        {\n        }\n\n        #endregion\n\n        #region ˽з\n\n\n        protected override void WndProc(ref   Message m)\n        {\n            base.WndProc(ref   m);\n\n            if (m.Msg == User32.WM_PAINT || m.Msg == User32.WM_ERASEBKGND || m.Msg == User32.WM_NCPAINT)\n            {\n                if (!this.Focused && this.Text == String.Empty  && this.WaterText != String.Empty)\n                {\n                    Graphics g = Graphics.FromHwnd(this.Handle);\n                    g.DrawString(this.WaterText, this.Font, Brushes.Gray, 2, 2);\n                }\n            }\n        }\n\n        #endregion\n\n        #region ISEValidate Ա\n\n        private string title;\n        /// <summary>\n        /// \n        /// </summary>\n        [Description(\"\")]\n        [Category(\"Sheng.Winform.Controls\")]\n        public string Title\n        {\n            get\n            {\n                return this.title;\n            }\n            set\n            {\n                this.title = value;\n            }\n        }\n\n        private bool highLight = true;\n        /// <summary>\n        /// ֤ʧʱǷҪʾı䱳ɫ\n        /// </summary>\n        [Description(\"Ҫƥʽ\")]\n        [Category(\"Sheng.Winform.Controls\")]\n        public bool HighLight\n        {\n            get\n            {\n                return this.highLight;\n            }\n            set\n            {\n                this.highLight = value;\n            }\n        }\n\n        /// <summary>\n        /// ֤ؼ\n        /// </summary>\n        /// <returns></returns>\n        public bool SEValidate(out string msg)\n        {\n            msg = String.Empty;\n\n            if (!this.AllowEmpty && this.Text == \"\")\n            {\n                msg += String.Format(\"[ {0} ] {1}\", this.Title, \"Ϊ\");\n                return false;\n            }\n\n            #region CustomValidate\n\n            if (CustomValidate != null)\n            {\n                string customValidateMsg;\n                if (CustomValidate(this, out customValidateMsg) == false)\n                {\n                    msg += String.Format(\"[ {0} ] {1}\", this.Title, customValidateMsg);\n                    return false;\n                }\n            }\n\n            #endregion\n\n            return true;\n        }\n\n        public CustomValidateMethod CustomValidate\n        {\n            get;\n            set;\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengComboSelector/ShengComboSelector.Designer.cs",
    "content": "﻿namespace Sheng.Winform.Controls\n{\n    partial class ShengComboSelector\n    {\n        /// <summary> \n        /// 必需的设计器变量。\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary> \n        /// 清理所有正在使用的资源。\n        /// </summary>\n        /// <param name=\"disposing\">如果应释放托管资源，为 true；否则为 false。</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region 组件设计器生成的代码\n\n        /// <summary> \n        /// 设计器支持所需的方法 - 不要\n        /// 使用代码编辑器修改此方法的内容。\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.SuspendLayout();\n            // \n            // SEComboSelector\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.BackColor = System.Drawing.SystemColors.Window;\n            this.Name = \"SEComboSelector\";\n            this.Size = new System.Drawing.Size(278, 53);\n            this.ResumeLayout(false);\n\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengComboSelector/ShengComboSelector.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Drawing;\nusing System.Data;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Diagnostics;\nusing System.Collections;\nusing System.Reflection;\nusing System.Drawing.Drawing2D;\nusing Sheng.Winform.Controls.PopupControl;\n\nnamespace Sheng.Winform.Controls\n{\n    public partial class ShengComboSelector : UserControl, IShengValidate\n    {\n        #region 私有成员\n\n        private DateTime _dropDownHideTime;\n\n        private Popup _popup;\n        private ShengComboSelectorItemContainer _itemContainer;\n\n        /// <summary>\n        /// 当前状态\n        /// </summary>\n        private EnumState _state = EnumState.Normal;\n        private EnumState State\n        {\n            get { return _state; }\n            set\n            {\n                _state = value;\n                this.Invalidate();\n            }\n        }\n\n        #region 绘图表面\n\n        private int buttonSize = 6;\n\n        /// <summary>\n        /// 整个可用的绘图表面\n        /// </summary>\n        private Rectangle DrawAreaRectangle\n        {\n            get\n            {\n                Rectangle r = new Rectangle(this.ClientRectangle.Location, this.ClientRectangle.Size);\n                r.Width--;\n                r.Height--;\n                return r;\n            }\n        }\n\n        /// <summary>\n        /// 右边按钮的绘图表面\n        /// </summary>\n        private Rectangle ButtonAreaRectangle\n        {\n            get\n            {\n                Rectangle r = new Rectangle();\n                r.Size = new Size(buttonSize, buttonSize);\n                r.Location = new Point(\n                     DrawAreaRectangle.Width - r.Width - 4,\n                    (DrawAreaRectangle.Height - r.Height) / 2);\n                return r;\n            }\n        }\n\n        /// <summary>\n        /// 文本的绘制表面\n        /// </summary>\n        private Rectangle TitleStringAreaRectangle\n        {\n            get\n            {\n                Rectangle r = new Rectangle();\n                r.Location = new Point(6, 5);\n                r.Width = DrawAreaRectangle.Width - (DrawAreaRectangle.Width - ButtonAreaRectangle.Left) - r.Left;\n                r.Height = this.Font.Height;\n                return r;\n            }\n        }\n\n        /// <summary>\n        /// 副文本的绘制表面\n        /// </summary>\n        private Rectangle DescriptionStringAreaRectangle\n        {\n            get\n            {\n                Rectangle r = new Rectangle();\n                r.Location = new Point(6, TitleStringAreaRectangle.Height + 7);\n                r.Width = DrawAreaRectangle.Width - (DrawAreaRectangle.Width - ButtonAreaRectangle.Left) - r.Left;\n                r.Height = this.Font.Height;\n                return r;\n            }\n        }\n\n        /// <summary>\n        /// 聚焦框\n        /// </summary>\n        private Rectangle FocusRectangle\n        {\n            get\n            {\n                Rectangle r = new Rectangle();\n\n                //不好只用文本的区域，要考虑以后加图片后聚焦框的问题\n                //r.Location = TitleStringAreaRectangle.Location;\n                //r.Width = TitleStringAreaRectangle.Width - 2; //和按钮空开一点\n                //r.Height = TitleStringAreaRectangle.Height + DescriptionStringAreaRectangle.Height;\n\n                r.Location = new Point(0, 0);\n                r.Width = DrawAreaRectangle.Width - (DrawAreaRectangle.Width - ButtonAreaRectangle.Left) - r.Left;\n                r.Height = DrawAreaRectangle.Height;\n                r.Inflate(-3, -3);\n\n                return r;\n            }\n        }\n\n        private GraphicsPath ButtonPath\n        {\n            get\n            {\n                int pointY = 2;\n                Point[] pathPoint = \n                { \n                    new Point(0,pointY), \n                    new Point(buttonSize,pointY), \n                    new Point(buttonSize/2 ,buttonSize/2 + pointY), \n                    new Point(0,pointY) \n                };\n\n                Point offSetPoint = ButtonAreaRectangle.Location;\n                pathPoint[0].Offset(offSetPoint);\n                pathPoint[1].Offset(offSetPoint);\n                pathPoint[2].Offset(offSetPoint);\n                pathPoint[3].Offset(offSetPoint);\n\n                //foreach不能\n                //报foreach里不能改p的成员\n                //foreach (Point p in pathPoint)\n                //{\n                //    //p.Offset(ButtonAreaRectangle.Location);\n                //    p.X = p.X + ButtonAreaRectangle.X;\n                //    p.Y = p.Y + ButtonAreaRectangle.Y;\n                //}\n\n                GraphicsPath path = new GraphicsPath();\n                path.AddLines(pathPoint);  //一个向下的正三角形\n                return path;\n            }\n        }\n\n        #endregion\n\n        private Font _titleFont = new Font(SystemFonts.DefaultFont.Name, SystemFonts.DefaultFont.Size, FontStyle.Bold);\n        private Font _descriptionFont = new Font(SystemFonts.DefaultFont.Name, SystemFonts.DefaultFont.Size);\n\n        private TextFormatFlags _textFlags = TextFormatFlags.SingleLine | TextFormatFlags.WordEllipsis;\n\n        #endregion\n\n        #region 公开属性\n\n        /// <summary>\n        /// 弹出面板的宽度\n        /// </summary>\n        public Nullable<int> PopupWidth;\n\n        /// <summary>\n        /// 当前选中的值\n        /// 如果设置了ValueMember，就是绑定对象的ValueMember的值\n        /// 如果没有，就是绑定对象\n        /// </summary>\n        public object SelectedValue\n        {\n            get { return _itemContainer.SelectedValue; }\n            set\n            {\n                _itemContainer.SelectedValue = value;\n            }\n        }\n\n        /// <summary>\n        /// 获取当前选中的绑定的对象\n        /// </summary>\n        public object DataBoundItem\n        {\n            get\n            {\n                return _itemContainer.DataBoundItem;\n            }\n        }\n\n        /// <summary>\n        /// 显示指定项的类型\n        /// </summary>\n        public Type DataSourceType\n        {\n            get { return _itemContainer.DataSourceType; }\n            set { _itemContainer.DataSourceType = value; }\n        }\n\n        public IList DataSource\n        {\n            get { return _itemContainer.DataSource; }\n            set\n            {\n                _itemContainer.DataSource = value;\n                //要刷一下，至少要刷掉之前显示的内容\n                this.Invalidate();\n            }\n        }\n\n        /// <summary>\n        /// 项的高度\n        /// </summary>\n        public int ItemHeight\n        {\n            get { return _itemContainer.ItemHeight; }\n            //set { _itemContainer.ItemHeight = value; }\n        }\n\n        private int _maxItem = 8;\n        /// <summary>\n        /// 最大显示的项数\n        /// </summary>\n        public int MaxItem\n        {\n            get { return _maxItem; }\n            set { _maxItem = value; }\n        }\n\n        private bool _showDescription = true;\n        /// <summary>\n        /// 是否显示说明字段，此属性不影响弹出面板是否显示\n        /// 弹出面板是否显示由DescriptionMember是否设置决定\n        /// </summary>\n        public bool ShowDescription\n        {\n            get { return _showDescription; }\n            set { _showDescription = value; }\n        }\n\n        #region Member\n\n        public string DisplayMember\n        {\n            get { return _itemContainer.DisplayMember; }\n            set { _itemContainer.DisplayMember = value; }\n        }\n\n        public string DescriptionMember\n        {\n            get { return _itemContainer.DescriptionMember; }\n            set { _itemContainer.DescriptionMember = value; }\n        }\n\n        public string ValueMember\n        {\n            get { return _itemContainer.ValueMember; }\n            set { _itemContainer.ValueMember = value; }\n        }\n\n        #endregion\n\n        #region 配色相关\n\n        #region Selected\n\n        private Color _selectedTextColor = Color.Black;\n        public Color SelectedTextColor\n        {\n            get\n            {\n                return _selectedTextColor;\n            }\n            set\n            {\n                _selectedTextColor = value;\n            }\n        }\n\n        private Color _selectedDescriptionColor = Color.DarkGray;\n        public Color SelectedDescriptionColor\n        {\n            get\n            {\n                return _selectedDescriptionColor;\n            }\n            set\n            {\n                _selectedDescriptionColor = value;\n            }\n        }\n\n        private Color _selectedColor = Color.FromArgb(193, 210, 238);\n        public Color SelectedColor\n        {\n            get\n            {\n                return _selectedColor;\n            }\n            set\n            {\n                _selectedColor = value;\n            }\n        }\n\n        private Color _selectedBorderColor = Color.FromArgb(49, 106, 197);\n        public Color SelectedBorderColor\n        {\n            get\n            {\n                return _selectedBorderColor;\n            }\n            set\n            {\n                _selectedBorderColor = value;\n            }\n        }\n\n        #endregion\n\n        #region Focus\n\n        private Color _focusTextColor = Color.Black;\n        public Color FocusTextColor\n        {\n            get\n            {\n                return _focusTextColor;\n            }\n            set\n            {\n                _focusTextColor = value;\n            }\n        }\n\n        private Color _focusDescriptionColor = Color.DarkGray;\n        public Color FocusDescriptionColor\n        {\n            get\n            {\n                return _focusDescriptionColor;\n            }\n            set\n            {\n                _focusDescriptionColor = value;\n            }\n        }\n\n        private Color _focusBackColor = Color.FromArgb(224, 232, 246);\n        public Color FocusBackColor\n        {\n            get\n            {\n                return _focusBackColor;\n            }\n            set\n            {\n                _focusBackColor = value;\n            }\n        }\n\n        private Color _focusBorderColor = Color.FromArgb(152, 180, 226);\n        public Color FocusBorderColor\n        {\n            get\n            {\n                return _focusBorderColor;\n            }\n            set\n            {\n                _focusBorderColor = value;\n            }\n        }\n\n        #endregion\n\n        #region Normal\n\n        private Color _textColor = Color.Black;\n        public Color TextColor\n        {\n            get\n            {\n                return _textColor;\n            }\n            set\n            {\n                _textColor = value;\n            }\n        }\n\n        private Color _descriptionColor = Color.DarkGray;\n        public Color DescriptionColor\n        {\n            get\n            {\n                return _descriptionColor;\n            }\n            set\n            {\n                _descriptionColor = value;\n            }\n        }\n\n        private Color _borderColor = SystemColors.ControlDark;\n        public Color BorderColor\n        {\n            get\n            {\n                return _borderColor;\n            }\n            set\n            {\n                _borderColor = value;\n            }\n        }\n\n        #endregion\n\n        #region Item\n\n        #region Selected\n\n        public Color ItemSelectedColor\n        {\n            get\n            {\n                return _itemContainer.SelectedColor;\n            }\n            set\n            {\n                _itemContainer.SelectedColor = value;\n            }\n        }\n\n        public Color ItemSelectedBorderColor\n        {\n            get\n            {\n                return _itemContainer.SelectedBorderColor;\n            }\n            set\n            {\n                _itemContainer.SelectedBorderColor = value;\n            }\n        }\n\n        public Color ItemSelectedTextColor\n        {\n            get\n            {\n                return _itemContainer.SelectedTextColor;\n            }\n            set\n            {\n                _itemContainer.SelectedTextColor = value;\n            }\n        }\n\n        public Color ItemSelectedDescriptionColor\n        {\n            get\n            {\n                return _itemContainer.SelectedDescriptionColor;\n            }\n            set\n            {\n                _itemContainer.SelectedDescriptionColor = value;\n            }\n        }\n\n        #endregion\n\n        #region Focus\n\n        public Color ItemFocusTextColor\n        {\n            get\n            {\n                return _itemContainer.FocusTextColor;\n            }\n            set\n            {\n                _itemContainer.FocusTextColor = value;\n            }\n        }\n\n        public Color ItemFocusDescriptionColor\n        {\n            get\n            {\n                return _itemContainer.FocusDescriptionColor;\n            }\n            set\n            {\n                _itemContainer.FocusDescriptionColor = value;\n            }\n        }\n\n        public Color ItemFocusColor\n        {\n            get\n            {\n                return _itemContainer.FocusColor;\n            }\n            set\n            {\n                _itemContainer.FocusColor = value;\n            }\n        }\n\n        public Color ItemFocusBorderColor\n        {\n            get\n            {\n                return _itemContainer.FocusBorderColor;\n            }\n            set\n            {\n                _itemContainer.FocusBorderColor = value;\n            }\n        }\n\n        #endregion\n\n        #region Normal\n\n        public Color ItemTextColor\n        {\n            get\n            {\n                return _itemContainer.TextColor;\n            }\n            set\n            {\n                _itemContainer.TextColor = value;\n            }\n        }\n\n        public Color ItemDescriptionColor\n        {\n            get\n            {\n                return _itemContainer.DescriptionColor;\n            }\n            set\n            {\n                _itemContainer.DescriptionColor = value;\n            }\n        }\n\n        public Color ItemBackgroundColor\n        {\n            get\n            {\n                return _itemContainer.BackgroundColor;\n            }\n            set\n            {\n                _itemContainer.BackgroundColor = value;\n            }\n        }\n\n        public Color ItemBorderColor\n        {\n            get\n            {\n                return _itemContainer.BorderColor;\n            }\n            set\n            {\n                _itemContainer.BorderColor = value;\n            }\n        }\n\n        #endregion\n\n        #endregion\n\n        #endregion\n\n        #region 数据校验有关\n\n        private bool allowEmpty = true;\n        /// <summary>\n        /// 是否允许空\n        /// </summary>\n        [Description(\"是否允许空\")]\n        [Category(\"Sheng.Winform.Controls\")]\n        public bool AllowEmpty\n        {\n            get\n            {\n                return this.allowEmpty;\n            }\n            set\n            {\n                this.allowEmpty = value;\n            }\n        }\n\n        #endregion\n\n        #endregion\n\n        #region  构造\n\n        public ShengComboSelector()\n        {\n            InitializeComponent();\n\n            if (DesignMode)\n                return;\n\n            this.SetStyle(ControlStyles.DoubleBuffer, true);\n            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);\n            this.SetStyle(ControlStyles.UserPaint, true);\n            this.SetStyle(ControlStyles.ResizeRedraw, true);\n            this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);\n            this.SetStyle(ControlStyles.ContainerControl, true);\n\n            _itemContainer = new ShengComboSelectorItemContainer();\n            _popup = new Popup(_itemContainer);\n            //_popup.Resizable = true;\n\n            _popup.Closed += new ToolStripDropDownClosedEventHandler(_popup_Closed);\n            _itemContainer.OnSelectedItemChangedClick += new ShengComboSelectorItemContainer.OnSelectedItemChangedHandler(_itemContainer_OnSelectedItemChanged);\n            _itemContainer.OnItemClick += new ShengComboSelectorItemContainer.OnItemClickHandler(_itemContainer_OnItemClick);\n\n            this._dropDownHideTime = DateTime.UtcNow;\n        }\n\n        #endregion\n\n        #region 私有方法和受保护方法\n\n        protected override void OnPaint(PaintEventArgs e)\n        {\n            Graphics g = e.Graphics;\n\n            //绘制边框和背景\n            #region 绘制背景和边框\n\n            SolidBrush backBrush;\n            Pen borderPen;\n\n            if (this.Enabled)\n            {\n                if (_state == EnumState.Selected)\n                {\n                    backBrush = new SolidBrush(this.SelectedColor);\n                    borderPen = new Pen(this.SelectedBorderColor);\n                }\n                else if (_state == EnumState.Hot)\n                {\n                    backBrush = new SolidBrush(this.FocusBackColor);\n                    borderPen = new Pen(this.FocusBorderColor);\n                }\n                else\n                {\n                    //backBrush = new SolidBrush(this.BackgroundColor);\n                    backBrush = new SolidBrush(this.BackColor);\n                    borderPen = new Pen(this.BorderColor);\n                }\n            }\n            else\n            {\n                backBrush = new SolidBrush(SystemColors.Control);\n                borderPen = new Pen(this.BorderColor);\n            }\n\n            g.FillRectangle(backBrush, DrawAreaRectangle);\n            g.DrawRectangle(borderPen, DrawAreaRectangle);\n\n            backBrush.Dispose();\n            borderPen.Dispose();\n\n            #endregion\n\n            //如果当前有选定的项（值）\n            if (this.DataBoundItem != null)\n            {\n                #region 绘制标题\n\n                //绘制标题\n                string text = String.Empty;\n                if (String.IsNullOrEmpty(this.DisplayMember) == false)\n                {\n                    PropertyInfo displayPropertyInfo = this.DataBoundItem.GetType().GetProperty(this.DisplayMember);\n                    if (displayPropertyInfo != null)\n                    {\n                        object textObj = displayPropertyInfo.GetValue(this.DataBoundItem, null);\n                        if (textObj != null)\n                            text = textObj.ToString();\n                    }\n                }\n                else\n                {\n                    text = this.DataBoundItem.ToString();\n                }\n\n                Color textColor = SystemColors.InactiveCaptionText;\n                if (this.Enabled)\n                {\n                    if (_state == EnumState.Selected)\n                    {\n                        textColor = this.SelectedTextColor;\n                    }\n                    else if (_state == EnumState.Hot)\n                    {\n                        textColor = this.FocusTextColor;\n                    }\n                    else\n                    {\n                        textColor = this.TextColor;\n                    }\n                }\n                //g.DrawString(text, _titleFont, textBrush, TitleStringAreaRectangle);\n                //g.FillRectangle(Brushes.Red, TitleStringAreaRectangle);\n                TextRenderer.DrawText(g, text, _titleFont, TitleStringAreaRectangle, textColor, _textFlags);\n                //textBrush.Dispose();\n\n                #endregion\n\n                if (ShowDescription)\n                {\n                    #region 绘制Description\n\n                    //绘制Description\n                    string description = String.Empty;\n                    if (String.IsNullOrEmpty(this.DescriptionMember) == false)\n                    {\n                        PropertyInfo descriptionPropertyInfo = this.DataBoundItem.GetType().GetProperty(this.DescriptionMember);\n                        if (descriptionPropertyInfo != null)\n                        {\n                            object descriptionObj = descriptionPropertyInfo.GetValue(this.DataBoundItem, null);\n                            if (descriptionObj != null)\n                                description = descriptionObj.ToString();\n                        }\n                    }\n\n                    if (String.IsNullOrEmpty(description) == false)\n                    {\n                        Color descriptionColor;\n                        if (_state == EnumState.Selected)\n                        {\n                            descriptionColor = this.SelectedDescriptionColor;\n                        }\n                        else if (_state == EnumState.Hot)\n                        {\n                            descriptionColor = this.FocusDescriptionColor;\n                        }\n                        else\n                        {\n                            descriptionColor = this.DescriptionColor;\n                        }\n                        //g.DrawString(description, _descriptionFont, descriptionBrush, DescriptionStringAreaRectangle);\n                        TextRenderer.DrawText(g, description, _descriptionFont, DescriptionStringAreaRectangle, descriptionColor, _textFlags);\n                        //descriptionBrush.Dispose();\n                    }\n\n                    #endregion\n                }\n            }\n\n            //g.FillRectangle(Brushes.Red, FocusRectangle);\n\n            //右侧按钮\n            if (this.Enabled)\n            {\n                //ControlPaint.DrawComboButton(g, ButtonAreaRectangle, ButtonState.Flat);;\n                g.FillPath(Brushes.Black, ButtonPath);\n            }\n            //else\n            //    ControlPaint.DrawComboButton(g, ButtonAreaRectangle, ButtonState.Inactive);\n\n            if (_state == EnumState.Selected)\n            {\n                ControlPaint.DrawFocusRectangle(g, FocusRectangle);\n            }\n        }\n\n        protected override void OnMouseEnter(EventArgs e)\n        {\n            if (this.Enabled)\n            {\n                if (this.State != EnumState.Selected)\n                    this.State = EnumState.Hot;\n            }\n\n            base.OnMouseEnter(e);\n        }\n\n        protected override void OnMouseLeave(EventArgs e)\n        {\n            if (this.Enabled)\n            {\n                if (_popup.Visible == false)\n                {\n                    if (this.Focused)\n                    {\n                        this.State = EnumState.Selected;\n                    }\n                    else\n                    {\n                        this.State = EnumState.Normal;\n                    }\n                }\n            }\n\n            base.OnMouseLeave(e);\n        }\n\n        protected override void OnEnter(EventArgs e)\n        {\n            this.State = EnumState.Selected;\n            base.OnEnter(e);\n        }\n\n        protected override void OnLeave(EventArgs e)\n        {\n\n            this.State = EnumState.Normal;\n\n            base.OnLeave(e);\n        }\n\n        protected override void OnMouseDown(MouseEventArgs e)\n        {\n            base.OnMouseDown(e);\n\n            if ((DateTime.UtcNow - _dropDownHideTime).TotalSeconds > 0.2)\n            {\n                ShowDropDown();\n            }\n        }\n\n        private void ShowDropDown()\n        {\n            //每次打开都要判读，如果把PopupWidth做成属性，在set里设置\n            //那么控件resize时，popup的宽度可能就不对了\n            if (this.PopupWidth == null)\n                _popup.Width = this.Width;\n            else\n                _popup.Width = this.PopupWidth.Value;\n\n            int showItem = 1;\n\n            if (_itemContainer.Items.Count > this.MaxItem)\n                showItem = this.MaxItem;\n            else if (_itemContainer.Items.Count == 0)\n                showItem = 1;\n            else\n                showItem = _itemContainer.Items.Count;\n\n            _popup.Height = showItem * this.ItemHeight + showItem * 1 + 1;\n\n            _popup.Show(this);\n        }\n\n        #endregion\n\n        #region 事件处理\n\n        void _popup_Closed(object sender, ToolStripDropDownClosedEventArgs e)\n        {\n            _dropDownHideTime = DateTime.UtcNow;\n        }\n\n        void _itemContainer_OnSelectedItemChanged(ShengComboSelectorItem item)\n        {\n            this.Invalidate();\n\n            //Application.DoEvents();\n\n            if (this.OnSelectedValueChanged != null)\n            {\n                if (item != null)\n                    OnSelectedValueChanged(item.Value);\n                else\n                    OnSelectedValueChanged(null);\n            }\n        }\n\n        void _itemContainer_OnItemClick(ShengComboSelectorItem item)\n        {\n            _popup.Close();\n        }\n\n        #endregion\n\n        #region 枚举\n\n        public enum EnumState\n        {\n            Normal = 0,\n            /// <summary>\n            /// 鼠标悬停\n            /// </summary>\n            Hot = 1,\n            /// <summary>\n            /// 获得焦点\n            /// </summary>\n            Selected = 2\n        }\n\n        #endregion\n\n        #region 公开事件\n\n        public delegate void OnSelectedValueChangedHandler(object value);\n        /// <summary>\n        /// 当前热点项生改变\n        /// </summary>\n        public event OnSelectedValueChangedHandler OnSelectedValueChanged;\n\n        #endregion\n\n        #region ISEValidate 成员\n\n        private string title;\n        /// <summary>\n        /// 标题\n        /// </summary>\n        [Description(\"标题\")]\n        [Category(\"Sheng.Winform.Controls\")]\n        public string Title\n        {\n            get\n            {\n                return this.title;\n            }\n            set\n            {\n                this.title = value;\n            }\n        }\n\n        private bool highLight = true;\n        /// <summary>\n        /// 验证失败时是否需要高亮显示（改变背景色）\n        /// </summary>\n        [Description(\"验证失败时是否需要高亮显示（改变背景色）\")]\n        [Category(\"Sheng.Winform.Controls\")]\n        public bool HighLight\n        {\n            get\n            {\n                return this.highLight;\n            }\n            set\n            {\n                this.highLight = value;\n            }\n        }\n\n        public bool SEValidate(out string msg)\n        {\n            msg = String.Empty;\n\n            if (this.AllowEmpty == false && this.SelectedValue == null)\n            {\n                msg += String.Format(\"[ {0} ] {1}\", this.Title, \"不允许为空\");\n                return false;\n            }\n\n            #region CustomValidate\n\n            if (CustomValidate != null)\n            {\n                string customValidateMsg;\n                if (CustomValidate(this, out customValidateMsg) == false)\n                {\n                    msg += String.Format(\"[ {0} ] {1}\", this.Title, customValidateMsg);\n                    return false;\n                }\n            }\n\n            #endregion\n\n            return true;\n        }\n\n        public CustomValidateMethod CustomValidate\n        {\n            get;\n            set;\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengComboSelector/ShengComboSelector.resx",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n</root>"
  },
  {
    "path": "Sheng.Winform.Controls/ShengComboSelector/ShengComboSelectorItem.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Drawing;\nusing System.Reflection;\nusing System.Diagnostics;\n\nnamespace Sheng.Winform.Controls\n{\n    public class ShengComboSelectorItem\n    {\n        #region 私有成员\n\n        private Point _titlePoint = new Point(10, 3);\n        private Point _descriptionPoint = new Point(10, 20);\n\n        private Font _titleFont = new Font(SystemFonts.DefaultFont.Name, SystemFonts.DefaultFont.Size, FontStyle.Bold);\n        private Font _descriptionFont = new Font(SystemFonts.DefaultFont.Name, SystemFonts.DefaultFont.Size);\n\n        private TextFormatFlags textFlags = TextFormatFlags.SingleLine | TextFormatFlags.WordEllipsis;\n\n        #region 绘图表面\n\n        /// <summary>\n        /// 整个可用的绘图表面\n        /// </summary>\n        private Rectangle DrawAreaRectangle\n        {\n            get\n            {\n                return this.ItemContainer.GetItemRectangle(this.Index);\n            }\n        }\n\n        /// <summary>\n        /// 文本的绘制表面\n        /// </summary>\n        private Rectangle TitleStringAreaRectangle\n        {\n            get\n            {\n                Rectangle r = new Rectangle();\n                Point locationPoint = DrawAreaRectangle.Location;\n                locationPoint.Offset(this._titlePoint);\n                r.Location = locationPoint;  //直接在Location上Offset不起作用\n                r.Width = DrawAreaRectangle.Width - r.Left;\n                r.Height = this._titleFont.Height;\n                return r;\n            }\n        }\n\n        /// <summary>\n        /// 副文本的绘制表面\n        /// </summary>\n        private Rectangle DescriptionStringAreaRectangle\n        {\n            get\n            {\n                Rectangle r = new Rectangle();\n                Point descriptionPoint = DrawAreaRectangle.Location;\n                descriptionPoint.Offset(new Point(10, TitleStringAreaRectangle.Height + 7));\n                r.Location = descriptionPoint;\n                r.Width = DrawAreaRectangle.Width - r.Left;\n                r.Height = this._descriptionFont.Height;\n                return r;\n            }\n        }\n\n        #endregion\n\n        #endregion\n\n        #region 公开属性\n\n        /// <summary>\n        /// 绑定的对象\n        /// </summary>\n        public object Value\n        {\n            get;\n            set;\n        }\n\n        public int Index\n        {\n            get\n            {\n                if (this.ItemContainer == null)\n                    return -1;\n\n                return this.ItemContainer.Items.IndexOf(this);\n            }\n        }\n\n        /// <summary>\n        /// 所属的面板\n        /// </summary>\n        public ShengComboSelectorItemContainer ItemContainer\n        {\n            get;\n            set;\n        }\n\n        private bool _selected = false;\n        /// <summary>\n        /// 当前是否选中\n        /// </summary>\n        public bool Selected\n        {\n            get { return _selected; }\n            set\n            {\n                _selected = value;\n                ItemContainer.DrawItem(this.Index);\n            }\n        }\n\n        #endregion\n\n        #region 构造\n\n        public ShengComboSelectorItem(object value)\n        {\n            Value = value;\n        }\n\n        #endregion\n\n        #region 公开方法\n\n        //绘制此项目\n        public void DrawItem(Graphics g)\n        {\n            //Debug.WriteLine(\"DrawItem:\" + Index);\n\n            if (ItemContainer.InDisplayRange(this.Index) == false)\n                return;\n\n            Rectangle clientRect = this.ItemContainer.GetItemRectangle(this.Index);\n\n            #region 绘制背景和边框\n\n            SolidBrush backBrush;\n            Pen borderPen;\n\n            if (this.Selected)\n            {\n                backBrush = new SolidBrush(ItemContainer.SelectedColor);\n                borderPen = new Pen(ItemContainer.SelectedBorderColor);\n            }\n            else if (this.ItemContainer.HotedItem == this)\n            {\n                backBrush = new SolidBrush(ItemContainer.FocusColor);\n                borderPen = new Pen(ItemContainer.FocusBorderColor);\n            }\n            else\n            {\n                backBrush = new SolidBrush(ItemContainer.BackgroundColor);\n                borderPen = new Pen(ItemContainer.BorderColor);\n            }\n\n            g.FillRectangle(backBrush, clientRect);\n            g.DrawRectangle(borderPen, clientRect);\n\n            backBrush.Dispose();\n            borderPen.Dispose();\n\n            #endregion\n\n            #region 绘制标题\n\n            //绘制标题\n            string text = String.Empty;\n            if (String.IsNullOrEmpty(ItemContainer.DisplayMember) == false)\n            {\n                if (ItemContainer.DisplayPropertyInfo != null)\n                {\n                    object textObj = ItemContainer.DisplayPropertyInfo.GetValue(this.Value, null);\n                    if (textObj != null)\n                        text = textObj.ToString();\n                }\n            }\n            else\n            {\n                text = this.Value.ToString();\n            }\n\n            Color textColor;\n            if (this.Selected)\n            {\n                textColor = ItemContainer.SelectedTextColor;\n            }\n            else if (this.ItemContainer.HotedItem == this)\n            {\n                textColor = ItemContainer.FocusTextColor;\n            }\n            else\n            {\n                textColor = ItemContainer.TextColor;\n            }\n            //g.DrawString(text, _titleFont, textBrush, textPoint);\n            TextRenderer.DrawText(g, text, _titleFont, TitleStringAreaRectangle, textColor, textFlags);\n            //textBrush.Dispose();\n\n            #endregion\n\n            #region 绘制Description\n\n            //绘制Description\n            string description = String.Empty;\n            if (String.IsNullOrEmpty(ItemContainer.DescriptionMember) == false)\n            {\n                if (ItemContainer.DiscriptionPropertyInfo != null)\n                {\n                    object descriptionObj = ItemContainer.DiscriptionPropertyInfo.GetValue(this.Value, null);\n                    if (descriptionObj != null)\n                        description = descriptionObj.ToString();\n                }\n            }\n\n            if (String.IsNullOrEmpty(description) == false)\n            {\n                Color descriptionColor;\n                if (this.Selected)\n                {\n                    descriptionColor = ItemContainer.SelectedDescriptionColor;\n                }\n                else if (this.ItemContainer.HotedItem == this)\n                {\n                    descriptionColor = ItemContainer.FocusDescriptionColor;\n                }\n                else\n                {\n                    descriptionColor = ItemContainer.DescriptionColor;\n                }\n                //g.DrawString(description, _descriptionFont, descriptionBrush, descriptionPoint);\n                TextRenderer.DrawText(g, description, _descriptionFont, DescriptionStringAreaRectangle, descriptionColor, textFlags);\n                //descriptionBrush.Dispose();\n            }\n\n            #endregion\n\n            g.Dispose();\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengComboSelector/ShengComboSelectorItemCollection.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Collections;\n\nnamespace Sheng.Winform.Controls\n{\n    public class ShengComboSelectorItemCollection : CollectionBase\n    {\n        #region 构造\n\n        public ShengComboSelectorItemCollection()\n        {\n        }\n\n        public ShengComboSelectorItemCollection(ShengComboSelectorItemCollection value)\n        {\n            this.AddRange(value);\n        }\n\n        public ShengComboSelectorItemCollection(ShengComboSelectorItem[] value)\n        {\n            this.AddRange(value);\n        }\n\n        #endregion\n\n        #region 基本方法和属性\n\n        public ShengComboSelectorItem this[int index]\n        {\n            get\n            {\n                return ((ShengComboSelectorItem)(List[index]));\n            }\n            set\n            {\n                List[index] = value;\n            }\n        }\n\n        public virtual int Add(ShengComboSelectorItem value)\n        {\n            return List.Add(value);\n        }\n\n        public void AddRange(ShengComboSelectorItem[] value)\n        {\n            for (int i = 0; (i < value.Length); i = (i + 1))\n            {\n                this.Add(value[i]);\n            }\n        }\n\n        public void AddRange(ShengComboSelectorItemCollection value)\n        {\n            for (int i = 0; (i < value.Count); i = (i + 1))\n            {\n                this.Add(value[i]);\n            }\n        }\n\n        public bool Contains(ShengComboSelectorItem value)\n        {\n            return List.Contains(value);\n        }\n\n        public void CopyTo(ShengComboSelectorItem[] array, int index)\n        {\n            List.CopyTo(array, index);\n        }\n\n        public int IndexOf(ShengComboSelectorItem value)\n        {\n            return List.IndexOf(value);\n        }\n\n        public void Insert(int index, ShengComboSelectorItem value)\n        {\n            List.Insert(index, value);\n        }\n\n        public new SERichComboBoxDropItemEnumerator GetEnumerator()\n        {\n            return new SERichComboBoxDropItemEnumerator(this);\n        }\n\n        public virtual void Remove(ShengComboSelectorItem value)\n        {\n            List.Remove(value);\n        }\n\n        #endregion\n\n        #region Enumerator\n\n        public class SERichComboBoxDropItemEnumerator : object, IEnumerator\n        {\n\n            private IEnumerator baseEnumerator;\n\n            private IEnumerable temp;\n\n            public SERichComboBoxDropItemEnumerator(ShengComboSelectorItemCollection mappings)\n            {\n                this.temp = ((IEnumerable)(mappings));\n                this.baseEnumerator = temp.GetEnumerator();\n            }\n\n            public ShengComboSelectorItem Current\n            {\n                get\n                {\n                    return ((ShengComboSelectorItem)(baseEnumerator.Current));\n                }\n            }\n\n            object IEnumerator.Current\n            {\n                get\n                {\n                    return baseEnumerator.Current;\n                }\n            }\n\n            public bool MoveNext()\n            {\n                return baseEnumerator.MoveNext();\n            }\n\n            bool IEnumerator.MoveNext()\n            {\n                return baseEnumerator.MoveNext();\n            }\n\n            public void Reset()\n            {\n                baseEnumerator.Reset();\n            }\n\n            void IEnumerator.Reset()\n            {\n                baseEnumerator.Reset();\n            }\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengComboSelector/ShengComboSelectorItemContainer.Designer.cs",
    "content": "﻿namespace Sheng.Winform.Controls\n{\n    partial class ShengComboSelectorItemContainer\n    {\n        /// <summary> \n        /// 必需的设计器变量。\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary> \n        /// 清理所有正在使用的资源。\n        /// </summary>\n        /// <param name=\"disposing\">如果应释放托管资源，为 true；否则为 false。</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region 组件设计器生成的代码\n\n        /// <summary> \n        /// 设计器支持所需的方法 - 不要\n        /// 使用代码编辑器修改此方法的内容。\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.panelItem = new System.Windows.Forms.Panel();\n            this.vScrollBar = new System.Windows.Forms.VScrollBar();\n            this.SuspendLayout();\n            // \n            // panelItem\n            // \n            this.panelItem.AutoScroll = true;\n            this.panelItem.BackColor = System.Drawing.SystemColors.Window;\n            this.panelItem.Dock = System.Windows.Forms.DockStyle.Fill;\n            this.panelItem.Location = new System.Drawing.Point(0, 0);\n            this.panelItem.Name = \"panelItem\";\n            this.panelItem.Size = new System.Drawing.Size(193, 189);\n            this.panelItem.TabIndex = 0;\n            // \n            // vScrollBar\n            // \n            this.vScrollBar.Dock = System.Windows.Forms.DockStyle.Right;\n            this.vScrollBar.Location = new System.Drawing.Point(193, 0);\n            this.vScrollBar.Name = \"vScrollBar\";\n            this.vScrollBar.Size = new System.Drawing.Size(17, 189);\n            this.vScrollBar.TabIndex = 0;\n            // \n            // SEComboSelectorItemContainer\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.Controls.Add(this.panelItem);\n            this.Controls.Add(this.vScrollBar);\n            this.Name = \"SEComboSelectorItemContainer\";\n            this.Size = new System.Drawing.Size(210, 189);\n            this.ResumeLayout(false);\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.Panel panelItem;\n        private System.Windows.Forms.VScrollBar vScrollBar;\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengComboSelector/ShengComboSelectorItemContainer.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Drawing;\nusing System.Data;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Collections;\nusing System.Diagnostics;\nusing System.Reflection;\n\nnamespace Sheng.Winform.Controls\n{\n    public partial class ShengComboSelectorItemContainer : UserControl\n    {\n        #region 私有成员\n\n        //ToolTip _toolTip = new ToolTip();\n\n        private int _tempHotIndex = 0;\n        private int _hotIndex = -1;\n\n        private ShengComboSelectorItemCollection _items = new ShengComboSelectorItemCollection();\n        public ShengComboSelectorItemCollection Items\n        {\n            get { return _items; }\n        }\n\n        //当前可见范围\n        private int _displayRangeMin = 0;\n        private int _displayRangeMax = 0;\n\n        private int ScrollValue\n        {\n            get { return this.vScrollBar.Value; }\n            set { this.vScrollBar.Value = value; }\n        }\n\n        private int ScrollMaximum\n        {\n            get { return this.vScrollBar.Maximum; }\n            set\n            {\n                //当容器的高度只是显示一项的高度时，this.panelItem.Height / this.ItemHeight = 0\n                // this.ScrollMaximum = _items.Count - this.panelItem.Height / this.ItemHeight;\n                //ScrollMaximum = 1 ，而此时实际上不需要显示滚动条，将value重置为0\n                if (value >= _items.Count)\n                    value = 0;\n\n                if (value <= 0)\n                {\n                    value = 0;\n                    this.vScrollBar.Visible = false;\n                }\n                else\n                {\n                    this.vScrollBar.Visible = true;\n                }\n\n                this.vScrollBar.Maximum = value;\n            }\n        }\n\n        private int ScrollMinimum\n        {\n            get { return this.vScrollBar.Minimum; }\n            set { this.vScrollBar.Minimum = value; }\n        }\n\n        #endregion\n\n        #region 公开属性\n\n        /// <summary>\n        /// 显示指定项的类型\n        /// </summary>\n        public Type DataSourceType\n        {\n            get;\n            set;\n        }\n\n        private IList _dataSource;\n        /// <summary>\n        /// 数据源\n        /// </summary>\n        public IList DataSource\n        {\n            get { return _dataSource; }\n            set\n            {\n                _dataSource = value;\n\n                if (_dataSource != null && _dataSource.Count > 0)\n                {\n                    //避免每次绘制都进行反射操作\n                    //直接拿不行，涉及到类的多态的问题，不同的类拿到的PropertyInfo不能通用，\n                    //即使都是从基类派生出来的也不行，通过DataSourceType显示指定为基类型解决\n                    Type sourceType ;\n\n                    if (DataSourceType != null)\n                        sourceType = DataSourceType;\n                    else\n                        sourceType = _dataSource[0].GetType();\n\n                    if (String.IsNullOrEmpty(this.DisplayMember) == false)\n                        DisplayPropertyInfo = sourceType.GetProperty(this.DisplayMember);\n                    if (String.IsNullOrEmpty(this.DescriptionMember) == false)\n                        DiscriptionPropertyInfo = sourceType.GetProperty(this.DescriptionMember);\n                    if (String.IsNullOrEmpty(this.ValueMember) == false)\n                        ValuePropertyInfo = sourceType.GetProperty(this.ValueMember);\n                }\n                else\n                {\n                    DisplayPropertyInfo = null;\n                    DiscriptionPropertyInfo = null;\n                    ValuePropertyInfo = null;\n                }\n\n                this.Reset();\n                ShowItem();\n            }\n        }\n\n        internal PropertyInfo DisplayPropertyInfo\n        {\n            get;\n            private set;\n        }\n\n        internal PropertyInfo DiscriptionPropertyInfo\n        {\n            get;\n            private set;\n        }\n\n        internal PropertyInfo ValuePropertyInfo\n        {\n            get;\n            private set;\n        }\n\n        //private int _itemHeight = 38;\n        ///// <summary>\n        ///// 项的高度\n        ///// </summary>\n        //public int ItemHeight\n        //{\n        //    get { return _itemHeight;}\n        //    set { _itemHeight = value; }\n        //}\n\n        /// <summary>\n        /// 项的高度\n        /// </summary>\n        public int ItemHeight\n        {\n            get\n            {\n                int height = SystemFonts.DefaultFont.Height;\n\n                if (String.IsNullOrEmpty(this.DescriptionMember) == false)\n                {\n                    height += SystemFonts.DefaultFont.Height;\n                }\n\n                height += (4 * 2 + 2);  //上下空4，两行字中间空2\n\n                return height;\n            }\n        }\n\n        /// <summary>\n        /// 项目的绘制区域\n        /// </summary>\n        public Rectangle ItemsRectangle\n        {\n            get\n            {\n                Rectangle r = new Rectangle(this.panelItem.ClientRectangle.Location, this.panelItem.ClientRectangle.Size);\n                r.Width--;\n                r.Height--;\n                return r;\n            }\n        }\n\n        /// <summary>\n        /// 当前选定的项目\n        /// </summary>\n        public ShengComboSelectorItem SelectedItem\n        {\n            get\n            {\n                for (int i = 0; i < this.Items.Count; i++)\n                {\n                    if (_items[i].Selected)\n                        return _items[i];\n                }\n\n                return null;\n            }\n            set\n            {\n                foreach (ShengComboSelectorItem item in _items)\n                {\n                    if (item.Selected)\n                        item.Selected = false;\n                }\n\n                if (value != null)\n                    value.Selected = true;\n            }\n        }\n\n        private ShengComboSelectorItem _hotedItem;\n        /// <summary>\n        /// 当前热点项目\n        /// </summary>\n        public ShengComboSelectorItem HotedItem\n        {\n            get { return _hotedItem; }\n            private set\n            {\n                if (value != _hotedItem)\n                {\n                    ShengComboSelectorItem _oldHot = _hotedItem as ShengComboSelectorItem;\n\n                    _hotedItem = value;\n\n                    if (_oldHot != null)\n                    {\n                        _oldHot.DrawItem(this.panelItem.CreateGraphics());\n                    }\n                    if (_hotedItem != null)\n                    {\n                        _hotedItem.DrawItem(this.panelItem.CreateGraphics());\n                    }\n\n                    //if (_toolTip.Active)\n                    //    _toolTip.Hide(this.panelItem);\n\n                    if (OnHotedItemChanged != null)\n                    {\n                        OnHotedItemChanged(_hotedItem);\n                    }\n                }\n            }\n        }\n\n        #region Member\n\n        public string DisplayMember\n        {\n            get;\n            set;\n        }\n\n        public string ValueMember\n        {\n            get;\n            set;\n        }\n\n        public string DescriptionMember\n        {\n            get;\n            set;\n        }\n\n        #endregion\n\n        public int SelectedIndex\n        {\n            get\n            {\n                if (SelectedItem == null)\n                    return -1;\n                else\n                    return SelectedItem.Index;\n            }\n        }\n\n        /// <summary>\n        /// 当前选中的值\n        /// 如果设置了ValueMember，就是绑定对象的ValueMember的值\n        /// 如果没有，就是绑定对象\n        /// </summary>\n        public object SelectedValue\n        {\n            get\n            {\n                if (SelectedItem != null)\n                {\n                    if (String.IsNullOrEmpty(this.ValueMember) == false)\n                    {\n                        PropertyInfo propertyInfo = SelectedItem.Value.GetType().GetProperty(this.ValueMember);\n                        if (propertyInfo != null)\n                        {\n                            return propertyInfo.GetValue(this.SelectedItem.Value, null);\n                        }\n                    }\n                    return SelectedItem.Value;\n                }\n                else\n                    return null;\n            }\n            set\n            {\n                SelectItemByValue(value);\n            }\n        }\n\n        /// <summary>\n        /// 获取当前选中的绑定的对象\n        /// </summary>\n        public object DataBoundItem\n        {\n            get\n            {\n                if (SelectedItem != null)\n                    return SelectedItem.Value;\n                else\n                    return null;\n            }\n        }\n\n        #region 配色相关\n\n        #region Selected\n\n        private Color _selectedColor = Color.FromArgb(193, 210, 238);\n        public Color SelectedColor\n        {\n            get\n            {\n                return _selectedColor;\n            }\n            set\n            {\n                _selectedColor = value;\n            }\n        }\n\n        private Color _selectedBorderColor = Color.FromArgb(49, 106, 197);\n        public Color SelectedBorderColor\n        {\n            get\n            {\n                return _selectedBorderColor;\n            }\n            set\n            {\n                _selectedBorderColor = value;\n            }\n        }\n\n        private Color _selectedTextColor = Color.Black;\n        public Color SelectedTextColor\n        {\n            get\n            {\n                return _selectedTextColor;\n            }\n            set\n            {\n                _selectedTextColor = value;\n            }\n        }\n\n        private Color _selectedDescriptionColor= Color.DarkGray;\n        public Color SelectedDescriptionColor\n        {\n            get\n            {\n                return _selectedDescriptionColor;\n            }\n            set\n            {\n                _selectedDescriptionColor = value;\n            }\n        }\n\n        #endregion\n\n        #region Focus\n\n        private Color _focusTextColor = Color.Black;\n        public Color FocusTextColor\n        {\n            get\n            {\n                return _focusTextColor;\n            }\n            set\n            {\n                _focusTextColor = value;\n            }\n        }\n\n        private Color _focusDescriptionColor= Color.DarkGray;\n        public Color FocusDescriptionColor\n        {\n            get\n            {\n                return _focusDescriptionColor;\n            }\n            set\n            {\n                _focusDescriptionColor = value;\n            }\n        }\n\n        private Color _focusColor = Color.FromArgb(224, 232, 246);\n        public Color FocusColor\n        {\n            get\n            {\n                return _focusColor;\n            }\n            set\n            {\n                _focusColor = value;\n            }\n        }\n\n        private Color _focusBorderColor = Color.FromArgb(152, 180, 226);\n        public Color FocusBorderColor\n        {\n            get\n            {\n                return _focusBorderColor;\n            }\n            set\n            {\n                _focusBorderColor = value;\n            }\n        }\n\n        #endregion\n\n        #region Normal\n\n        private Color _textColor = Color.Black;\n        public Color TextColor\n        {\n            get\n            {\n                return _textColor;\n            }\n            set\n            {\n                _textColor = value;\n            }\n        }\n\n         private Color _descriptionColor= Color.DarkGray;\n        public Color DescriptionColor\n        {\n            get\n            {\n                return _descriptionColor;\n            }\n            set\n            {\n                _descriptionColor = value;\n            }\n        }\n\n        private Color _backgroundColor = Color.White;\n        public Color BackgroundColor\n        {\n            get\n            {\n                return _backgroundColor;\n            }\n            set\n            {\n                _backgroundColor = value;\n            }\n        }\n\n        private Color _borderColor = Color.White;\n        public Color BorderColor\n        {\n            get\n            {\n                return _borderColor;\n            }\n            set\n            {\n                _borderColor = value;\n            }\n        }\n\n        #endregion\n\n        #endregion\n\n        #endregion\n\n        #region 构造\n\n        public ShengComboSelectorItemContainer()\n        {\n            InitializeComponent();\n\n            this.BorderStyle = BorderStyle.FixedSingle;\n\n            this.SetStyle(ControlStyles.Selectable, true);\n\n            Reset();\n\n            this.MouseWheel += new MouseEventHandler(SERichComboBoxDropPanel_MouseWheel);\n            this.panelItem.Paint += new PaintEventHandler(panelItem_Paint);\n            this.panelItem.MouseClick += new MouseEventHandler(panelItem_MouseClick);\n            this.panelItem.MouseMove += new MouseEventHandler(panelItem_MouseMove);\n            this.panelItem.MouseLeave += new EventHandler(panelItem_MouseLeave);\n            this.panelItem.MouseEnter += new EventHandler(panelItem_MouseEnter);\n            this.panelItem.MouseHover += new EventHandler(panelItem_MouseHover);\n            this.vScrollBar.ValueChanged += new EventHandler(vScrollBar_ValueChanged);\n\n            //this.Height = this.ItemHeight * this.showitem\n        }\n\n        #endregion\n\n        #region 私有方法\n\n        private void CreateItem()\n        {\n            _items.Clear();\n            if (this.DataSource != null)\n            {\n                foreach (object value in this.DataSource)\n                {\n                    AddItem(new ShengComboSelectorItem(value));\n                }\n            }\n        }\n\n        private void AddItem(ShengComboSelectorItem item)\n        {\n            item.ItemContainer = this;\n            this._items.Add(item);\n        }\n\n        private void SelectItem(int selectedIndex)\n        {\n            if (SelectedItem != null)\n                SelectedItem.Selected = false;\n\n            if (selectedIndex >= 0 && selectedIndex < this.Items.Count)\n            {\n                this.Items[selectedIndex].Selected = true;\n            }\n\n            if (OnSelectedItemChangedClick != null)\n                if (selectedIndex < _items.Count && selectedIndex >= 0)\n                {\n                    OnSelectedItemChangedClick(this.Items[selectedIndex]);\n                }\n                else\n                {\n                    OnSelectedItemChangedClick(null);\n                }\n        }\n\n        private void SelectItemByValue(object value)\n        {\n            if (this.ValuePropertyInfo != null)\n            {\n                foreach (ShengComboSelectorItem item in _items)\n                {\n                    if (this.ValuePropertyInfo != null)\n                    {\n                        if (this.ValuePropertyInfo.GetValue(item.Value, null).Equals(value))\n                        {\n                            SelectItem(item.Index);\n                            return;\n                        }\n                    }\n                }\n            }\n            else\n            {\n                foreach (ShengComboSelectorItem item in _items)\n                {\n                    if (item.Value.Equals(value))\n                    {\n                        SelectItem(item.Index);\n                        return;\n                    }\n                }\n            }\n\n            SelectItem(-1);\n        }\n\n        private int GetMouseHotIndex(int mouseY)\n        {\n            return mouseY / this.ItemHeight + this.ScrollValue;\n        }\n\n        private void DrawBackGround()\n        {\n            Graphics g = this.panelItem.CreateGraphics();\n            g.Clear(SystemColors.Window);\n        }\n\n        private void DrawItems()\n        {\n            DrawBackGround();\n\n            if (this.Items == null || this.Items.Count == 0)\n                return;\n\n            this.ScrollMaximum = _items.Count - this.panelItem.Height / this.ItemHeight;\n\n            //if (this.ScrollMaximum == 0)\n            //    this.vScrollBar.Visible = false;\n            //else\n            //    this.vScrollBar.Visible = true;\n\n            _displayRangeMin = this.ScrollValue;\n            _displayRangeMax = this.panelItem.Height / this.ItemHeight + this.ScrollValue - 1;\n\n            //当容器的高度只是显示一项的高度时，this.panelItem.Height / this.ItemHeight = 0\n            //再-1 后，结果将为-1\n            if (_displayRangeMax < 0)\n                _displayRangeMax = 0;\n\n            if (_displayRangeMax >= this.Items.Count)\n                _displayRangeMax = this.Items.Count - 1;\n\n            for (int i = _displayRangeMin; i <= _displayRangeMax; i++)\n            {\n                DrawItem(i);\n            }\n        }\n\n        private void Reset()\n        {\n            this.ScrollMaximum = 0;\n            this.ScrollMinimum = 0;\n            this.ScrollValue = 0;\n            this.vScrollBar.LargeChange = 1;\n\n            if (this.Items == null)\n            {\n                this.ScrollMaximum = 0;\n            }\n            else\n            {\n                this.ScrollMaximum = _items.Count - this.panelItem.Height / this.ItemHeight;\n            }\n        }\n       \n        #endregion\n\n        #region 公开方法\n\n        //把项目显示到面板上去\n        public void ShowItem()\n        {\n            CreateItem();\n\n            DrawItems();\n        }\n\n        /// <summary>\n        /// 判断指定下标的项是否在当前需要显示的范围\n        /// </summary>\n        /// <param name=\"index\"></param>\n        /// <returns></returns>\n        public bool InDisplayRange(int index)\n        {\n            //if (_displayRangeMin == 0 && _displayRangeMax == 0)\n            //    return false;\n\n            //判断index是出超出索引范围，因为当没有项目时，还是会显示一个空项的位置\n            //以示用户没有内容\n            if (index >= _items.Count)\n                return false;\n\n            if (index < _displayRangeMin || index > _displayRangeMax)\n                return false;\n            else\n                return true;\n        }\n\n        internal void DrawItem(int index)\n        {\n            //调用item的绘制方法绘制\n            _items[index].DrawItem(this.panelItem.CreateGraphics());\n        }\n\n        //获取指定矩形的绘制矩形\n        public Rectangle GetItemRectangle(int index)\n        {\n            if (InDisplayRange(index) == false)\n                return Rectangle.Empty;\n\n            int displayIndex = index - this.ScrollValue;\n            int y = displayIndex * this.ItemHeight;\n            y += (index - _displayRangeMin) * 1;\n            return new Rectangle(0, y, this.ItemsRectangle.Width, this.ItemHeight);\n        }\n\n        #endregion\n\n        #region 事件处理\n\n        private void panelItem_MouseEnter(object sender, EventArgs e)\n        {\n            ////拿到焦点，以便 接收鼠标滚轮事件\n            //if (this.Focused == false)\n            //{\n            //    this.Focus();\n            //}\n        }\n\n        private void SERichComboBoxDropPanel_MouseWheel(object sender, MouseEventArgs e)\n        {\n            int value = this.ScrollValue;\n\n            if (e.Delta > 0)\n                value += -this.vScrollBar.LargeChange;\n            else\n                value += this.vScrollBar.LargeChange;\n\n            if (value >= this.ScrollMinimum && value <= this.ScrollMaximum)\n            {\n                this.ScrollValue = value;\n            }\n        }\n\n        private void panelItem_Paint(object sender, PaintEventArgs e)\n        {\n            DrawItems();\n        }\n\n        private void panelItem_MouseClick(object sender, MouseEventArgs e)\n        {\n            //if (this.Popup != null)\n            //    this.Popup.Close();\n\n            //if (this.OnClick != null)\n            //{\n            //    OnClick(this, new OnClickEventArgs(this.SelectedItemCount, this.ActionType));\n            //}\n\n            int index = GetMouseHotIndex(e.Y);\n            if (InDisplayRange(index))\n            {\n                if (index != SelectedIndex)\n                {\n                    SelectItem(index);\n                }\n\n                if (OnItemClick != null)\n                {\n                    OnItemClick(SelectedItem);\n                }\n            }\n        }\n\n        private void panelItem_MouseMove(object sender, MouseEventArgs e)\n        {\n            this._tempHotIndex = GetMouseHotIndex(e.Y);\n\n            if (this._hotIndex != this._tempHotIndex)\n            {\n                _hotIndex = GetMouseHotIndex(e.Y);\n                if (InDisplayRange(_hotIndex))\n                    this.HotedItem = _items[_hotIndex];\n            }\n        }\n\n        private void panelItem_MouseLeave(object sender, EventArgs e)\n        {\n            this.HotedItem = null;\n            this._hotIndex = -1;\n        }\n\n        private void panelItem_MouseHover(object sender, EventArgs e)\n        {\n            //_toolTip.Show(\"Test\", this.panelItem);\n        }\n\n        private void vScrollBar_ValueChanged(object sender, EventArgs e)\n        {\n            DrawItems();\n        }\n\n        //void item_OnItemClick(SEComboSelectorItem sender)\n        //{\n        //    if (sender != this.SelectedItem)\n        //    {\n        //        SelectedItem = sender;\n        //        //foreach (SEComboSelectorItem item in _items)\n        //        //{\n        //        //    if (item.Selected)\n        //        //        item.Selected = false;\n        //        //}\n        //        //sender.Selected = true;\n        //    }\n        //}\n\n        #endregion\n\n        #region 公开事件\n\n        public delegate void OnSelectedItemChangedHandler(ShengComboSelectorItem item);\n        /// <summary>\n        /// 单击（选择）项时发生\n        /// </summary>\n        public event OnSelectedItemChangedHandler OnSelectedItemChangedClick;\n\n        public delegate void OnHotedItemChangedHandler(ShengComboSelectorItem item);\n        /// <summary>\n        /// 当前热点项生改变\n        /// </summary>\n        public event OnHotedItemChangedHandler OnHotedItemChanged;\n\n        public delegate void OnItemClickHandler(ShengComboSelectorItem item);\n        /// <summary>\n        /// 单击项\n        /// </summary>\n        public event OnItemClickHandler OnItemClick;\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengComboSelector/ShengComboSelectorItemContainer.resx",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n</root>"
  },
  {
    "path": "Sheng.Winform.Controls/ShengComboSelector2/Enums.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nnamespace Sheng.Winform.Controls\n{\n    /// <summary>\n    /// Represents the visual state of an image list view item.\n    /// </summary>\n    [Flags]\n    public enum ShengComboSelectorState\n    {\n        /// <summary>\n        /// 没有任何选择状态，处于一般正常状态\n        /// </summary>\n        None = 0,\n        /// <summary>\n        /// 项处于选中状态\n        /// </summary>\n        Selected = 1,\n        /// <summary>\n        /// 鼠标滑过\n        /// </summary>\n        Hovered = 2,\n        //再加不要忘了是4\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengComboSelector2/ShengComboSelector2.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Drawing;\nusing System.Drawing.Drawing2D;\nusing Sheng.Winform.Controls.PopupControl;\nusing System.Collections;\nusing Sheng.Winform.Controls.Kernal;\nusing Sheng.Winform.Controls.Drawing;\nusing System.ComponentModel;\n\nnamespace Sheng.Winform.Controls\n{\n    /*\n     * 控件的高度根据内容自动调整，忽略外部设置\n     */\n    public class ShengComboSelector2 : Control, IShengValidate\n    {\n        #region 私有成员\n\n        /// <summary>\n        /// 边框宽度\n        /// </summary>\n        const int _borderSize = 1;\n\n        /*\n         * 下拉框弹出之后，再次点击控件，下拉框又会闪出来\n         * 是因为点控件，下拉框自动关闭，但因为点了控件，所以下拉框又会闪出来\n         * 所以在下拉框关闭时，记下时间，点击时判断与上次下拉框关闭时的时间间隔\n         * 如果过小，就不打开下拉框\n         */\n        private DateTime _dropDownHideTime;\n\n        private Popup _popup;\n        private ShengListView _listView;\n\n        #region 当前状态\n\n        private ShengComboSelectorState _state = ShengComboSelectorState.None;\n\n        private bool Selected\n        {\n            get\n            {\n                return (_state & ShengComboSelectorState.Selected) == ShengComboSelectorState.Selected;\n            }\n            set\n            {\n                bool selected = Selected;\n\n                if (value)\n                    _state = _state | ShengComboSelectorState.Selected;\n                else\n                    _state = _state ^ ShengComboSelectorState.Selected;\n\n                if (selected != Selected)\n                    Refresh();\n            }\n        }\n\n        private bool Hovered\n        {\n            get\n            {\n                return (_state & ShengComboSelectorState.Hovered) == ShengComboSelectorState.Hovered;\n            }\n            set\n            {\n                bool hovered = Hovered;\n\n                if (value)\n                    _state = _state | ShengComboSelectorState.Hovered;\n                else\n                    _state = _state ^ ShengComboSelectorState.Hovered;\n\n                if (hovered != Hovered)\n                    Refresh();\n            }\n        }\n\n        #endregion\n\n        #region 绘图表面\n\n        //箭头的大小是指的箭头的高度，宽度将是高度的2倍\n        private int _buttonSize =6;\n\n        /// <summary>\n        /// 文本和description文本之间的间距\n        /// </summary>\n        private int _textSpaceBetween = 2;\n\n        private TextFormatFlags _textFlags = TextFormatFlags.SingleLine | TextFormatFlags.WordEllipsis;\n\n        #endregion\n\n        #endregion\n\n        #region 公开属性\n\n        private int _maxItem = 5;\n        /// <summary>\n        /// 最大显示的项数\n        /// </summary>\n        public int MaxItem\n        {\n            get { return _maxItem; }\n            set { _maxItem = value; }\n        }\n\n        private ShengComboSelectorTheme _theme = new ShengComboSelectorTheme();\n        public ShengComboSelectorTheme Theme\n        {\n            get { return _theme; }\n            set { _theme = value; }\n        }\n\n        private bool _showDescription = true;\n        /// <summary>\n        /// 是否显示说明字段，此属性不影响弹出面板是否显示\n        /// 弹出面板是否显示由DescriptionMember是否设置决定\n        /// </summary>\n        public bool ShowDescription\n        {\n            get { return _showDescription; }\n            set\n            {\n                _showDescription = value;\n                this.Height = MeasureHeight();\n            }\n        }\n\n        public string DisplayMember\n        {\n            get { return _listView.DisplayMember; }\n            set { _listView.DisplayMember = value; }\n        }\n\n        private string _descriptionMember;\n        public string DescriptionMember\n        {\n            get { return _descriptionMember; }\n            set\n            {\n                _descriptionMember = value;\n                _listView.SetExtendMember(ShengListViewDescriptiveMembers.DescriptioinMember, value);\n            }\n        }\n\n        /// <summary>\n        /// 下拉列表的布局模式\n        /// </summary>\n        public ShengListViewLayoutMode LayoutMode\n        {\n            get { return _listView.LayoutMode; }\n            set { _listView.LayoutMode = value; }\n        }\n\n        public override Font Font\n        {\n            get\n            {\n                return base.Font;\n            }\n            set\n            {\n                base.Font = value;\n                this.Height = MeasureHeight();\n            }\n        }\n\n        #region 数据校验有关\n\n        private bool allowEmpty = true;\n        /// <summary>\n        /// 是否允许空\n        /// </summary>\n        [Description(\"是否允许空\")]\n        [Category(\"Sheng.Winform.Controls\")]\n        public bool AllowEmpty\n        {\n            get\n            {\n                return this.allowEmpty;\n            }\n            set\n            {\n                this.allowEmpty = value;\n            }\n        }\n\n        #endregion\n\n        #endregion\n\n        #region 构造\n\n        public ShengComboSelector2()\n        {\n            if (DesignMode)\n                return;\n\n            SetStyle(ControlStyles.ResizeRedraw, true);\n            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);\n            SetStyle(ControlStyles.Selectable, true);\n          \n            this.Padding = new System.Windows.Forms.Padding(5);\n\n            _listView = new ShengListView();\n            _listView.Padding = new System.Windows.Forms.Padding(0);\n            _listView.BorderStyle = BorderStyle.None;\n            _listView.AllowMultiSelection = false;\n            _listView.LayoutMode = ShengListViewLayoutMode.Descriptive;\n           \n            //SelectedItemChanaged事件不行，如果就点当前已选中的项，就关不掉下拉框了\n            _listView.Click += new EventHandler(_listView_Click);\n            _listView.SelectedItemChanaged += new EventHandler(_listView_SelectedItemChanaged);\n            _listView.ItemTextGetting += new EventHandler<ShengListViewGetItemTextEventArgs>(_listView_ItemTextGetting);\n\n            _popup = new Popup(_listView);          \n            _popup.Closed += new ToolStripDropDownClosedEventHandler(_popup_Closed);\n\n            this._dropDownHideTime = DateTime.UtcNow;\n\n            ApplyTheme();\n        }\n\n        #endregion\n\n        #region 事件处理\n\n        void _listView_Click(object sender, EventArgs e)\n        {\n            _popup.Close();\n        }\n\n        void _listView_SelectedItemChanaged(object sender, EventArgs e)\n        {\n            object value = GetSelectedValue();\n            OnSelectedValueChanged(value);\n        }\n\n        void _listView_ItemTextGetting(object sender, ShengListViewGetItemTextEventArgs e)\n        {\n            if (this.ItemTextGetting != null)\n            {\n                ItemTextGettingEventArgs args = new ItemTextGettingEventArgs(e.Item);\n                ItemTextGetting(this, args);\n                e.Text = args.Text;\n            }\n        }\n\n        void _popup_Closed(object sender, ToolStripDropDownClosedEventArgs e)\n        {\n            _dropDownHideTime = DateTime.UtcNow;\n\n            this.Selected = false;\n        }\n\n        #endregion\n\n        #region 方法\n\n        #region private\n\n        private void ApplyTheme()\n        {\n            this.BackColor = _theme.BackgroundColor;\n\n            _listView.Theme.HoverColorStart = _theme.HoveredBackColor;\n            _listView.Theme.HoverColorEnd = Color.FromArgb(125, _theme.HoveredBackColor);\n            _listView.Theme.ItemBorderColor = _theme.HoveredBorderColor;\n            _listView.Theme.SelectedColorStart = _theme.SelectedBackColor;\n            _listView.Theme.SelectedColorEnd = Color.FromArgb(125, _theme.HoveredBackColor);\n        }\n\n        private void OnSelectedValueChanged(object value)\n        {\n            //允许value为null\n            //从原来有选定的变为没选定了，事件肯定还是要触发的\n            if (this.SelectedValueChanged != null)\n            {\n                SelectedValueChanged(this, new OnSelectedValueChangedEventArgs(value));\n            }\n        }\n\n        /// <summary>\n        /// 测量当前控件应该的高度\n        /// </summary>\n        /// <returns></returns>\n        private int MeasureHeight()\n        {\n            int textHeight = this.FontHeight;\n\n            int height = _borderSize * 2 + textHeight + Padding.Top + Padding.Bottom;\n\n            if (ShowDescription)\n                height = height + textHeight + _textSpaceBetween;\n\n            return height;\n        }\n\n        /// <summary>\n        /// 整个可用的绘图表面\n        /// </summary>\n        private Rectangle GetBorderRectangle()\n        {\n            Rectangle rect = new Rectangle(this.ClientRectangle.Location, this.ClientRectangle.Size);\n            rect.Width--;\n            rect.Height--;\n            return rect;\n        }\n\n        private Rectangle GetContentRectangle()\n        {\n            Rectangle contentRectangle = GetBorderRectangle();\n            //return Rectangle.Inflate(contentRectangle, -1, -1);\n\n            contentRectangle.X += 1;\n            contentRectangle.Y += 1;\n            contentRectangle.Width -= 1;\n            contentRectangle.Height -= 1;\n\n            return contentRectangle;\n        }\n\n        /// <summary>\n        /// 右边按钮的绘图表面\n        /// </summary>\n        private Rectangle GetButtonAreaRectangle()\n        {\n            Rectangle clientRectangle = ClientRectangle;\n\n            Rectangle rectangle = new Rectangle();\n            //箭头的大小是指的箭头的高度，宽度将是高度的2倍\n            rectangle.Size = new Size(_buttonSize * 2, _buttonSize);\n            rectangle.Location = new Point(\n                 clientRectangle.Width - rectangle.Width - Padding.Right,\n                (clientRectangle.Height - rectangle.Height) / 2);\n            return rectangle;\n        }\n\n        private Rectangle GetTextRectangle()\n        {\n            Rectangle clientRectangle = GetContentRectangle();\n            Rectangle buttonRectangle = GetButtonAreaRectangle();\n            Rectangle textRectangle = new Rectangle();\n\n            textRectangle.Location = new Point(Padding.Left, clientRectangle.Y + Padding.Top);\n            textRectangle.Width = clientRectangle.Width - (clientRectangle.Width - buttonRectangle.Left)\n                - textRectangle.Left - 5; //多减5为字和按钮的间距\n            textRectangle.Height = this.FontHeight;\n\n            return textRectangle;\n        }\n\n        private Rectangle GetDescriptionRectangle()\n        {\n            Rectangle clientRectangle = GetContentRectangle();\n            Rectangle textRectangle = GetTextRectangle();\n            Rectangle buttonRectangle = GetButtonAreaRectangle();\n            Rectangle descriptionRectangle = new Rectangle();\n\n            int descriptionY = textRectangle.Y + textRectangle.Height + _textSpaceBetween;\n            descriptionRectangle.Location = new Point(Padding.Left, descriptionY);\n            descriptionRectangle.Width = clientRectangle.Width - (clientRectangle.Width - buttonRectangle.Left)\n                - descriptionRectangle.Left - 5; //多减5为字和按钮的间距\n            descriptionRectangle.Height = this.FontHeight;\n\n            return descriptionRectangle;\n        }\n\n        private void Render(Graphics g)\n        {\n            DrawBorderground(g);\n\n            DrawBackground(g);\n\n            DrawText(g);\n\n            DrawButton(g);\n\n            //DrawFocusRectangle(g);\n        }\n\n        /// <summary>\n        /// 绘制边框\n        /// </summary>\n        /// <param name=\"g\"></param>\n        private void DrawBorderground(Graphics g)\n        {\n            Rectangle borderRectangle = ClientRectangle;\n\n            //using (Pen borderPen = new Pen(Theme.BorderColor))\n            //{\n            //    g.DrawRectangle(borderPen, borderRectangle);\n            //}\n\n            Brush brush;\n\n            if (this.Selected)\n                brush =  _theme.CreateSelectedBorderBrush(borderRectangle);\n            else if(this.Hovered)\n                brush = _theme.CreateHoveredBorderBrush(borderRectangle);\n            else\n                brush = _theme.CreateBorderBrush(borderRectangle);\n\n            g.FillRectangle(brush, borderRectangle);\n\n            Rectangle rectangle = borderRectangle;\n            rectangle.X += 1;\n            rectangle.Y += 1;\n            rectangle.Width -= 2;\n            rectangle.Height -= 2;\n\n            g.FillRectangle(Brushes.White, rectangle);\n        }\n\n        /// <summary>\n        /// 绘制背景\n        /// </summary>\n        /// <param name=\"g\"></param>\n        private void DrawBackground(Graphics g)\n        {\n            Rectangle rectangle = GetContentRectangle();\n\n            if (this.Hovered && this.Selected == false)\n            {\n                //留出一个白色的内框\n                rectangle.X += 1;\n                rectangle.Y += 1;\n                rectangle.Width -= 2;\n                rectangle.Height -= 2;\n            }\n\n            Brush brush = null;\n\n            if (this.Enabled)\n            {\n                if (this.Selected)\n                    brush = _theme.CreateSelectedBackgroundBrush(rectangle);\n                else if (this.Hovered)\n                    brush = _theme.CreateHoveredBackgroundBrush(rectangle);\n                else\n                {\n                    //在正常状态下，还是要把指定的控件背景色考虑进去\n                    //比如在验证控件数据的时候，不合法数据会有一个突出的颜色显示\n                    //如现在会把不合法数据的控件背景色改成粉色\n                    using (Brush normalBackgroundBrush = new SolidBrush(this.BackColor))\n                    {\n                        g.FillRectangle(normalBackgroundBrush, rectangle);\n                    }\n                    //这个CreateBackgroundBrush上面大部分是透明色，下面是一个淡灰色\n                    brush = _theme.CreateBackgroundBrush(rectangle);\n                }\n            }\n            else\n            {\n                brush = _theme.CreateDisabledBackgroundBrush(rectangle);\n            }\n\n            g.FillRectangle(brush, rectangle);\n        }\n\n        /// <summary>\n        /// 绘制文本\n        /// </summary>\n        /// <param name=\"g\"></param>\n        private void DrawText(Graphics g)\n        {\n            object selectedValue = GetSelectedValue();\n            if (selectedValue == null)\n                return;\n\n            #region 绘制标题文本\n            \n            object textObj = ReflectionPool.GetPropertyValue(selectedValue, DisplayMember);\n            if (textObj != null)\n            {\n                string text = textObj.ToString();\n                if (text != String.Empty)\n                {\n                    Color textColor;\n                    if (this.Selected)\n                        textColor = _theme.SelectedTextColor;\n                    else if (this.Hovered)\n                        textColor = _theme.HoveredTextColor;\n                    else\n                        textColor = _theme.TextColor;\n\n                    Font textFont = new System.Drawing.Font(this.Font, FontStyle.Bold);\n                    Rectangle textRectangle = GetTextRectangle();\n                  //  g.FillRectangle(Brushes.Red, textRectangle);\n                    TextRenderer.DrawText(g, text, textFont, textRectangle, textColor, _textFlags);\n                }\n            }\n\n            #endregion\n\n            if (this.ShowDescription)\n            {\n                #region 绘制Description\n\n                object descriptionObj = ReflectionPool.GetPropertyValue(selectedValue, DescriptionMember);\n                if (descriptionObj != null)\n                {\n                    string description = descriptionObj.ToString();\n                    if (description != String.Empty)\n                    {\n                        Color textColor;\n                        if (this.Selected)\n                            textColor = _theme.SelectedDescriptionTextColor;\n                        else if (this.Hovered)\n                            textColor = _theme.HoveredDescriptionColor;\n                        else\n                            textColor = _theme.DescriptionTextColor;\n\n                        Rectangle descriptionRectangle = GetDescriptionRectangle();\n                        //    g.FillRectangle(Brushes.Red, descriptionRectangle);\n                        TextRenderer.DrawText(g, description, this.Font, descriptionRectangle, textColor, _textFlags);\n                    }\n                }\n\n                #endregion\n            }\n        }\n\n        private void DrawButton(Graphics g)\n        {\n            Rectangle rectangle = GetButtonAreaRectangle();\n          //  g.FillRectangle(Brushes.Red, rectangle);\n\n            int arrowX = rectangle.Left + (rectangle.Width - rectangle.Width / 2);\n            int arrowY = rectangle.Y;\n            Point startPoint = new Point(arrowX, arrowY);\n            Point endPoint = new Point(arrowX, arrowY + rectangle.Height);\n            GraphicsPath arrowPath = DrawingTool.GetArrowPath(startPoint, endPoint, rectangle.Height);\n\n            using (Brush arrowBrush = new LinearGradientBrush(rectangle,\n                _theme.ArrowColorStart, _theme.ArrowColorEnd, 45))\n            {\n                g.FillPath(arrowBrush, arrowPath);\n            }\n\n            arrowPath.Dispose();\n        }\n\n        private void DrawFocusRectangle(Graphics g)\n        {\n            if (this.Focused)\n                ControlPaint.DrawFocusRectangle(g, GetBorderRectangle());\n        }\n\n        #endregion\n\n        #region protected\n\n        protected override void OnSizeChanged(EventArgs e)\n        {\n            this.Height = MeasureHeight();\n            base.OnSizeChanged(e);\n        }\n\n        protected override void OnPaintBackground(PaintEventArgs pevent)\n        {\n            pevent.Graphics.Clear(_theme.BackgroundColor);\n           // base.OnPaintBackground(pevent);\n        }\n\n        protected override void OnPaint(PaintEventArgs e)\n        {\n            Render(e.Graphics);\n        }\n\n        protected override void OnMouseEnter(EventArgs e)\n        {\n            if (this.Enabled)\n            {\n                this.Hovered = true;\n            }\n\n            base.OnMouseEnter(e);\n        }\n\n        protected override void OnMouseLeave(EventArgs e)\n        {\n            if (this.Enabled)\n            {\n                //if (_popup.Visible == false)\n                //{\n                    this.Hovered = false;\n                //}\n            }\n\n            base.OnMouseLeave(e);\n        }\n\n        protected override void OnEnter(EventArgs e)\n        {\n            //this.Selected = true;\n            base.OnEnter(e);\n        }\n\n        protected override void OnLeave(EventArgs e)\n        {\n\n            //this.Selected = false;\n            base.OnLeave(e);\n        }\n\n        protected override void OnGotFocus(EventArgs e)\n        {\n            this.Refresh();\n            base.OnGotFocus(e);\n        }\n\n        protected override void OnLostFocus(EventArgs e)\n        {\n            this.Refresh();\n            base.OnLostFocus(e);\n        }\n\n        protected override void OnMouseDown(MouseEventArgs e)\n        {\n            base.OnMouseDown(e);\n\n            this.Focus();\n\n            if ((DateTime.UtcNow - _dropDownHideTime).TotalSeconds > 0.2)\n            {\n                Selected = true;\n                ShowDropDown();\n            }\n        }\n\n        private void ShowDropDown()\n        {\n            //每次打开都要判读，如果把PopupWidth做成属性，在set里设置\n            //那么控件resize时，popup的宽度可能就不对了\n            _popup.Width = this.Width;\n\n            int showItem = 1;\n            int itemCount = _listView.Items.Count;\n\n            if (itemCount > this.MaxItem)\n                showItem = this.MaxItem;\n            else if (itemCount == 0)\n                showItem = 1;\n            else\n                showItem = itemCount;\n\n            _popup.Height = showItem * _listView.ItemHeight;\n\n            _popup.Height =  _listView.Height;\n\n            _popup.Show(this);\n\n            _popup.Select();\n        }\n\n\n        #endregion\n\n        #region public\n\n        public void DataBind(IList dataSource)\n        {\n            _listView.DataBind(dataSource);\n            this.Refresh();\n        }\n\n        public object GetSelectedValue()\n        {\n            return _listView.GetSelectedValue();\n        }\n\n        public void SetSelectedValue(object obj)\n        {\n            _listView.SetSelectedValue(obj);\n        }\n\n        public void Clear()\n        {\n            _listView.Clear();\n            this.Refresh();\n        }\n\n        #endregion\n\n        #endregion\n\n        #region 公开事件\n\n        /// <summary>\n        /// 当前热点项生改变\n        /// </summary>\n        public event EventHandler<OnSelectedValueChangedEventArgs> SelectedValueChanged;\n\n        public class OnSelectedValueChangedEventArgs:EventArgs\n        {\n            private object _value;\n            public object Value\n            {\n                get { return _value; }\n            }\n\n            public OnSelectedValueChangedEventArgs(object value)\n            {\n                _value = value;\n            }\n        }\n\n        /// <summary>\n        /// 通过外能事件获取用于绘制项的文本\n        /// </summary>\n        public event EventHandler<ItemTextGettingEventArgs> ItemTextGetting;\n\n        public class ItemTextGettingEventArgs : EventArgs\n        {\n            public object Item { get; private set; }\n\n            public string Text { get; set; }\n\n            public ItemTextGettingEventArgs(object item)\n            {\n                Item = item;\n            }\n        }\n\n        #endregion\n\n        #region ISEValidate 成员\n\n        private string title;\n        /// <summary>\n        /// 标题\n        /// </summary>\n        [Description(\"标题\")]\n        [Category(\"Sheng.Winform.Controls\")]\n        public string Title\n        {\n            get\n            {\n                return this.title;\n            }\n            set\n            {\n                this.title = value;\n            }\n        }\n\n        private bool highLight = true;\n        /// <summary>\n        /// 验证失败时是否需要高亮显示（改变背景色）\n        /// </summary>\n        [Description(\"验证失败时是否需要高亮显示（改变背景色）\")]\n        [Category(\"Sheng.Winform.Controls\")]\n        public bool HighLight\n        {\n            get\n            {\n                return this.highLight;\n            }\n            set\n            {\n                this.highLight = value;\n            }\n        }\n\n        public bool SEValidate(out string msg)\n        {\n            msg = String.Empty;\n\n            if (this.AllowEmpty == false && this.GetSelectedValue() == null)\n            {\n                msg += String.Format(\"[ {0} ] {1}\", this.Title, \"不允许为空\");\n                return false;\n            }\n\n            #region CustomValidate\n\n            if (CustomValidate != null)\n            {\n                string customValidateMsg;\n                if (CustomValidate(this, out customValidateMsg) == false)\n                {\n                    msg += String.Format(\"[ {0} ] {1}\", this.Title, customValidateMsg);\n                    return false;\n                }\n            }\n\n            #endregion\n\n            return true;\n        }\n\n        public CustomValidateMethod CustomValidate\n        {\n            get;\n            set;\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengComboSelector2/ShengComboSelectorTheme.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Drawing;\nusing System.Drawing.Drawing2D;\n\nnamespace Sheng.Winform.Controls\n{\n    public class ShengComboSelectorTheme\n    {\n        private Color _arrowColorStart = Color.Gray;// Color.FromArgb(255, SystemColors.Highlight);\n        /// <summary>\n        /// 排序箭头开始颜色\n        /// </summary>\n        public Color ArrowColorStart\n        {\n            get { return _arrowColorStart; }\n            set { _arrowColorStart = value; }\n        }\n\n        private Color _arrowColorEnd = Color.LightGray;// Color.FromArgb(16, SystemColors.Highlight);\n        /// <summary>\n        /// 排序箭头开始颜色\n        /// </summary>\n        public Color ArrowColorEnd\n        {\n            get { return _arrowColorEnd; }\n            set { _arrowColorEnd = value; }\n        }\n\n        #region Selected\n\n        private Color _selectedTextColor = SystemColors.WindowText;\n        public Color SelectedTextColor\n        {\n            get\n            {\n                return _selectedTextColor;\n            }\n            set\n            {\n                _selectedTextColor = value;\n            }\n        }\n\n        private Color _selectedDescriptionTextColor = SystemColors.GrayText;\n        public Color SelectedDescriptionTextColor\n        {\n            get\n            {\n                return _selectedDescriptionTextColor;\n            }\n            set\n            {\n                _selectedDescriptionTextColor = value;\n            }\n        }\n\n        private Color _selectedBackColor = Color.FromArgb(255, 216, 107);\n        public Color SelectedBackColor\n        {\n            get\n            {\n                return _selectedBackColor;\n            }\n            set\n            {\n                _selectedBackColor = value;\n            }\n        }\n\n        private Color _selectedBorderColor = Color.FromArgb(194, 138, 48);\n        public Color SelectedBorderColor\n        {\n            get\n            {\n                return _selectedBorderColor;\n            }\n            set\n            {\n                _selectedBorderColor = value;\n            }\n        }\n\n        #endregion\n\n        #region Hovered\n\n        private Color _hoveredTextColor = SystemColors.WindowText;\n        public Color HoveredTextColor\n        {\n            get\n            {\n                return _hoveredTextColor;\n            }\n            set\n            {\n                _hoveredTextColor = value;\n            }\n        }\n\n        private Color _hoveredDescriptionTextColor = SystemColors.GrayText;\n        public Color HoveredDescriptionColor\n        {\n            get\n            {\n                return _hoveredDescriptionTextColor;\n            }\n            set\n            {\n                _hoveredDescriptionTextColor = value;\n            }\n        }\n\n        /*\n         * 淡蓝色\n         *  seComboSelectorTheme1.HoveredBackColor =\n         *   System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(232)))), ((int)(((byte)(246)))));\n            seComboSelectorTheme1.HoveredBorderColor = \n         * System.Drawing.Color.FromArgb(((int)(((byte)(152)))), ((int)(((byte)(180)))), ((int)(((byte)(226)))));\n         */\n\n        private Color _hoveredBackColor = Color.FromArgb(254, 228, 134);\n        public Color HoveredBackColor\n        {\n            get\n            {\n                return _hoveredBackColor;\n            }\n            set\n            {\n                _hoveredBackColor = value;\n            }\n        }\n\n        private Color _hoveredBorderColor = Color.FromArgb(242, 202, 88);\n        public Color HoveredBorderColor\n        {\n            get\n            {\n                return _hoveredBorderColor;\n            }\n            set\n            {\n                _hoveredBorderColor = value;\n            }\n        }\n\n        #endregion\n\n        #region Normal\n\n        private Color _backgroundColor = Color.White;\n        /// <summary>\n        /// 控件的背景画布颜色\n        /// 因为控件的边框和过度色都有依靠改变透明度实现渐变，所以一个白色的底版就非常重要\n        /// 使过度色不受控件本身背景色的影响，光不绘制背景不行，要刷上白色背景\n        /// </summary>\n        public Color BackgroundColor\n        {\n            get { return _backgroundColor; }\n            set { _backgroundColor = value; }\n        }\n\n        private Color _backColor = Color.Gray;\n        /// <summary>\n        /// 控件背景色\n        /// </summary>\n        public Color BackColor\n        {\n            get { return _backColor; }\n            set { _backColor = value; }\n        }\n\n        private Color _textColor = SystemColors.WindowText;\n        public Color TextColor\n        {\n            get\n            {\n                return _textColor;\n            }\n            set\n            {\n                _textColor = value;\n            }\n        }\n\n        private Color _descriptionTextColor = SystemColors.GrayText;\n        public Color DescriptionTextColor\n        {\n            get\n            {\n                return _descriptionTextColor;\n            }\n            set\n            {\n                _descriptionTextColor = value;\n            }\n        }\n\n        private Color _borderColor = Color.LightGray;\n        /// <summary>\n        /// 边框颜色\n        /// </summary>\n        public Color BorderColor\n        {\n            get\n            {\n                return _borderColor;\n            }\n            set\n            {\n                _borderColor = value;\n            }\n        }\n\n        #endregion\n\n        public Brush CreateDisabledBackgroundBrush(Rectangle bounds)\n        {\n            return Office2010Renderer.CreateDisabledBackgroundBrush(bounds,_borderColor);\n        }\n\n        public Brush CreateBackgroundBrush(Rectangle bounds)\n        {\n            return Office2010Renderer.CreateBackgroundBrush(bounds, _backColor);\n        }\n\n        public Brush CreateBorderBrush(Rectangle bounds)\n        {\n            return Office2010Renderer.CreateBorderBrush(bounds, _borderColor);\n        }\n\n        public Brush CreateHoveredBackgroundBrush(Rectangle bounds)\n        {\n            return Office2010Renderer.CreateHoveredBackgroundBrush(bounds, _hoveredBackColor);\n        }\n\n        public Brush CreateHoveredBorderBrush(Rectangle bounds)\n        {\n            return Office2010Renderer.CreateHoveredBorderBrush(bounds, _hoveredBorderColor);\n        }\n\n        public Brush CreateSelectedBackgroundBrush(Rectangle bounds)\n        {\n            return Office2010Renderer.CreateSelectedBackgroundBrush(bounds, _selectedBackColor);\n        }\n\n        public Brush CreateSelectedBorderBrush(Rectangle bounds)\n        {\n            return Office2010Renderer.CreateSelectedBorderBrush(bounds, _selectedBorderColor);\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengDataGridView/Renderer/IShengDataGridViewCellRenderer.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Drawing;\n\nnamespace Sheng.Winform.Controls\n{\n    /// <summary>\n    /// 与 DataGridViewRenderer 配合使用的单元格渲染器\n    /// 负责绘制单元格的内容部分\n    /// </summary>\n    interface IShengDataGridViewCellRenderer\n    {\n        Type RenderCellType { get; }\n\n        // clipBounds :System.Drawing.Rectangle，它表示需要重新绘制的 System.Windows.Forms.DataGridView 区域\n        void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds,\n            int rowIndex, DataGridViewElementStates elementState, object value,\n            object formattedValue, string errorText, DataGridViewCellStyle cellStyle);\n    }\n}"
  },
  {
    "path": "Sheng.Winform.Controls/ShengDataGridView/Renderer/ShengDataGridViewCheckBoxCellRenderer.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Drawing;\nusing System.Windows.Forms.VisualStyles;\n\nnamespace Sheng.Winform.Controls\n{\n    class ShengDataGridViewCheckBoxCellRenderer : IShengDataGridViewCellRenderer\n    {\n        #region IDataGridViewCellRenderer 成员\n\n        private Type _renderCellType = typeof(DataGridViewCheckBoxCell);\n        public Type RenderCellType\n        {\n            get { return _renderCellType; }\n        }\n\n        public void Paint(System.Drawing.Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex,\n            DataGridViewElementStates elementState, object value, object formattedValue, string errorText,\n            DataGridViewCellStyle cellStyle)\n        {\n            CheckBoxState checkBoxState = CheckBoxState.UncheckedDisabled;\n            //value可能为 DBNull,如从数据库写数据或数据来自dataTable，所以要判断 is bool\n            //如果value 为null的话,is bool会返回false的，所以不用专门判断是否为null了\n            if (value is bool && Convert.ToBoolean(value))\n            {\n                checkBoxState = CheckBoxState.CheckedDisabled;\n            }\n\n            Size checkBoxSize = CheckBoxRenderer.GetGlyphSize(graphics, checkBoxState);\n            Point drawInPoint = new Point(cellBounds.X + cellBounds.Width / 2 - checkBoxSize.Width / 2,\n                cellBounds.Y + cellBounds.Height / 2 - checkBoxSize.Height / 2);\n            CheckBoxRenderer.DrawCheckBox(graphics, drawInPoint, checkBoxState);\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengDataGridView/Renderer/ShengDataGridViewImageCellRenderer.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Drawing;\nusing System.Windows.Forms.VisualStyles;\nusing System.Diagnostics;\nusing Sheng.Winform.Controls.Drawing;\n\nnamespace Sheng.Winform.Controls\n{\n    class ShengDataGridViewImageCellRenderer : IShengDataGridViewCellRenderer\n    {\n        #region IDataGridViewCellRenderer 成员\n\n        private Type _renderCellType = typeof(DataGridViewImageCell);\n        public Type RenderCellType\n        {\n            get { return _renderCellType; }\n        }\n\n        public void Paint(System.Drawing.Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex,\n            DataGridViewElementStates elementState, object value, object formattedValue, string errorText,\n            DataGridViewCellStyle cellStyle)\n        {\n            if (value == null)\n                return;\n\n            if ((value is Image) == false)\n            {\n                Debug.Assert(false, \"value 不是 Image\");\n                return;\n            }\n\n            //如果需要缩放的话，在绘制完毕后，将缩放的图像释放\n            //Value是单元格的图像，这里不应，也不能直接释放\n            Image image = (Image)value;\n            bool scaleImage = false;\n            if (image.Width > cellBounds.Width || image.Height > cellBounds.Height)\n            {\n                scaleImage = true;\n                int imageWidth = cellBounds.Width - 2;\n                int imageHeight = cellBounds.Height - 2;\n                image = DrawingTool.GetScaleImage(image, imageWidth, imageHeight);\n            }\n\n            Point drawInPoint = new Point(cellBounds.X + cellBounds.Width / 2 - image.Width / 2,\n                cellBounds.Y + cellBounds.Height / 2 - image.Height / 2);\n\n            graphics.DrawImage(image, new Rectangle(drawInPoint,image.Size));\n\n            if (scaleImage)\n                image.Dispose();\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengDataGridView/Renderer/ShengDataGridViewRenderer.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Drawing;\nusing System.Drawing.Drawing2D;\nusing System.Diagnostics;\nusing Sheng.Winform.Controls.Drawing;\n\nnamespace Sheng.Winform.Controls\n{\n    /// <summary>\n    /// DataGridView 必须打开双倍缓冲，否则闪烁 \n    /// </summary>\n    class ShengDataGridViewRenderer\n    {\n        #region 私有成员\n\n        private DataGridView _dataGridView;\n\n        /// <summary>\n        /// 当前热点行\n        /// </summary>\n        private DataGridViewRow _hoveredRow;\n\n        private ShengDataGridViewRendererTheme _theme = new ShengDataGridViewRendererTheme();\n\n        /// <summary>\n        /// 总列数\n        /// </summary>\n        private int _columnsCount\n        {\n            get { return _dataGridView.Columns.Count; }\n        }\n\n        /// <summary>\n        /// DataGridView的字体\n        /// </summary>\n        private Font _font\n        {\n            get { return _dataGridView.Font; }\n        }\n\n        private StringFormat _cellTextStringFormat = new StringFormat();\n\n        private StringFormat _columnHeaderTextStringFormat = new StringFormat();\n\n        private List<IShengDataGridViewCellRenderer> _cellRenderers = new List<IShengDataGridViewCellRenderer>();\n\n        #endregion\n\n        #region 构造\n\n        public ShengDataGridViewRenderer(DataGridView dataGridView)\n        {\n            AddCellRenderer(new ShengDataGridViewCheckBoxCellRenderer());\n            AddCellRenderer(new ShengDataGridViewImageCellRenderer());\n\n            _cellTextStringFormat.FormatFlags = StringFormatFlags.NoWrap;\n            _columnHeaderTextStringFormat.FormatFlags = StringFormatFlags.NoWrap;\n\n            _dataGridView = dataGridView;\n\n            _dataGridView.Scroll += new ScrollEventHandler(_dataGridView_Scroll);\n            _dataGridView.MouseMove += new MouseEventHandler(_dataGridView_MouseMove);\n            _dataGridView.MouseLeave += new EventHandler(_dataGridView_MouseLeave);\n            _dataGridView.CellPainting += new DataGridViewCellPaintingEventHandler(_dataGridView_CellPainting);\n            _dataGridView.GotFocus += new EventHandler(_dataGridView_GotFocus);\n            _dataGridView.LostFocus += new EventHandler(_dataGridView_LostFocus);\n        }\n\n        #endregion\n\n        #region 事件处理\n\n        private void _dataGridView_Scroll(object sender, ScrollEventArgs e)\n        {\n            Point mousePosition = _dataGridView.PointToClient(Cursor.Position);\n            MouseEventArgs args = new MouseEventArgs(MouseButtons.None, 0, mousePosition.X, mousePosition.Y, 0);\n            _dataGridView_MouseMove(_dataGridView, args);\n        }\n\n        private void _dataGridView_MouseLeave(object sender, EventArgs e)\n        {\n            if (_hoveredRow != null)\n            {\n                int rowIndex = _hoveredRow.Index;\n                _hoveredRow = null;\n                DrawRow(rowIndex);\n            }\n        }\n\n        private void _dataGridView_MouseMove(object sender, MouseEventArgs e)\n        {\n            DataGridViewRow oldHoveredRow = _hoveredRow;\n            Point pt = e.Location;\n            int firstDisplayedScrollingRowIndex = _dataGridView.FirstDisplayedScrollingRowIndex;\n            int displayedRowCount = _dataGridView.DisplayedRowCount(true);\n            for (int i = firstDisplayedScrollingRowIndex; i < displayedRowCount + firstDisplayedScrollingRowIndex; i++)\n            {\n                Rectangle rowRectangle = GetRowDisplayRectangle(i);\n                \n                if (rowRectangle.Contains(pt))\n                {\n                    _hoveredRow = _dataGridView.Rows[i];\n                    break;\n                }\n                else\n                {\n                    _hoveredRow = null;\n                }\n            }\n            if (oldHoveredRow != _hoveredRow)\n            {\n                if (oldHoveredRow != null)\n                    DrawRow(oldHoveredRow.Index);\n                if (_hoveredRow != null)\n                    DrawRow(_hoveredRow.Index);\n            }\n        }\n\n        private void _dataGridView_GotFocus(object sender, EventArgs e)\n        {\n            _dataGridView.Refresh();\n        }\n\n        private void _dataGridView_LostFocus(object sender, EventArgs e)\n        {\n            _dataGridView.Refresh();\n        }\n\n        private void _dataGridView_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)\n        {\n            DrawCell(e.Graphics, e.CellBounds, e.RowIndex, e.ColumnIndex, e.Value, e.State);\n            e.Handled = true;\n        }\n\n        #endregion\n\n        #region 私有方法\n\n        private void DrawCell(Graphics g, Rectangle bounds, int rowIndex, int columnIndex, object value,\n            DataGridViewElementStates state)\n        {\n            if (columnIndex < 0)\n                return;\n\n            g.SetClip(bounds);\n\n            //表头\n            if (rowIndex == -1)\n            {\n                string headerText = null;\n                if (value != null) headerText = value.ToString();\n                DrawColumnHeader(g, bounds, columnIndex, headerText);\n            }\n            //行头\n            else if (columnIndex == -1)\n            {\n                DrawRowHeader(g, bounds, state);\n\n            }\n            //一般行\n            else\n            {\n                DrawRowCell(g, bounds, rowIndex, columnIndex, value, state);\n            }\n        }\n\n        /// <summary>\n        /// 绘制表头\n        /// </summary>\n        /// <param name=\"g\"></param>\n        /// <param name=\"bounds\"></param>\n        /// <param name=\"headerText\"></param>\n        private void DrawColumnHeader(Graphics g, Rectangle bounds, int columnIndex,string headerText)\n        {\n            DataGridViewColumnHeaderCell headerCell = _dataGridView.Columns[columnIndex].HeaderCell;\n\n            Rectangle contentBounds = bounds;\n            int contentBoundsX = contentBounds.X;\n            int contentBoundsY = contentBounds.Y;\n            int contentBoundsWidth = contentBounds.Width;\n            int contentBoundsHeight = contentBounds.Height;\n\n            #region 绘制背景\n\n            //绘制背景\n            using (LinearGradientBrush brush = new LinearGradientBrush(bounds, _theme.ColumnHeaderBackColorStart,\n                _theme.ColumnHeaderBackColorEnd, LinearGradientMode.Vertical))\n            {\n                g.FillRectangle(brush, bounds);\n            }\n\n            #endregion\n\n            #region 绘制文本\n\n            //绘制文本\n            if (String.IsNullOrEmpty(headerText) == false)\n            {\n                SizeF textSize = g.MeasureString(headerText, _font);\n\n                RectangleF textBounds = new RectangleF();\n                textBounds.X = contentBoundsX + 2;\n                textBounds.Y = bounds.Y + (bounds.Height - textSize.Height) / 2;\n                textBounds.Width = bounds.Width - 4;\n                textBounds.Height = textSize.Height;\n\n                Brush textBrush = new SolidBrush(_theme.ColumnHeaderTextColor);\n                g.DrawString(headerText, _dataGridView.Font, textBrush, textBounds, _columnHeaderTextStringFormat);\n                textBrush.Dispose();\n            }\n\n            #endregion\n\n            #region 在右侧绘制分隔线\n\n            Rectangle separatorBounds = new Rectangle();\n            separatorBounds.X = contentBoundsX + contentBoundsWidth - 1;\n            separatorBounds.Y = contentBoundsY;\n            separatorBounds.Width = 1;\n            separatorBounds.Height = contentBoundsHeight;\n\n            Brush separatorBrush = new LinearGradientBrush(separatorBounds,\n                _theme.ColumnHeaderSeparatorColorStart, _theme.ColumnHeaderSeparatorColorEnd, LinearGradientMode.Vertical);\n\n            g.FillRectangle(separatorBrush, separatorBounds);\n            \n            separatorBrush.Dispose();\n\n            #endregion\n\n            #region 绘制排序箭头\n\n            //如果列排序了，在单元格中间靠顶部绘制，类似win7资源管理器中的列排序箭头绘制\n\n            if (headerCell.SortGlyphDirection != SortOrder.None)\n            {\n                int arrowLength = 5;\n                int arrowX = contentBoundsX + contentBoundsWidth / 2; //箭头中间的坐标\n                int arrowYOffset = 0;  //绘制箭头的Y坐标\n                int arrowYStart = 0;  //箭头本身的Y轴开始坐标\n                int arrowYEnd = 0;   //箭头本身的Y轴结束坐标\n                switch (headerCell.SortGlyphDirection)\n                {\n                    case SortOrder.Ascending: //▲\n                        arrowYStart = arrowLength + arrowYOffset ;\n                        arrowYEnd = arrowYOffset;\n                        break;\n                    case SortOrder.Descending:\n                        arrowYStart = arrowYOffset;\n                        arrowYEnd = arrowLength + arrowYOffset;\n                        break;\n                }\n\n                PointF startPoint = new PointF(arrowX, arrowYStart);\n                PointF endPoint = new PointF(arrowX, arrowYEnd);\n                GraphicsPath arrowPath = DrawingTool.GetArrowPath(startPoint, endPoint, arrowLength);\n                //用于填充的Rectangle必须是Graphics的实际呈现区域\n                Rectangle arrowBrushRectangle = new Rectangle(arrowX - arrowLength/2, 0, arrowLength, arrowLength);\n                Brush arrowBrush = new LinearGradientBrush(arrowBrushRectangle,\n                    _theme.ArrowColorStart, _theme.ArrowColorEnd, 45);\n                g.FillPath(arrowBrush, arrowPath);\n                arrowPath.Dispose();\n                arrowBrush.Dispose();\n            }\n\n            #endregion\n        }\n\n        /// <summary>\n        /// 绘制行头\n        /// </summary>\n        /// <param name=\"g\"></param>\n        /// <param name=\"bounds\"></param>\n        private void DrawRowHeader(Graphics g, Rectangle bounds, DataGridViewElementStates state)\n        {\n            g.Clear(_theme.RowHeaderColor);\n        }\n\n        /// <summary>\n        /// 绘制行中的单元格\n        /// </summary>\n        /// <param name=\"g\"></param>\n        /// <param name=\"bounds\"></param>\n        /// <param name=\"value\"></param>\n        /// <param name=\"state\"></param>\n        private void DrawRowCell(Graphics g, Rectangle bounds, int rowIndex, int columnIndex, object value, DataGridViewElementStates state)\n        {\n            if (bounds == Rectangle.Empty)\n                return;\n\n            g.Clear(_theme.RowBackColor);\n\n            Rectangle contentBounds = bounds;\n            int contentBoundsX = contentBounds.X;\n            int contentBoundsY = contentBounds.Y;\n            int contentBoundsWidth = contentBounds.Width;\n            int contentBoundsHeight = contentBounds.Height;\n\n            bool selected = (state & DataGridViewElementStates.Selected) == DataGridViewElementStates.Selected;\n\n            #region 绘制选定或未选定情况下的单元格\n\n            if (selected)\n            {\n                Brush backBrush;\n                Pen borderPen;\n\n                if (_dataGridView.Focused)\n                {\n                    backBrush = new LinearGradientBrush(contentBounds, _theme.RowSelectedBackColorStart, _theme.RowSelectedBackColorEnd,\n                      LinearGradientMode.Vertical);\n                    borderPen = new Pen(_theme.RowSelectedBorderColor);\n                }\n                else\n                {\n                    backBrush = new LinearGradientBrush(contentBounds, _theme.RowUnFocusedSelectedColorStart, _theme.RowUnFocusedSelectedColorEnd,\n                      LinearGradientMode.Vertical);\n                    borderPen = new Pen(_theme.RowUnFocusedSelectedBorderColor);\n                }               \n\n                DrawRowCell(g, columnIndex, bounds, backBrush, borderPen);\n\n                backBrush.Dispose();\n                borderPen.Dispose();\n            }\n            else\n            {\n                using (Brush backBrush = new SolidBrush(_theme.RowBackColor))\n                {\n                    g.FillRectangle(backBrush, bounds);\n                }\n            }\n\n            #endregion\n\n            #region 绘制鼠标经过时的背景\n\n            if (_hoveredRow != null && rowIndex == _hoveredRow.Index)\n            {\n                Brush backBrush = new LinearGradientBrush(bounds, _theme.RowHoveredBackColorStart, _theme.RowHoveredBackColorEnd,\n                       LinearGradientMode.Vertical);\n                Pen borderPen = new Pen(_theme.RowHoveredBorderColor);\n\n                DrawRowCell(g, columnIndex, bounds, backBrush, borderPen);\n\n                backBrush.Dispose();\n                borderPen.Dispose();\n            }\n\n            #endregion\n\n            #region 绘制单元格的内容部分，如文本，checkbox，或图像\n\n            if (value != null)\n            {\n                DataGridViewCell cell = _dataGridView[columnIndex, rowIndex];\n                IShengDataGridViewCellRenderer cellRenderer = GetCellRenderer(cell);\n                if (cellRenderer != null)\n                {\n                    cellRenderer.Paint(g, _dataGridView.ClientRectangle, bounds, rowIndex, state, value,\n                        cell.FormattedValue, cell.ErrorText, cell.Style);\n                }\n                //如果没有找到匹配的单元格渲染器，绘制内容的文本形式\n                else\n                {\n                    string text = value.ToString();\n                    SizeF textSize = g.MeasureString(text, _font);\n                    RectangleF textBounds = new RectangleF();\n                    textBounds.X = contentBoundsX + 2;\n                    textBounds.Y = bounds.Y + (bounds.Height - textSize.Height) / 2;\n                    textBounds.Width = bounds.Width - 4;\n                    textBounds.Height = textSize.Height;\n\n                    using (SolidBrush fontBrush = new SolidBrush(_theme.RowTextColor))\n                    {\n                        g.DrawString(value.ToString(), _dataGridView.Font, fontBrush, textBounds, _cellTextStringFormat);\n                    }\n                }\n            }\n\n            #endregion\n\n        }\n\n        private void DrawRowCell(Graphics g, int columnIndex, Rectangle bounds, Brush backBrush, Pen borderPen)\n        {\n            Rectangle contentBounds = bounds;\n            int contentBoundsX = contentBounds.X;\n            int contentBoundsY = contentBounds.Y;\n            int contentBoundsWidth = contentBounds.Width;\n            int contentBoundsHeight = contentBounds.Height;\n\n            if (columnIndex == 0)\n            {\n                Rectangle startCellBounds = new Rectangle(contentBoundsX + 1, contentBoundsY, contentBoundsWidth, contentBoundsHeight);\n                g.FillRectangle(backBrush, startCellBounds);\n                Rectangle startCellBorderBounds = startCellBounds;\n                startCellBorderBounds.Height -= 1;\n                g.DrawRectangle(borderPen, startCellBorderBounds);\n            }\n            else if (columnIndex == _columnsCount - 1)\n            {\n                Rectangle endCellBounds = new Rectangle(contentBoundsX - 1, contentBoundsY, contentBoundsWidth, contentBoundsHeight);\n                g.FillRectangle(backBrush, endCellBounds);\n                Rectangle endCellBorderBounds = endCellBounds;\n                endCellBorderBounds.Height -= 1;\n                g.DrawRectangle(borderPen, endCellBorderBounds);\n            }\n            else\n            {\n                g.FillRectangle(backBrush, contentBounds);\n                g.DrawLine(borderPen, contentBoundsX, contentBoundsY,\n                    contentBoundsX + contentBoundsWidth, contentBoundsY);\n                g.DrawLine(borderPen, contentBoundsX, contentBoundsY + contentBoundsHeight - 1,\n                    contentBoundsX + contentBoundsWidth, contentBoundsY + contentBoundsHeight - 1);\n            }\n        }\n\n        private void DrawRow(int rowIndex)\n        {\n            _dataGridView.Refresh();\n            return;\n\n            #region \n\n            //经测试，直接调用Refresh方法，并没有效率上的问题\n            //而下面专门实现的代码，却有闪烁问题\n            //是否和 CreateGraphics 有关系？暂不深纠，就用_dataGridView.Refresh();\n            /*\n        //    Debug.Write(\"DrawRow(int rowIndex) : \" + rowIndex.ToString() + Environment.NewLine);\n\n            Graphics g = _dataGridView.CreateGraphics();\n            DataGridViewRow row = _dataGridView.Rows[rowIndex];\n            DataGridViewSelectedRowCollection selectedRows = _dataGridView.SelectedRows;\n            DataGridViewElementStates state = new DataGridViewElementStates();\n            if (selectedRows.Contains(row))\n            {\n                state = state | DataGridViewElementStates.Selected;\n            }\n            foreach (DataGridViewCell cell in row.Cells)\n            {\n                int columnIndex = cell.ColumnIndex;\n\n                //GetCellDisplayRectangle只能获取单元格被显示出来的部分，而不是整个单元格的Bounds\n                //即使传入 false参数也不管用，怀疑是该方法 Bug\n                Rectangle cellBounds = GetCellRectangle(columnIndex, rowIndex);\n                //Rectangle cellBounds = _dataGridView.GetCellDisplayRectangle(columnIndex, rowIndex, false);\n              //  Rectangle cellBounds = _dataGridView[columnIndex, rowIndex].ContentBounds;\n                //调GetCellDisplayRectangle方法取单元格的呈现区域，第一列的单元格X轴有一个像素的误差，原因不明\n                //if (columnIndex == 0)\n                //{\n                //    cellBounds.X -= 1;\n                //    cellBounds.Width += 1;\n                //}\n                if (cellBounds != Rectangle.Empty)\n                {\n                    object cellValue = cell.Value;\n                    g.SetClip(cellBounds);\n                    DrawCell(g, cellBounds, rowIndex, columnIndex, cellValue, state);\n                }\n            }\n\n            //重绘边框，因为在绘制X轴为负的单元格时，会覆盖掉原有的边框\n            g.SetClip(_dataGridView.ClientRectangle);\n            ControlPaint.DrawBorder(g,_dataGridView.ClientRectangle, Color.Black, 1,\n                ButtonBorderStyle.Solid, Color.Black, 1,ButtonBorderStyle.Solid, Color.Black, 1,\n                ButtonBorderStyle.Solid, Color.Black, 1, ButtonBorderStyle.Solid);\n            */\n\n            #endregion\n        }\n\n        /// <summary>\n        /// 获取单元格的完全绘制区域（完全不显示的单元格返回Rectangle.Empty）\n        /// </summary>\n        /// <param name=\"columnIndex\"></param>\n        /// <param name=\"rowIndex\"></param>\n        /// <returns></returns>\n        private Rectangle GetCellRectangle(int columnIndex, int rowIndex)\n        {\n            DataGridViewCell cell = _dataGridView[columnIndex, rowIndex];\n            Size cellSize = cell.Size;\n\n            //传false也无法取到完整的单元格区域，取得的结果与true一样\n            //此处就传true，不传false，防止以后微软修正这个bug之后这里的计算出现错误\n            Rectangle cellBounds = _dataGridView.GetCellDisplayRectangle(columnIndex, rowIndex, true);\n            //没有呈现单元格区域\n            if (cellBounds == Rectangle.Empty)\n                return cellBounds;\n            //如果完全呈现了单元格区域 或 完全没有呈现单元格区域，直接返回cellBounds\n            if (cellBounds.Size == cellSize)\n            {\n                return cellBounds;\n            }\n\n            //水平滚动条的偏移\n            int horizontalOffset = _dataGridView.HorizontalScrollingOffset;\n\n            //此单元格前面的单元格的宽度总计\n            int preColumnsWidth = 0;\n            for (int i = columnIndex-1; i >= 0; i--)\n            {\n                DataGridViewColumn column = _dataGridView.Columns[i];\n                if (column.Visible)\n                    preColumnsWidth += column.Width;\n            }\n\n            //目标单元的Rectangle：X坐标=cellBounds减(水平滚动条偏移减此单元格前面的单元格的宽度总计)\n            //但是如果 水平滚动条偏移减此单元格前面的单元格的宽度总计 得到的值小于0，则说明目标单元格的X坐标就在可视范围内\n            //超出可视范围的部分完全在控件的右侧，否则（大于0），则目标单元格的X轴坐标需要修正\n            int cellX = cellBounds.X;\n            int cellY = cellBounds.Y;\n            int cellXoffSet = horizontalOffset - preColumnsWidth;\n            if (cellXoffSet > 0)\n            {\n                cellX = cellX - cellXoffSet;\n            }\n\n            int cellWidth = cellBounds.Width + (cellSize.Width - cellBounds.Width);\n            int cellHeight = cellSize.Height;\n\n            Rectangle newCellBounds = new Rectangle(cellX, cellY, cellWidth, cellHeight);\n            return newCellBounds;\n        }\n\n        /// <summary>\n        /// 获取行的实际显示区域，不包括右边的空白（如果所有单元格的宽度加起来还是不到控件的宽度，那么右边的空白去掉）\n        /// _dataGridView.GetRowDisplayRectangle 不行，无论传true或false，都会把整个行可用区域返回\n        /// 就是说包括右边空白的，这个区域的宽度等于控件的宽度\n        /// </summary>\n        /// <param name=\"rowIndex\"></param>\n        /// <returns></returns>\n        private Rectangle GetRowDisplayRectangle(int rowIndex)\n        {\n            Rectangle rowRectangle = _dataGridView.GetRowDisplayRectangle(rowIndex, true);\n\n            int rowCellWidth = 0;\n            foreach (DataGridViewCell cell in _dataGridView.Rows[rowIndex].Cells)\n            {\n                rowCellWidth += cell.Size.Width;\n            }\n\n            if (rowRectangle.Width > rowCellWidth)\n            {\n                rowRectangle.Width = rowCellWidth;\n            }\n\n            return rowRectangle;\n        }\n\n        private IShengDataGridViewCellRenderer GetCellRenderer(DataGridViewCell cell)\n        {\n            Type cellType = cell.GetType();\n            foreach (var item in _cellRenderers)\n            {\n                if (item.RenderCellType.Equals(cellType) || cellType.IsSubclassOf(item.RenderCellType))\n                {\n                    return item;\n                }\n            }\n\n            return null;\n        }\n\n        #endregion\n\n        #region 公开方法\n\n        public void AddCellRenderer(IShengDataGridViewCellRenderer cellRenderer)\n        {\n            if (cellRenderer == null)\n            {\n                Debug.Assert(false, \"cellRenderer 为 null\");\n                return;\n            }\n\n            if (_cellRenderers.Contains(cellRenderer))\n            {\n                Debug.Assert(false, \"cellRenderer 已存在\");\n                return;\n            }\n\n            _cellRenderers.Add(cellRenderer);\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengDataGridView/Renderer/ShengDataGridViewRendererTheme.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Drawing;\n\nnamespace Sheng.Winform.Controls\n{\n    class ShengDataGridViewRendererTheme\n    {\n        private Color _backColor = SystemColors.Window;\n        /// <summary>\n        /// 控件背景色\n        /// </summary>\n        public Color BackColor\n        {\n            get { return _backColor; }\n            set { _backColor = value; }\n        }\n\n        private Color _columnHeaderBackColorStart = Color.WhiteSmoke;\n        /// <summary>\n        /// 列头颜色\n        /// </summary>\n        public Color ColumnHeaderBackColorStart\n        {\n            get { return _columnHeaderBackColorStart; }\n            set { _columnHeaderBackColorStart = value; }\n        }\n\n        private Color _columnHeaderBackColorEnd = Color.GhostWhite;\n        /// <summary>\n        /// 列头颜色\n        /// </summary>\n        public Color ColumnHeaderBackColorEnd\n        {\n            get { return _columnHeaderBackColorEnd; }\n            set { _columnHeaderBackColorEnd = value; }\n        }\n\n        private Color _columnHeaderTextColor = Color.Black;\n        /// <summary>\n        /// 列头文本颜色\n        /// </summary>\n        public Color ColumnHeaderTextColor\n        {\n            get { return _columnHeaderTextColor; }\n            set { _columnHeaderTextColor = value; }\n        }\n\n        private Color _columnHeaderSeparatorColorStart = Color.FromArgb(96, SystemColors.Highlight);\n        /// <summary>\n        /// 列头分隔条颜色\n        /// </summary>\n        public Color ColumnHeaderSeparatorColorStart\n        {\n            get { return _columnHeaderSeparatorColorStart; }\n            set { _columnHeaderSeparatorColorStart = value; }\n        }\n\n        private Color _columnHeaderSeparatorColorEnd = Color.Transparent;\n        public Color ColumnHeaderSeparatorColorEnd\n        {\n            get { return _columnHeaderSeparatorColorEnd; }\n            set { _columnHeaderSeparatorColorEnd = value; }\n        }\n\n        private Color _rowHeaderColor = SystemColors.Control;\n        /// <summary>\n        /// 行头颜色\n        /// </summary>\n        public Color RowHeaderColor\n        {\n            get { return _rowHeaderColor; }\n            set { _rowHeaderColor = value; }\n        }\n\n        private Color _rowBackColor = SystemColors.Window;\n        /// <summary>\n        /// 行背景色\n        /// </summary>\n        public Color RowBackColor\n        {\n            get { return _rowBackColor; }\n            set { _rowBackColor = value; }\n        }\n\n        private Color _rowSelectedBackColorStart = Color.FromArgb(16, SystemColors.Highlight);\n        /// <summary>\n        /// 行处于选中状态时的背景色\n        /// </summary>\n        public Color RowSelectedBackColorStart\n        {\n            get { return _rowSelectedBackColorStart; }\n            set { _rowSelectedBackColorStart = value; }\n        }\n\n        private Color _rowSelectedBackColorEnd = Color.FromArgb(64, SystemColors.Highlight);\n        /// <summary>\n        /// 行处于选中状态时的背景色\n        /// </summary>\n        public Color RowSelectedBackColorEnd\n        {\n            get { return _rowSelectedBackColorEnd; }\n            set { _rowSelectedBackColorEnd = value; }\n        }\n\n        private Color _rowSelectedBorderColor = Color.FromArgb(128, SystemColors.Highlight);\n        /// <summary>\n        /// 行处于选中状态时的边框颜色\n        /// </summary>\n        public Color RowSelectedBorderColor\n        {\n            get { return _rowSelectedBorderColor; }\n            set { _rowSelectedBorderColor = value; }\n        }\n\n        private Color _rowHoveredBackColorStart = Color.FromArgb(16, SystemColors.Highlight);\n        /// <summary>\n        /// 行处于热点状态时的背景色\n        /// </summary>\n        public Color RowHoveredBackColorStart\n        {\n            get { return _rowHoveredBackColorStart; }\n            set { _rowHoveredBackColorStart = value; }\n        }\n\n        private Color _rowHoveredBackColorEnd = Color.FromArgb(24, SystemColors.Highlight);\n        /// <summary>\n        /// 行处于选中状态时的背景色\n        /// </summary>\n        public Color RowHoveredBackColorEnd\n        {\n            get { return _rowHoveredBackColorEnd; }\n            set { _rowHoveredBackColorEnd = value; }\n        }\n\n        private Color _rowHoveredBorderColor = Color.FromArgb(32, SystemColors.Highlight);\n        /// <summary>\n        /// 行处于热点状态时的边框颜色\n        /// </summary>\n        public Color RowHoveredBorderColor\n        {\n            get { return _rowHoveredBorderColor; }\n            set { _rowHoveredBorderColor = value; }\n        }\n\n        private Color _rowUnFocusedSelectedColorStart = Color.FromArgb(16, SystemColors.GrayText);\n        /// <summary>\n        /// 控件失去焦点时选定项的背景色\n        /// </summary>\n        public Color RowUnFocusedSelectedColorStart\n        {\n            get { return _rowUnFocusedSelectedColorStart; }\n            set { _rowUnFocusedSelectedColorStart = value; }\n        }\n\n        private Color _rowUnFocusedSelectedColorEnd = Color.FromArgb(32, SystemColors.GrayText);\n        public Color RowUnFocusedSelectedColorEnd\n        {\n            get { return _rowUnFocusedSelectedColorEnd; }\n            set { _rowUnFocusedSelectedColorEnd = value; }\n        }\n\n        private Color _rowUnFocusedSelectedBorderColor = Color.FromArgb(64, SystemColors.GrayText);\n        /// <summary>\n        /// 行处于选中状态但控件没有焦点时的边框颜色\n        /// </summary>\n        public Color RowUnFocusedSelectedBorderColor\n        {\n            get { return _rowUnFocusedSelectedBorderColor; }\n            set { _rowUnFocusedSelectedBorderColor = value; }\n        }\n\n\n        private Color _rowTextColor = SystemColors.WindowText;\n        public Color RowTextColor\n        {\n            get { return _rowTextColor; }\n            set { _rowTextColor = value; }\n        }\n\n        private Color _arrowColorStart = Color.FromArgb(255, SystemColors.Highlight);\n        /// <summary>\n        /// 排序箭头开始颜色\n        /// </summary>\n        public Color ArrowColorStart\n        {\n            get { return _arrowColorStart; }\n            set { _arrowColorStart = value; }\n        }\n\n        private Color _arrowColorEnd = Color.FromArgb(16, SystemColors.Highlight);\n        /// <summary>\n        /// 排序箭头开始颜色\n        /// </summary>\n        public Color ArrowColorEnd\n        {\n            get { return _arrowColorEnd; }\n            set { _arrowColorEnd = value; }\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengDataGridView/ShengDataGridView.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.ComponentModel;\nusing System.Drawing;\n\nnamespace Sheng.Winform.Controls\n{\n    \n    public class ShengDataGridView : DataGridView\n    {\n        private string waterText = String.Empty;\n        /// <summary>\n        /// 水印文本\n        /// 设置水印文本后需要把Enable设置为false,暂时没有解决绘制后拖动滚动条的残影问题\n        /// </summary>\n        [Description(\"水印文本\")]\n        [Category(\"Sheng.Winform.Controls\")]\n        public string WaterText\n        {\n            get { return this.waterText; }\n            set\n            {\n                this.waterText = value;\n                this.Invalidate();\n            }\n        }\n\n        public ShengDataGridView()\n        {\n            //如果打开双倍缓存，水印文本绘制不出来，原因不明\n            //this.DoubleBuffered = true;\n            this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);\n            this.ResizeRedraw = true;\n\n            this.RowHeadersVisible = false;\n            this.RowHeadersWidthSizeMode = System.Windows.Forms.DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders;\n            this.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;\n            this.AllowUserToAddRows = false;\n            this.AllowUserToDeleteRows = false;\n            this.AllowUserToResizeRows = false;\n            this.BackgroundColor = System.Drawing.Color.White;\n            this.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;\n            this.CellBorderStyle = System.Windows.Forms.DataGridViewCellBorderStyle.None;\n            this.ColumnHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.None;\n            this.ReadOnly = true;\n\n            ShengDataGridViewRenderer renderer = new ShengDataGridViewRenderer(this);\n        }\n\n        protected override void OnCellMouseDown(DataGridViewCellMouseEventArgs e)\n        {\n            //使datagridview可以通过鼠标右键选择行\n            //这在绑定了右键菜单的情况下非常有用,可以在右键菜单弹出前确定行\n            if (e.Button == MouseButtons.Right && e.RowIndex >= 0)\n            {\n                /*\n                 * 注意一旦设置了CurrentCell属性\n                 * 就会失去之前已经选中的行,所以先获取选中的行到selectedRows\n                 */\n\n                //如果右击的行已经是选中的行了\n                if (this.Rows[e.RowIndex].Selected)\n                    return;\n\t\t\t\t\t\n\t\t\t\tif (e.ColumnIndex < 0 || e.RowIndex < 0)\n                    return;\n\n                //当前选中的行\n                DataGridViewSelectedRowCollection selectedRows = this.SelectedRows;\n\n                //为点击的单元格设置焦点,\n                this.CurrentCell = this[e.ColumnIndex, e.RowIndex];\n\n                //如果没有按下Control或Shift键\n                if (Control.ModifierKeys != Keys.Control && Control.ModifierKeys != Keys.Shift)\n                {\n                    //取消其它行的选中状态\n                    foreach (DataGridViewRow row in selectedRows)\n                        row.Selected = false;\n                }\n                else\n                {\n                    //为之前选中的行继续保持选中状态,因为设置CurrentCell属性会失去已经选中的行的选中状态\n                    //但如果不允许多选,就没必要了\n                    if (this.MultiSelect)\n                        foreach (DataGridViewRow row in selectedRows)\n                            row.Selected = true;\n                }\n\n                //设置右击的这行为选中行\n                this.Rows[e.RowIndex].Selected = true;\n            }\n\n            base.OnCellMouseDown(e);\n        }\n\n        protected override void OnPaint(PaintEventArgs e)\n        {\n            base.OnPaint(e);\n\n            if (this.Rows.Count == 0 && (this.waterText != null || this.waterText != String.Empty))\n            {\n                PaintWaterText();\n            }\n        }\n\n        //protected override void OnScroll(ScrollEventArgs e)\n        //{\n        //    base.OnScroll(e);\n\n        //    if (this.Rows.Count == 0 && this.waterText != String.Empty)\n        //    {\n        //        PaintWaterText();\n        //    }\n        //}\n\n        private TextFormatFlags textFlags = TextFormatFlags.WordBreak | TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter;\n\n        private Rectangle DrawStringRectangle\n        {\n            get\n            {\n                if (this.ClientRectangle == new Rectangle())\n                {\n                    return new Rectangle(0, 0, 1, 1);\n                }\n\n                Rectangle drawStringRectangle;\n\n                drawStringRectangle = this.ClientRectangle;\n\n                drawStringRectangle.X = drawStringRectangle.X + this.Padding.Left;\n                drawStringRectangle.Y = drawStringRectangle.Y + this.Padding.Top + this.ColumnHeadersHeight;\n                drawStringRectangle.Width = drawStringRectangle.Width - this.Padding.Left - this.Padding.Right;\n                drawStringRectangle.Height = 50;\n\n                return drawStringRectangle;\n            }\n        }\n\n        private void PaintWaterText()\n        {\n            Graphics g = this.CreateGraphics();\n            TextRenderer.DrawText(g, this.waterText, this.Font, this.DrawStringRectangle, this.ForeColor, textFlags);\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengDataGridView/ShengDataGridViewCheckBoxColumn.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Drawing;\nusing System.ComponentModel;\n\nnamespace Sheng.Winform.Controls\n{\n    \n    public class ShengDataGridViewCheckBoxColumn : DataGridViewCheckBoxColumn\n    {\n        public ShengDataGridViewCheckBoxColumn()\n        {\n\n            this.CellTemplate = new SEDataGridViewCheckBoxCell();\n        }\n\n    }\n\n    \n    public class SEDataGridViewCheckBoxCell : DataGridViewCheckBoxCell\n    {\n        /// Override the Clone method so that the Enabled property is copied.\n        public override object Clone()\n        {\n            SEDataGridViewCheckBoxCell cell =\n                (SEDataGridViewCheckBoxCell)base.Clone();\n            return cell;\n        }\n\n        public SEDataGridViewCheckBoxCell()\n        {\n        }\n\n        protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds,\n            int rowIndex, DataGridViewElementStates elementState, object value,\n            object formattedValue, string errorText, DataGridViewCellStyle cellStyle,\n            DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)\n        {\n            //base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);\n\n            SolidBrush cellBackground;\n            if ((elementState & DataGridViewElementStates.Selected) == DataGridViewElementStates.Selected)\n                cellBackground = new SolidBrush(cellStyle.SelectionBackColor);\n            else\n                cellBackground = new SolidBrush(cellStyle.BackColor);\n\n            graphics.FillRectangle(cellBackground, cellBounds);\n            cellBackground.Dispose();\n\n            PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle);\n\n            Point drawInPoint = new Point(cellBounds.X + cellBounds.Width / 2 - 7, cellBounds.Y + cellBounds.Height / 2 - 7);\n\n            if (Convert.ToBoolean(value))\n                CheckBoxRenderer.DrawCheckBox(graphics, drawInPoint, System.Windows.Forms.VisualStyles.CheckBoxState.CheckedDisabled);\n            else\n                CheckBoxRenderer.DrawCheckBox(graphics, drawInPoint, System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedDisabled);\n\n            if (this.DataGridView.CurrentCell == this\n                && (paintParts & DataGridViewPaintParts.Focus) == DataGridViewPaintParts.Focus)\n            {\n                ControlPaint.DrawFocusRectangle(graphics, cellBounds);\n            }\n\n        }\n\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengDataGridView/ShengDataGridViewImageBinderCell.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Diagnostics;\nusing System.Drawing;\n\nnamespace Sheng.Winform.Controls\n{\n    public class ShengDataGridViewImageBinderCell : DataGridViewImageCell\n    {\n        public ShengDataGridViewImageBinderCell()\n        {\n            \n        }\n\n        protected override object GetValue(int rowIndex)\n        {\n            if (rowIndex == -1)\n                return base.GetValue(rowIndex);\n\n            ShengDataGridViewImageBinderColumn column = this.OwningColumn as ShengDataGridViewImageBinderColumn;\n            Debug.Assert(column != null, \"column 为 null\");\n            if (column == null)\n            {\n                return base.GetValue(rowIndex);\n            }\n\n            /*\n             * 这里用\n             * DataGridViewRow row = this.OwningRow;\n             * row.DataBoundItem\n             * 在某些情况下总是取不到值，DataBoundItem 总为 null\n             * 如窗体选择界面上的窗体列表\n             * 而用 row.DataGridView.Rows[rowIndex].DataBoundItem 则可以取到\n             * 进行 row == row.DataGridView.Rows[rowIndex] 的判断结果居然为 false\n             * 原因不明，无法理解\n             * 在 row.DataGridView[ColumnIndex, rowIndex] 为 true 时（这是理论上，也是多数情况下的正常情况）\n             * 还是要走 row.DataBoundItem，否则死循环\n             */\n\n            DataGridViewRow row = this.OwningRow;\n            object value = null;\n            if (row == row.DataGridView.Rows[rowIndex])\n            {\n                Debug.Assert(row.DataBoundItem != null, \"row.DataBoundItem 为 null\");\n                value = row.DataBoundItem;\n            }\n            else\n            {\n                value = row.DataGridView.Rows[rowIndex].DataBoundItem;\n                Debug.Assert(value != null, \"value 为 null\");\n            }\n\n            if (value == null)\n                return null;\n\n            #region 原本想启用一个缓存机制\n\n            //原本想启用一个缓存机制避免每次都调用一次列上的GetImage方法取图像\n            //但是这样做为未来的扩展留下一个隐患\n            //因为打算在Type和Image映射的基础上增加一个Filter功能\n            //不但有根据类型映射，还能根据每次对象上的Property不同显示不同的图像\n            //比如对象的某个Property为true，显示一个图，为false，显示另一个图\n            //这就需要每次都去检查对象的状态\n\n            //if (_dataCache == null || _dataCache != row.DataBoundItem)\n            //{\n            //    _dataCache = row.DataBoundItem;\n            //    _image = column.GetImage(row.DataBoundItem);\n            //}\n            //return _image;\n\n            #endregion\n\n            return column.GetImage(value);\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengDataGridView/ShengDataGridViewImageBinderColumn.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Drawing;\nusing System.Diagnostics;\nusing Sheng.Winform.Controls.Kernal;\n\nnamespace Sheng.Winform.Controls\n{\n    /// <summary>\n    /// 将图像资源映射到DataGridView中的不同对象类型或对象上\n    /// </summary>\n    public class ShengDataGridViewImageBinderColumn : DataGridViewImageColumn\n    {\n        #region 私有成员\n\n        private List<ImageAndTypeMappingCodon> _imageMappingCodons = new List<ImageAndTypeMappingCodon>();\n\n        #endregion\n\n        #region 构造\n\n        public ShengDataGridViewImageBinderColumn()\n        {\n            this.CellTemplate = new ShengDataGridViewImageBinderCell();\n        }\n\n        #endregion\n\n        #region 公开方法\n\n        public void AddCodon(ImageAndTypeMappingCodon codon)\n        {\n            if (_imageMappingCodons.Contains(codon))\n            {\n                Debug.Assert(false, \"_typeBinderDataGridViewTypeCodons 重复添加:\" + codon.ToString());\n                return;\n            }\n\n            Debug.Assert(GetCodon(codon.DataBoundType) == null,\n                \"_typeBinderDataGridViewTypeCodons 重复添加类型:\" + codon.ToString());\n\n            _imageMappingCodons.Add(codon);\n        }\n\n        public void Mapping(Type type, Image image)\n        {\n            Mapping(type, image, false);\n        }\n\n        public void Mapping(Type type, Image image, bool actOnSubClass)\n        {\n            AddCodon(new ImageAndTypeMappingCodon(type, image, actOnSubClass));\n        }\n\n        internal Image GetImage(object data)\n        {\n            Debug.Assert(data != null, \"data 为 null\");\n\n            if (data == null)\n                return null;\n\n            Type dataType = data.GetType();\n\n            ImageAndTypeMappingCodon mappingCodon = GetCodon(dataType);\n\n            if (mappingCodon == null)\n                return null;\n\n            return mappingCodon.Image;\n        }\n\n        #endregion\n\n        #region 私有方法\n\n        private ImageAndTypeMappingCodon GetCodon(Type type)\n        {\n            foreach (var item in _imageMappingCodons)\n            {\n                if (item.DataBoundType == null)\n                    continue;\n\n                if (item.DataBoundType == type || (item.ActOnSubClass && type.IsSubclassOf(item.DataBoundType)))\n                {\n                    return item;\n                }\n            }\n\n            return null;\n        }\n\n        #endregion\n\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengDatetimePicker.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.ComponentModel;\n\nnamespace Sheng.Winform.Controls\n{\n    \n    public class ShengDatetimePicker:DateTimePicker\n    {\n        private string title;\n        /// <summary>\n        /// \n        /// </summary>\n        [Description(\"\")]\n        [Category(\"Sheng.Winform.Controls\")]\n        public string Title\n        {\n            get\n            {\n                return this.title;\n            }\n            set\n            {\n                this.title = value;\n            }\n        }\n\n        private string relationType;\n        /// <summary>\n        /// ͣStartEnd\n        /// </summary>\n        [Description(\"ͣStartEnd\")]\n        [Category(\"Sheng.Winform.Controls\")]\n        public string RelationType\n        {\n            get\n            {\n                return this.relationType;\n            }\n            set\n            {\n                this.relationType = value;\n            }\n        }\n\n        private ShengDatetimePicker relation;\n        /// <summary>\n        /// \n        /// </summary>\n        [Description(\"\")]\n        [Category(\"Sheng.Winform.Controls\")]\n        public ShengDatetimePicker Relation\n        {\n            get\n            {\n                return this.relation;\n            }\n            set\n            {\n                this.relation = value;\n            }\n        }\n\n        public ShengDatetimePicker()\n        {\n            \n        }\n\n        /// <summary>\n        /// ıѡʱ,Թв\n        /// </summary>\n        /// <param name=\"eventargs\"></param>\n        protected override void OnValueChanged(EventArgs eventargs)\n        {\n            base.OnValueChanged(eventargs);\n        }\n\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengFlatButton.Designer.cs",
    "content": "﻿namespace Sheng.Winform.Controls\n{\n    partial class ShengFlatButton\n    {\n        /// <summary> \n        /// 必需的设计器变量。\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary> \n        /// 清理所有正在使用的资源。\n        /// </summary>\n        /// <param name=\"disposing\">如果应释放托管资源，为 true；否则为 false。</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region 组件设计器生成的代码\n\n        /// <summary> \n        /// 设计器支持所需的方法 - 不要\n        /// 使用代码编辑器修改此方法的内容。\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.SuspendLayout();\n            // \n            // SEFlatButton\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.Name = \"SEFlatButton\";\n            this.Size = new System.Drawing.Size(166, 52);\n            this.ResumeLayout(false);\n\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengFlatButton.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Drawing;\nusing System.Data;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Drawing.Drawing2D;\nusing System.Drawing.Text;\nusing Sheng.Winform.Controls.Drawing;\n\nnamespace Sheng.Winform.Controls\n{\n    /// <summary>\n    /// 具有扁平样式的,可以选中和取消选中状态的按钮\n    /// </summary>\n    \n    public partial class ShengFlatButton : UserControl\n    {\n        #region 有关绘制外观的参数\n\n        //显示图像的位置X坐标\n        int imageLocationX ;\n\n        //显示图像的位置Y坐标\n        int imageLocationY ;\n\n        //显示文本的位置X坐标\n        int textLocationX ;\n\n        //显示文本的位置Y坐标\n        //int textLocationY = 4;\n        int textLocationY;\n\n        //文本填充\n        SolidBrush textBrush;\n\n        //显示图像的Rectangle\n        Rectangle imageRect;\n\n        //背景填充\n        LinearGradientBrush backBrush;\n\n        //背景填充 选中状态\n        LinearGradientBrush backBrush_Selected;\n\n        //填充Rectangle \n        Rectangle fillRect;\n\n        //边框Rectangle 顶层\n        Rectangle drawRect;\n\n        //边框画笔 \n        Pen drawPen;\n\n        //按下时的边框画笔 顶层\n        Pen drawPen_Selected;\n\n        #endregion\n\n        private bool allowSelect = true;\n        /// <summary>\n        /// 是否允许选中\n        /// </summary>\n        public bool AllowSelect\n        {\n            get { return allowSelect; }\n            set { allowSelect = value; }\n        }\n\n        private bool selected = false;\n        /// <summary>\n        /// 当前按钮是否处于选中状态\n        /// </summary>\n        public bool Selected\n        {\n            get\n            {\n                return selected;\n            }\n            set\n            {\n                selected = value;\n                this.Refresh();\n            }\n        }\n\n        private Image image;\n        /// <summary>\n        /// 显示图像\n        /// </summary>\n        public Image Image\n        {\n            get\n            {\n                return this.image;\n            }\n            set\n            {\n                this.image = value;\n                this.Refresh();\n            }\n        }\n\n        private string showText;\n        /// <summary>\n        /// 显示的文本\n        /// </summary>\n        public string ShowText\n        {\n            get\n            {\n                return this.showText;\n            }\n            set\n            {\n                this.showText = value;\n                this.Refresh();\n            }\n        }\n\n        StringFormat stringFormat = new StringFormat();\n\n        public ShengFlatButton()\n        {\n\n            InitializeComponent();\n\n            EnableDoubleBuffering();\n\n            stringFormat.HotkeyPrefix = HotkeyPrefix.Show;\n        }\n\n        protected override void OnPaint(PaintEventArgs e)\n        {\n            imageLocationX = 8;\n\n            imageLocationY = (int)Math.Round((float)(this.ClientRectangle.Height - (int)Math.Round(this.Font.SizeInPoints)) / 2);\n            imageLocationY = imageLocationY - 2;\n            textLocationX = 26;\n            textLocationY = (int)Math.Round((float)(this.ClientRectangle.Height - (int)Math.Round(this.Font.SizeInPoints)) / 2);\n            textLocationY = textLocationY - 1;\n            fillRect = new Rectangle(0, 0, this.Bounds.Width, this.Bounds.Height);\n            drawRect = new Rectangle(0, 0, this.Bounds.Width - 2, this.Bounds.Height - 2);\n            textBrush = new SolidBrush(this.ForeColor);\n            imageRect = new Rectangle(imageLocationX, imageLocationY, 16, 16);\n            backBrush = new LinearGradientBrush(drawRect,\n                 Color.White,Color.FromArgb(236,233,217),LinearGradientMode.ForwardDiagonal);\n            backBrush_Selected = new LinearGradientBrush(drawRect,\n                 Color.FromArgb(241, 243, 236), Color.FromArgb(188, 196, 166), LinearGradientMode.ForwardDiagonal);\n            drawPen = new Pen(SystemColors.ActiveCaption);\n\n            //按下时的边框画笔 顶层\n            drawPen_Selected = new Pen(SystemColors.ActiveCaption);\n\n            //如果是按下状态\n            if (this.Selected)\n            {\n                //GraphPlotting.FillRoundRect(e.Graphics, backBrush_Selected, fillRect, 0, 2);\n                //GraphPlotting.DrawRoundRect(e.Graphics, drawPen_Selected, drawRect, 2);\n\n                e.Graphics.FillPath(backBrush_Selected, DrawingTool.RoundedRect(fillRect, 3));\n                e.Graphics.DrawPath(drawPen_Selected, DrawingTool.RoundedRect(drawRect, 3));\n            }\n            else\n            {\n                //GraphPlotting.FillRoundRect(e.Graphics, backBrush, fillRect, 1, 2);\n                //GraphPlotting.DrawRoundRect(e.Graphics, drawPen, drawRect, 2);\n\n                e.Graphics.FillPath(backBrush, DrawingTool.RoundedRect(fillRect, 3));\n                e.Graphics.DrawPath(drawPen, DrawingTool.RoundedRect(drawRect, 3));\n            }\n\n            //绘制图像和文本\n            if (this.Image != null)\n            {\n                e.Graphics.DrawImage(this.Image, imageRect);\n                e.Graphics.DrawString(this.Text, this.Font, textBrush, new Point(textLocationX + 14, textLocationY), stringFormat);\n\n            }\n\n            e.Graphics.DrawString(this.ShowText, this.Font, textBrush, new Point(textLocationX, textLocationY), stringFormat);\n\n            //if (this.Focused)\n            //{\n            //    ControlPaint.DrawFocusRectangle(e.Graphics, this.ClientRectangle);\n            //}\n        }\n\n        /// <summary>\n        /// 开启双倍缓冲\n        /// </summary>\n        private void EnableDoubleBuffering()\n        {\n            // Set the value of the double-buffering style bits to true.\n            this.SetStyle(ControlStyles.DoubleBuffer |\n               ControlStyles.UserPaint |\n               ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw,\n               true);\n            this.UpdateStyles();\n        }\n\n        protected override void OnClick(EventArgs e)\n        {\n            if (this.Selected)\n            {\n                return;\n            }\n\n            if (this.AllowSelect && !this.Selected)\n            {\n                this.Selected = true;\n            }\n\n            base.OnClick(e);\n        }\n\n        protected override bool ShowFocusCues\n        {\n            get\n            {\n                return true;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengFlatButton.resx",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n</root>"
  },
  {
    "path": "Sheng.Winform.Controls/ShengForm.Designer.cs",
    "content": "﻿namespace Sheng.Winform.Controls\n{\n    partial class ShengForm\n    {\n        /// <summary>\n        /// 必需的设计器变量。\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// 清理所有正在使用的资源。\n        /// </summary>\n        /// <param name=\"disposing\">如果应释放托管资源，为 true；否则为 false。</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Windows 窗体设计器生成的代码\n\n        /// <summary>\n        /// 设计器支持所需的方法 - 不要\n        /// 使用代码编辑器修改此方法的内容。\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.SuspendLayout();\n            // \n            // SEForm\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.ClientSize = new System.Drawing.Size(292, 266);\n            this.Name = \"SEForm\";\n            this.Text = \"FormBase\";\n            this.ResumeLayout(false);\n\n        }\n\n        #endregion\n\n    }\n}"
  },
  {
    "path": "Sheng.Winform.Controls/ShengForm.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Data;\nusing System.Drawing;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Reflection;\n\nusing Sheng.Winform.Controls.Localisation;\n\nnamespace Sheng.Winform.Controls\n{\n    \n    public partial class ShengForm : Form, IShengForm\n    {\n        public ShengForm()\n        {\n\n            InitializeComponent();\n        }\n\n        /// <summary>\n        /// ֤ؼ\n        /// </summary>\n        /// <returns></returns>\n        public virtual bool DoValidate()\n        {\n            string validateMsg;\n            bool validateResult =  ShengValidateHelper.ValidateContainerControl(this, out validateMsg); \n\n            if (validateResult == false)\n            {\n                MessageBox.Show(validateMsg, Language.Current.MessageBoxCaptiton_Message, MessageBoxButtons.OK, MessageBoxIcon.Information);\n            }\n            return validateResult;\n        }\n\n    }\n}"
  },
  {
    "path": "Sheng.Winform.Controls/ShengForm.resx",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n</root>"
  },
  {
    "path": "Sheng.Winform.Controls/ShengGroupBox.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Reflection;\nusing System.Drawing;\nusing System.ComponentModel;\n\nnamespace Sheng.Winform.Controls\n{\n    \n    public class ShengGroupBox : GroupBox, IShengValidate\n    {\n        #region \n\n        public ShengGroupBox()\n        {\n        }\n\n        #endregion\n\n        #region ISEValidate Ա\n\n        private string title;\n        /// <summary>\n        /// \n        /// </summary>\n        [Description(\"\")]\n        [Category(\"Sheng.Winform.Controls\")]\n        public string Title\n        {\n            get\n            {\n                return this.title;\n            }\n            set\n            {\n                this.title = value;\n            }\n        }\n\n        private bool highLight = false;\n        /// <summary>\n        /// ֤ʧʱǷҪʾı䱳ɫ\n        /// </summary>\n        [Description(\"֤ʧʱǷҪʾı䱳ɫ\")]\n        [Category(\"Sheng.Winform.Controls\")]\n        public bool HighLight\n        {\n            get\n            {\n                return this.highLight;\n            }\n            set\n            {\n                this.highLight = value;\n            }\n        }\n\n        /// <summary>\n        /// ֤ؼ\n        /// </summary>\n        /// <param name=\"validateMsg\"></param>\n        /// <returns></returns>\n        public bool SEValidate(out string validateMsg)\n        {\n            return ShengValidateHelper.ValidateContainerControl(this, out validateMsg);\n        }\n\n        public CustomValidateMethod CustomValidate\n        {\n            get;\n            set;\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengImageListView/Enums.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nnamespace Sheng.Winform.Controls\n{\n    /// <summary>\n    /// Represents the visual state of an image list view item.\n    /// </summary>\n    [Flags]\n    public enum ShengImageListViewItemState\n    {\n        /// <summary>\n        /// 没有任何选择状态，处于一般正常状态\n        /// </summary>\n        None = 0,\n        /// <summary>\n        /// 项处于选中状态\n        /// </summary>\n        Selected = 1,\n        /// <summary>\n        /// 该项具有输入焦点\n        /// </summary>\n        Focused = 2,\n        /// <summary>\n        /// Mouse cursor is over the item.\n        /// </summary>\n        Hovered = 4,\n    }\n\n    public enum ShengImageListViewItemVisibility\n    {\n        /// <summary>\n        /// The item is not visible.\n        /// </summary>\n        NotVisible,\n        /// <summary>\n        /// The item is partially visible.\n        /// </summary>\n        PartiallyVisible,\n        /// <summary>\n        /// The item is fully visible.\n        /// </summary>\n        Visible,\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengImageListView/Events.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nnamespace Sheng.Winform.Controls\n{\n\n    /// <summary>\n    /// 双击项事件参数\n    /// </summary>\n    public class ShengImageListViewItemDoubleClickEventArgs : EventArgs\n    {\n        public ShengImageListViewItem Item { get; private set; }\n\n        public ShengImageListViewItemDoubleClickEventArgs(ShengImageListViewItem item)\n        {\n            Item = item;\n        }\n    }\n\n    /// <summary>\n    /// 项被删除事件参数\n    /// </summary>\n    public class ShengImageListViewItemsRemovedEventArgs : EventArgs\n    {\n        public List<ShengImageListViewItem> Items { get; private set; }\n\n        public ShengImageListViewItemsRemovedEventArgs(List<ShengImageListViewItem> items)\n        {\n            Items = items;\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengImageListView/ShengImageListView.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Windows.Forms.VisualStyles;\nusing System.Drawing;\nusing System.Diagnostics;\n\nnamespace Sheng.Winform.Controls\n{\n    public class ShengImageListView : Control\n    {\n        #region 常量\n\n        /// <summary>\n        /// Creates a control with a border.\n        /// </summary>\n        private const int WS_BORDER = 0x00800000;\n        /// <summary>\n        /// Specifies that the control has a border with a sunken edge.\n        /// </summary>\n        private const int WS_EX_CLIENTEDGE = 0x00000200;\n\n        #endregion\n\n        #region 私有成员\n\n        private ShengImageListViewLayoutManager _layoutManager;\n\n        private bool _suspendLayout = false;\n        public bool Suspend\n        {\n            get { return _suspendLayout; }\n        }\n\n        /// <summary>\n        /// 是否需要在调用 ResumeLayout 时重绘\n        /// </summary>\n        private bool _needPaint = false;\n\n\n        //ToolTip _toolTip = new ToolTip();\n\n        //private System.Timers.Timer lazyRefreshTimer;\n\n        #endregion\n\n        #region 公开属性\n\n        /// <summary>\n        /// Gets whether the shift key is down.\n        /// </summary>\n        internal bool ShiftKey { get; private set; }\n        /// <summary>\n        /// Gets whether the control key is down.\n        /// </summary>\n        internal bool ControlKey { get; private set; }\n\n        /// <summary>\n        /// 鼠标左键是否处于按下状态\n        /// </summary>\n        internal bool LeftButton { get; private set; }\n\n        /// <summary>\n        /// 鼠标右键是否处于按下状态\n        /// </summary>\n        internal bool RightButton { get; private set; }\n\n        internal bool AnyMouseButton\n        {\n            get { return LeftButton || RightButton; }\n        }\n\n        //debug public\n        /// <summary>\n        /// 鼠标最后点击的位置\n        /// </summary>\n        public Point LastMouseDownLocation { get; private set; }\n\n        private ShengImageListViewItem _hoveredItem;\n        /// <summary>\n        /// 当前鼠标经过的项\n        /// </summary>\n        internal ShengImageListViewItem HoveredItem\n        {\n            get { return _hoveredItem; }\n            private set\n            {\n                ShengImageListViewItem oldHoveredItem = _hoveredItem;\n                ShengImageListViewItem newHoveredItem = value;\n\n                _hoveredItem = value;\n\n                if (oldHoveredItem != null && oldHoveredItem != newHoveredItem)\n                {\n                    oldHoveredItem.Hovered = false;\n                }\n\n                if (newHoveredItem != null)\n                    newHoveredItem.Hovered = true;\n\n                if (oldHoveredItem != newHoveredItem)\n                {\n                    NeedPaint();\n                }\n            }\n        }\n\n        private BorderStyle _borderStyle = BorderStyle.Fixed3D;\n        public BorderStyle BorderStyle\n        {\n            get { return _borderStyle; }\n            set { _borderStyle = value; }\n        }\n\n        private ShengImageListViewTheme _theme = new ShengImageListViewTheme();\n        /// <summary>\n        /// 配色方案\n        /// </summary>\n        public ShengImageListViewTheme Theme\n        {\n            get\n            {\n                return _theme;\n            }\n            set\n            {\n                _theme = value;\n                Refresh();\n            }\n        }\n\n        private bool _allowMultiSelection = false;\n        public bool AllowMultiSelection\n        {\n            get { return _allowMultiSelection; }\n            set { _allowMultiSelection = value; }\n        }\n\n        /// <summary>\n        /// 是否没有任何项\n        /// </summary>\n        public bool IsEmpty\n        {\n            get\n            {\n                return Items.Count == 0;\n            }\n        }\n\n        private ShengImageListViewCollection _items = new ShengImageListViewCollection();\n        public ShengImageListViewCollection Items\n        {\n            get { return _items; }\n            set { _items = value; }\n        }\n\n        /// <summary>\n        /// 获取当前具有输入焦点的项\n        /// </summary>\n        public ShengImageListViewItem FocusedItem\n        {\n            get\n            {\n                foreach (var item in _items)\n                {\n                    if (item.Focused)\n                        return item;\n                }\n\n                return null;\n            }\n        }\n\n        #endregion\n\n        #region 临时调试用\n\n        public ShengImageListViewLayoutManager LayoutManager\n        {\n            get { return _layoutManager; }\n        }\n\n        #endregion\n\n        #region 构造\n\n        public ShengImageListView()\n        {\n            SetStyle(ControlStyles.ResizeRedraw, true);\n            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);\n            SetStyle(ControlStyles.Selectable, true);\n\n            this.Padding = new System.Windows.Forms.Padding(10);\n\n            _items.Owner = this;\n\n            _layoutManager = new ShengImageListViewLayoutManager(this);\n\n            //lazyRefreshTimer = new System.Timers.Timer();\n            //lazyRefreshTimer.Interval = 10;\n            //lazyRefreshTimer.Enabled = false;\n            //lazyRefreshTimer.Elapsed += lazyRefreshTimer_Tick;\n            //lazyRefreshCallback = new RefreshDelegateInternal(Refresh);\n            \n           \n        }\n\n        //delegate void RefreshDelegateInternal();\n        //private RefreshDelegateInternal lazyRefreshCallback;\n        //void lazyRefreshTimer_Tick(object sender, EventArgs e)\n        //{\n        //    if (IsHandleCreated && IsDisposed == false)\n        //        BeginInvoke(lazyRefreshCallback);\n        //    lazyRefreshTimer.Stop();\n        //}\n\n        #endregion\n\n        #region 公开方法\n\n        #region internal\n\n        /// <summary>\n        /// 请求在下次调用 ResumeLayout 时重绘\n        /// </summary>\n        internal void NeedPaint()\n        {\n            _needPaint = true;\n        }\n\n        internal void RenderItem(ShengImageListViewItem item)\n        {\n            if (Suspend == false)\n            {\n                _layoutManager.RenderItem(this.CreateGraphics(), item);\n            }\n        }\n\n        //internal void Refresh(bool lazyRefresh)\n        //{\n        //    if (lazyRefresh)\n        //    {\n        //        lazyRefreshTimer.Stop();\n        //        lazyRefreshTimer.Start();\n        //    }\n        //    else\n        //    {\n        //        Refresh();\n        //    }\n        //}\n\n        #endregion\n\n        /// <summary>\n        /// 恢复正常的布局逻辑。\n        /// </summary>\n        public new void ResumeLayout()\n        {\n            _suspendLayout = false;\n\n            if (_needPaint)\n            {\n                this.Refresh();\n            }\n\n            base.ResumeLayout();\n        }\n\n        //public new void ResumeLayout(bool refreshNow)\n        //{\n        //    _suspendLayout = false;\n\n        //    if (refreshNow)\n        //    {\n        //        this.Refresh();\n        //    }\n        //    else\n        //    {\n        //        ResumeLayout();\n        //    }\n\n        //    base.ResumeLayout(refreshNow);\n        //}\n\n        /// <summary>\n        /// 临时挂起控件的布局逻辑。\n        /// </summary>\n        public new void SuspendLayout()\n        {\n            _suspendLayout = true;\n\n            base.SuspendLayout();\n        }\n\n        public override void Refresh()\n        {\n            //如果布局已被挂起，返回，不刷新\n            //但是在返回之前设置 _needPaint 为 true，以便随后调用ResumeLayout能够刷新\n            if (_suspendLayout)\n            {\n                _needPaint = true;\n                return;\n            }\n\n            _needPaint = false;\n\n            base.Refresh();\n        }\n\n        /// <summary>\n        /// 获取当前选中的所有项\n        /// </summary>\n        /// <returns></returns>\n        public List<ShengImageListViewItem> GetSelectedItems()\n        {\n            List<ShengImageListViewItem> items = new List<ShengImageListViewItem>();\n\n            foreach (var item in _items)\n            {\n                if (item.Selected)\n                    items.Add(item);\n            }\n\n            return items;\n        }\n\n        /// <summary>\n        /// 取消所有项的选择\n        /// </summary>\n        public void ClearSelect()\n        {\n            bool suspend = false;\n            if (this.Suspend == false)\n            {\n                this.SuspendLayout();\n                suspend = true;\n            }\n\n            foreach (var selectedItem in GetSelectedItems())\n            {\n                selectedItem.Selected = false;\n            }\n\n            if (suspend)\n                this.ResumeLayout();\n        }\n\n        /// <summary>\n        /// 更改了选择的项\n        /// </summary>\n        public void OnSelectedItemChanged()\n        {\n            if (SelectedItemChanaged != null)\n            {\n                SelectedItemChanaged(this, new EventArgs());\n            }\n        }\n\n        /// <summary>\n        /// 双击项\n        /// </summary>\n        /// <param name=\"item\"></param>\n        public void OnItemDoubleClick(ShengImageListViewItem item)\n        {\n            if (ItemDoubleClick != null)\n            {\n                ItemDoubleClick(this, new ShengImageListViewItemDoubleClickEventArgs(item));\n            }\n        }\n\n        public void OnItemsRemoved(List<ShengImageListViewItem> items)\n        {\n            _layoutManager.OnItemsRemoved(items);\n\n            if (ItemsRemoved != null)\n            {\n                ItemsRemoved(this, new ShengImageListViewItemsRemovedEventArgs(items));\n            }\n        }\n\n        #endregion\n\n        #region 私有方法\n\n        private void Hover(Point location)\n        {\n            ShengImageListViewHitInfo hitInfo = _layoutManager.HitTest(location);\n            if (hitInfo.ItemHit)\n            {\n                HoveredItem = Items[hitInfo.ItemIndex];\n            }\n            else\n            {\n                HoveredItem = null;\n            }\n        }\n\n        #endregion\n\n        #region 重写的方法\n\n        /// <summary>\n        /// 获取创建控件句柄时所需要的创建参数\n        /// </summary>\n        protected override CreateParams CreateParams\n        {\n            get\n            {\n                //设置控件的边框样式\n                CreateParams p = base.CreateParams;\n                p.Style &= ~WS_BORDER;\n                p.ExStyle &= ~WS_EX_CLIENTEDGE;\n                if (_borderStyle == BorderStyle.Fixed3D)\n                    p.ExStyle |= WS_EX_CLIENTEDGE;\n                else if (_borderStyle == BorderStyle.FixedSingle)\n                    p.Style |= WS_BORDER;\n                return p;\n            }\n        }\n\n        protected override void OnResize(EventArgs e)\n        {\n            base.OnResize(e);\n\n            //_layoutManager.Update();\n        }\n\n        #region Mouse\n\n        protected override void OnMouseDown(MouseEventArgs e)\n        {\n            SuspendLayout();\n\n            if (Focused == false)\n                Focus();\n\n            LeftButton = (e.Button & MouseButtons.Left) == MouseButtons.Left;\n            RightButton = (e.Button & MouseButtons.Right) == MouseButtons.Right;\n\n            LastMouseDownLocation = e.Location;\n\n            _layoutManager.MouseDown(e);\n\n            ResumeLayout();\n\n            base.OnMouseDown(e);\n        }\n\n        protected override void OnMouseUp(MouseEventArgs e)\n        {\n            if ((e.Button & MouseButtons.Left) == MouseButtons.Left)\n                LeftButton = false;\n            if ((e.Button & MouseButtons.Right) == MouseButtons.Right)\n                RightButton = false;\n\n            SuspendLayout();\n\n            _layoutManager.MouseUp(e);\n\n            ResumeLayout();\n\n            //显示上下文菜单\n            bool rightButton = (e.Button & MouseButtons.Right) == MouseButtons.Right;\n            if (rightButton && this.ContextMenuStrip != null)\n            {\n                this.ContextMenuStrip.Show(this.PointToScreen(e.Location));\n            }\n\n            base.OnMouseUp(e);\n        }\n\n        protected override void OnMouseMove(MouseEventArgs e)\n        {\n          //  if (_toolTip.Active)\n            //    _toolTip.Hide(this);\n\n            SuspendLayout();\n\n            //如果处于框选状态，不处理Hover\n            if (_layoutManager.MouseSelecting == false)\n            {\n                Hover(e.Location);\n            }\n\n            _layoutManager.MouseMove(e);\n\n            ResumeLayout();\n\n            base.OnMouseMove(e);\n        }\n\n        protected override void OnMouseWheel(MouseEventArgs e)\n        {\n            SuspendLayout();\n\n            _layoutManager.OnMouseWheel(e);\n\n            Hover(e.Location);\n\n            NeedPaint();\n            ResumeLayout();\n\n            base.OnMouseWheel(e);\n        }\n\n        protected override void OnMouseDoubleClick(MouseEventArgs e)\n        {\n            if (ItemDoubleClick != null)\n            {\n                ShengImageListViewHitInfo hitInfo = _layoutManager.HitTest(e.Location);\n                if (hitInfo.ItemHit)\n                {\n                    ShengImageListViewItem  item = Items[hitInfo.ItemIndex];\n                    OnItemDoubleClick(item);\n                }\n            }\n\n            base.OnMouseDoubleClick(e);\n        }\n\n        protected override void OnMouseHover(EventArgs e)\n        {\n            //Point toolTipPoint = this.PointToClient(Cursor.Position);\n            //_toolTip.Show(\"ff\", this, toolTipPoint);\n\n            base.OnMouseHover(e);\n        }\n\n        #endregion\n\n        #region Key\n\n        protected override bool IsInputKey(Keys keyData)\n        {\n            if ((keyData & Keys.Left) == Keys.Left ||\n               (keyData & Keys.Right) == Keys.Right ||\n               (keyData & Keys.Up) == Keys.Up ||\n               (keyData & Keys.Down) == Keys.Down)\n                return true;\n            else\n                return base.IsInputKey(keyData);\n        }\n\n        protected override void OnKeyDown(KeyEventArgs e)\n        {\n            ShiftKey = (e.Modifiers & Keys.Shift) == Keys.Shift;\n            ControlKey = (e.Modifiers & Keys.Control) == Keys.Control;\n\n            _layoutManager.OnKeyDown(e);\n\n            base.OnKeyDown(e);\n        }\n\n        protected override void OnKeyUp(KeyEventArgs e)\n        {\n            ShiftKey = (e.Modifiers & Keys.Shift) == Keys.Shift;\n            ControlKey = (e.Modifiers & Keys.Control) == Keys.Control;\n\n            _layoutManager.OnKeyUp(e);\n\n            base.OnKeyUp(e);\n        }\n\n        #endregion\n\n        #region Focus\n\n        protected override void OnGotFocus(EventArgs e)\n        {\n            base.OnGotFocus(e);\n            Refresh();\n        }\n\n        protected override void OnLostFocus(EventArgs e)\n        {\n            base.OnLostFocus(e);\n            Refresh();\n        }\n\n        #endregion\n\n        #region Paint\n\n        protected override void OnPaint(PaintEventArgs e)\n        {\n            _layoutManager.Render(e.Graphics);\n\n            //Size size1 = new Size(100, 100);\n            //Size size2 = new Size(50, 50);\n            //e.Graphics.DrawRectangle(Pens.Black, new Rectangle(new Point(10, 10), size1));\n            //size1 = Size.Add(size1, size2);\n            //e.Graphics.DrawRectangle(Pens.Red, new Rectangle(new Point(10, 10), size1));\n        }\n\n        #endregion\n\n        protected override void Dispose(bool disposing)\n        {\n            base.Dispose(disposing);\n        }\n\n        #endregion\n\n        #region 事件\n\n        /// <summary>\n        /// 更改了选择的项\n        /// </summary>\n        public event EventHandler SelectedItemChanaged;\n\n        /// <summary>\n        /// 双击项\n        /// </summary>\n        public event EventHandler<ShengImageListViewItemDoubleClickEventArgs> ItemDoubleClick;\n\n        /// <summary>\n        /// 项被删除\n        /// </summary>\n        public event EventHandler<ShengImageListViewItemsRemovedEventArgs> ItemsRemoved;\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengImageListView/ShengImageListViewCollection.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Collections;\n\nnamespace Sheng.Winform.Controls\n{\n    public class ShengImageListViewCollection : CollectionBase, IList<ShengImageListViewItem>\n    {\n        #region 基本方法和属性\n\n        public ShengImageListViewCollection()\n        {\n        }\n\n        public ShengImageListViewCollection(ShengImageListViewCollection value)\n        {\n            this.AddRange(value);\n        }\n\n        public ShengImageListViewCollection(ShengImageListViewItem[] value)\n        {\n            this.AddRange(value);\n        }\n\n        public ShengImageListViewItem this[int index]\n        {\n            get\n            {\n                return ((ShengImageListViewItem)(List[index]));\n            }\n            set\n            {\n                List[index] = value;\n            }\n        }\n\n        public int Add(ShengImageListViewItem value)\n        {\n            value.OwnerCollection = this;\n            int index = List.Add(value);\n            _owner.Refresh();\n            return index;\n        }\n\n        public void AddRange(ShengImageListViewItem[] value)\n        {\n            _owner.SuspendLayout();\n\n            for (int i = 0; (i < value.Length); i = (i + 1))\n            {\n                this.Add(value[i]);\n            }\n\n            _owner.ResumeLayout();\n        }\n\n        public void AddRange(ShengImageListViewCollection value)\n        {\n            _owner.SuspendLayout();\n\n            for (int i = 0; (i < value.Count); i = (i + 1))\n            {\n                this.Add(value[i]);\n            }\n\n            _owner.ResumeLayout();\n        }\n\n        public bool Contains(ShengImageListViewItem value)\n        {\n            return List.Contains(value);\n        }\n\n        public void CopyTo(ShengImageListViewItem[] array, int index)\n        {\n            List.CopyTo(array, index);\n        }\n\n        public int IndexOf(ShengImageListViewItem value)\n        {\n            return List.IndexOf(value);\n        }\n\n        public void Insert(int index, ShengImageListViewItem value)\n        {\n            value.OwnerCollection = this;\n            List.Insert(index, value);\n        }\n\n        public void Remove(ShengImageListViewItem value)\n        {\n            value.OwnerCollection = null;\n            List.Remove(value);\n            _owner.Refresh();\n\n            _owner.OnItemsRemoved(new List<ShengImageListViewItem>() { value });\n        }\n\n        public void Remove(List<ShengImageListViewItem> items)\n        {\n            _owner.SuspendLayout();\n\n            foreach (var item in items)\n            {\n                item.OwnerCollection = null;\n                List.Remove(item);\n            }\n\n            _owner.ResumeLayout();\n\n            _owner.OnItemsRemoved(items);\n        }\n\n        public new void RemoveAt(int index)\n        {\n            ShengImageListViewItem removedItem = this[index];\n\n            List.RemoveAt(index);\n\n            _owner.Refresh();\n\n            _owner.OnItemsRemoved(new List<ShengImageListViewItem>() { removedItem });\n        }\n\n        #endregion\n\n        #region 加的方法和属性\n\n        private ShengImageListView _owner;\n        internal ShengImageListView Owner\n        {\n            get { return _owner; }\n            set { _owner = value; }\n        }\n\n        public ShengImageListViewItem[] ToArray()\n        {\n            return this.ToList().ToArray();\n        }\n\n        public List<ShengImageListViewItem> ToList()\n        {\n            List<ShengImageListViewItem> list = new List<ShengImageListViewItem>();\n\n            foreach (ShengImageListViewItem e in this)\n            {\n                list.Add(e);\n            }\n\n            return list;\n        }\n\n        /// <summary>\n        /// 将指定的事件移动到(紧邻)另一个事件之前\n        /// </summary>\n        /// <param name=\"targetEvent\"></param>\n        /// <param name=\"referEvent\"></param>\n        public void PreTo(ShengImageListViewItem targetEvent, ShengImageListViewItem referEvent)\n        {\n            if (targetEvent == null || referEvent == null)\n                return;\n\n            if (this.Contains(targetEvent) == false || this.Contains(referEvent) == false)\n                return;\n\n            //这里不能因为目标事件是最顶过就直接返回\n            //因为此方法的目的是把目标事件放在指定事件 紧挨着 的 前面 一个，而不是前面的任意位置\n            //有可能目标事件index是0，指定事件是3，那么此方法要把目标事件的index变为2\n            //如果指定事件已经是最顶个了，直接返回\n            //int targetIndex = this.IndexOf(targetEvent);\n            //if (targetIndex == 0)\n            //    return;\n\n            int referIndex = this.IndexOf(referEvent);\n\n            //如果目标事件在指定事件之前的某个位置，这里不能先直接remove目标事件\n            //因为这样会使指定事件提前一个index，此时在referIndex上insert，就跑到指定事件后面去了\n            //如果目标事件本身在指定事件之后，则无此问题\n            //先判断如果在前，就 referIndex--，再insert\n\n            if (this.IndexOf(targetEvent) < referIndex)\n                referIndex--;\n\n            this.Remove(targetEvent);\n            this.Insert(referIndex, targetEvent);\n        }\n\n        /// <summary>\n        /// 将指定的事件移动到(紧邻)另一个事件之后\n        /// </summary>\n        /// <param name=\"targetEvent\"></param>\n        /// <param name=\"referEvent\"></param>\n        public void NextTo(ShengImageListViewItem targetEvent, ShengImageListViewItem referEvent)\n        {\n            if (targetEvent == null || referEvent == null)\n                return;\n\n            if (this.Contains(targetEvent) == false || this.Contains(referEvent) == false)\n                return;\n\n            //如果指定事件已经是最后个了，直接返回\n            //int targetIndex = this.IndexOf(targetEvent);\n            //if (targetIndex == this.Count - 1)\n            //    return;\n\n            int referIndex = this.IndexOf(referEvent);\n\n            //这里在remove之前，也要先判断目标事件是在指定事件之前还是之后\n            //如果在指定事件之后，那么referIndex++,不然就insert到指定事件前面了\n            if (this.IndexOf(targetEvent) > referIndex)\n                referIndex++;\n\n            this.Remove(targetEvent);\n            this.Insert(referIndex, targetEvent);\n        }\n\n        #endregion\n\n        #region ImageListViewItemEnumerator\n\n        [Serializable]\n        public class ImageListViewItemEnumerator : object, IEnumerator, IEnumerator<ShengImageListViewItem>\n        {\n            private IEnumerator baseEnumerator;\n\n            private IEnumerable temp;\n\n            public ImageListViewItemEnumerator(ShengImageListViewCollection mappings)\n            {\n                this.temp = ((IEnumerable)(mappings));\n                this.baseEnumerator = temp.GetEnumerator();\n            }\n\n            public ShengImageListViewItem Current\n            {\n                get\n                {\n                    return ((ShengImageListViewItem)(baseEnumerator.Current));\n                }\n            }\n\n            object IEnumerator.Current\n            {\n                get\n                {\n                    return baseEnumerator.Current;\n                }\n            }\n\n            public bool MoveNext()\n            {\n                return baseEnumerator.MoveNext();\n            }\n\n            bool IEnumerator.MoveNext()\n            {\n                return baseEnumerator.MoveNext();\n            }\n\n            public void Reset()\n            {\n                baseEnumerator.Reset();\n            }\n\n            void IEnumerator.Reset()\n            {\n                baseEnumerator.Reset();\n            }\n\n            #region IDisposable 成员\n\n            public void Dispose()\n            {\n\n            }\n\n            #endregion\n        }\n\n        #endregion\n\n        #region ICollection<ImageListViewItem> 成员\n\n        void ICollection<ShengImageListViewItem>.Add(ShengImageListViewItem item)\n        {\n            this.Add(item);\n        }\n\n        public bool IsReadOnly\n        {\n            get { return false; }\n        }\n\n        bool ICollection<ShengImageListViewItem>.Remove(ShengImageListViewItem item)\n        {\n            this.Remove(item);\n            return true;\n        }\n\n        #endregion\n\n        #region IEnumerable<ImageListViewItem> 成员\n\n        public new IEnumerator<ShengImageListViewItem> GetEnumerator()\n        {\n            return new ImageListViewItemEnumerator(this);\n        }\n\n        #endregion\n    }\n}\n\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengImageListView/ShengImageListViewColor.cs",
    "content": "using System.ComponentModel;\nusing System.Drawing;\nusing System;\nusing System.Reflection;\nusing System.Collections.Generic;\n\nnamespace Sheng.Winform.Controls\n{\n    /// <summary>\n    /// Represents the color palette of the image list view.\n    /// </summary>\n    public class ShengImageListViewColor\n    {\n        #region Member Variables\n        // control background color\n        Color mControlBackColor;\n\n        // item colors\n        Color mBackColor;\n        Color mBorderColor;\n        Color mUnFocusedColor1;\n        Color mUnFocusedColor2;\n        Color mUnFocusedBorderColor;\n        Color mUnFocusedForeColor;\n        Color mForeColor;\n        Color mHoverColor1;\n        Color mHoverColor2;\n        Color mHoverBorderColor;\n        Color mInsertionCaretColor;\n        Color mSelectedColor1;\n        Color mSelectedColor2;\n        Color mSelectedBorderColor;\n        Color mSelectedForeColor;\n\n        // thumbnail & pane\n        Color mImageInnerBorderColor;\n        Color mImageOuterBorderColor;\n\n        // details view\n        Color mCellForeColor;\n        Color mColumnHeaderBackColor1;\n        Color mColumnHeaderBackColor2;\n        Color mColumnHeaderForeColor;\n        Color mColumnHeaderHoverColor1;\n        Color mColumnHeaderHoverColor2;\n        Color mColumnSelectColor;\n        Color mColumnSeparatorColor;\n        Color mAlternateBackColor;\n        Color mAlternateCellForeColor;\n\n        // pane\n        Color mPaneBackColor;\n        Color mPaneSeparatorColor;\n        Color mPaneLabelColor;\n\n        // selection rectangle\n        Color mSelectionRectangleColor1;\n        Color mSelectionRectangleColor2;\n        Color mSelectionRectangleBorderColor;\n        #endregion\n\n        #region Properties\n        /// <summary>\n        /// Gets or sets the background color of the ImageListView control.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the background color of the ImageListView control.\")]\n        [DefaultValue(typeof(Color), \"Window\")]\n        public Color ControlBackColor\n        {\n            get { return mControlBackColor; }\n            set { mControlBackColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the background color of the ImageListViewItem.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the background color of the ImageListViewItem.\")]\n        [DefaultValue(typeof(Color), \"Window\")]\n        public Color BackColor\n        {\n            get { return mBackColor; }\n            set { mBackColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the background color of alternating cells in Details View.\n        /// </summary>\n        [Category(\"Appearance Details View\"), Description(\"Gets or sets the background color of alternating cells in Details View.\")]\n        [DefaultValue(typeof(Color), \"Window\")]\n        public Color AlternateBackColor\n        {\n            get { return mAlternateBackColor; }\n            set { mAlternateBackColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the border color of the ImageListViewItem.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the border color of the ImageListViewItem.\")]\n        [DefaultValue(typeof(Color), \"64, 128, 128, 128\")]\n        public Color BorderColor\n        {\n            get { return mBorderColor; }\n            set { mBorderColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the foreground color of the ImageListViewItem.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the foreground color of the ImageListViewItem.\")]\n        [DefaultValue(typeof(Color), \"ControlText\")]\n        public Color ForeColor\n        {\n            get { return mForeColor; }\n            set { mForeColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the background gradient color1 of the ImageListViewItem if the control is not focused.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the background gradient color1 of the ImageListViewItem if the control is not focused.\")]\n        [DefaultValue(typeof(Color), \"16, 128, 128, 128\")]\n        public Color UnFocusedColor1\n        {\n            get { return mUnFocusedColor1; }\n            set { mUnFocusedColor1 = value; }\n        }\n        /// <summary>\n        /// Gets or sets the background gradient color2 of the ImageListViewItem if the control is not focused.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the background gradient color2 of the ImageListViewItem if the control is not focused.\")]\n        [DefaultValue(typeof(Color), \"64, 128, 128, 128\")]\n        public Color UnFocusedColor2\n        {\n            get { return mUnFocusedColor2; }\n            set { mUnFocusedColor2 = value; }\n        }\n        /// <summary>\n        /// Gets or sets the border color of the ImageListViewItem if the control is not focused.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the border color of the ImageListViewItem if the control is not focused.\")]\n        [DefaultValue(typeof(Color), \"128, 128, 128, 128\")]\n        public Color UnFocusedBorderColor\n        {\n            get { return mUnFocusedBorderColor; }\n            set { mUnFocusedBorderColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the fore color of the ImageListViewItem if the control is not focused.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the fore color of the ImageListViewItem if the control is not focused.\")]\n        [DefaultValue(typeof(Color), \"ControlText\")]\n        public Color UnFocusedForeColor\n        {\n            get { return mUnFocusedForeColor; }\n            set { mUnFocusedForeColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the background gradient color1 if the ImageListViewItem is hovered.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the background gradient color1 if the ImageListViewItem is hovered.\")]\n        [DefaultValue(typeof(Color), \"8, 10, 36, 106\")]\n        public Color HoverColor1\n        {\n            get { return mHoverColor1; }\n            set { mHoverColor1 = value; }\n        }\n        /// <summary>\n        /// Gets or sets the background gradient color2 if the ImageListViewItem is hovered.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the background gradient color2 if the ImageListViewItem is hovered.\")]\n        [DefaultValue(typeof(Color), \"64, 10, 36, 106\")]\n        public Color HoverColor2\n        {\n            get { return mHoverColor2; }\n            set { mHoverColor2 = value; }\n        }\n        /// <summary>\n        /// Gets or sets the border color of the ImageListViewItem if the item is hovered.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the border color of the ImageListViewItem if the item is hovered.\")]\n        [DefaultValue(typeof(Color), \"64, 10, 36, 106\")]\n        public Color HoverBorderColor\n        {\n            get { return mHoverBorderColor; }\n            set { mHoverBorderColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the color of the insertion caret.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the color of the insertion caret.\")]\n        [DefaultValue(typeof(Color), \"Highlight\")]\n        public Color InsertionCaretColor\n        {\n            get { return mInsertionCaretColor; }\n            set { mInsertionCaretColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the background gradient color1 if the ImageListViewItem is selected.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the background gradient color1 if the ImageListViewItem is selected.\")]\n        [DefaultValue(typeof(Color), \"16, 10, 36, 106\")]\n        public Color SelectedColor1\n        {\n            get { return mSelectedColor1; }\n            set { mSelectedColor1 = value; }\n        }\n        /// <summary>\n        /// Gets or sets the background gradient color2 if the ImageListViewItem is selected.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the background gradient color2 if the ImageListViewItem is selected.\")]\n        [DefaultValue(typeof(Color), \"128, 10, 36, 106\")]\n        public Color SelectedColor2\n        {\n            get { return mSelectedColor2; }\n            set { mSelectedColor2 = value; }\n        }\n        /// <summary>\n        /// Gets or sets the border color of the ImageListViewItem if the item is selected.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the border color of the ImageListViewItem if the item is selected.\")]\n        [DefaultValue(typeof(Color), \"128, 10, 36, 106\")]\n        public Color SelectedBorderColor\n        {\n            get { return mSelectedBorderColor; }\n            set { mSelectedBorderColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the fore color of the ImageListViewItem if the item is selected.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the fore color of the ImageListViewItem if the item is selected.\")]\n        [DefaultValue(typeof(Color), \"ControlText\")]\n        public Color SelectedForeColor\n        {\n            get { return mSelectedForeColor; }\n            set { mSelectedForeColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the background gradient color1 of the column header.\n        /// </summary>\n        [Category(\"Appearance Details View\"), Description(\"Gets or sets the cells background color1 of the column header.\")]\n        [DefaultValue(typeof(Color), \"32, 212, 208, 200\")]\n        public Color ColumnHeaderBackColor1\n        {\n            get { return mColumnHeaderBackColor1; }\n            set { mColumnHeaderBackColor1 = value; }\n        }\n        /// <summary>\n        /// Gets or sets the background gradient color2 of the column header.\n        /// </summary>\n        [Category(\"Appearance Details View\"), Description(\"Gets or sets the cells background color2 of the column header.\")]\n        [DefaultValue(typeof(Color), \"196, 212, 208, 200\")]\n        public Color ColumnHeaderBackColor2\n        {\n            get { return mColumnHeaderBackColor2; }\n            set { mColumnHeaderBackColor2 = value; }\n        }\n        /// <summary>\n        /// Gets or sets the background hover gradient color1 of the column header.\n        /// </summary>\n        [Category(\"Appearance Details View\"), Description(\"Gets or sets the background hover color1 of the column header.\")]\n        [DefaultValue(typeof(Color), \"16, 10, 36, 106\")]\n        public Color ColumnHeaderHoverColor1\n        {\n            get { return mColumnHeaderHoverColor1; }\n            set { mColumnHeaderHoverColor1 = value; }\n        }\n        /// <summary>\n        /// Gets or sets the background hover gradient color2 of the column header.\n        /// </summary>\n        [Category(\"Appearance Details View\"), Description(\"Gets or sets the background hover color2 of the column header.\")]\n        [DefaultValue(typeof(Color), \"64, 10, 36, 106\")]\n        public Color ColumnHeaderHoverColor2\n        {\n            get { return mColumnHeaderHoverColor2; }\n            set { mColumnHeaderHoverColor2 = value; }\n        }\n        /// <summary>\n        /// Gets or sets the cells foreground color of the column header text.\n        /// </summary>\n        [Category(\"Appearance Details View\"), Description(\"Gets or sets the cells foreground color of the column header text.\")]\n        [DefaultValue(typeof(Color), \"WindowText\")]\n        public Color ColumnHeaderForeColor\n        {\n            get { return mColumnHeaderForeColor; }\n            set { mColumnHeaderForeColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the cells background color if column is selected in Details View.\n        /// </summary>\n        [Category(\"Appearance Details View\"), Description(\"Gets or sets the cells background color if column is selected in Details View.\")]\n        [DefaultValue(typeof(Color), \"16, 128, 128, 128\")]\n        public Color ColumnSelectColor\n        {\n            get { return mColumnSelectColor; }\n            set { mColumnSelectColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the color of the separator in Details View.\n        /// </summary>\n        [Category(\"Appearance Details View\"), Description(\"Gets or sets the color of the separator in Details View.\")]\n        [DefaultValue(typeof(Color), \"32, 128, 128, 128\")]\n        public Color ColumnSeparatorColor\n        {\n            get { return mColumnSeparatorColor; }\n            set { mColumnSeparatorColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the foreground color of the cell text in Details View.\n        /// </summary>\n        [Category(\"Appearance Details View\"), Description(\"Gets or sets the foreground color of the cell text in Details View.\")]\n        [DefaultValue(typeof(Color), \"ControlText\")]\n        public Color CellForeColor\n        {\n            get { return mCellForeColor; }\n            set { mCellForeColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the foreground color of alternating cells text in Details View.\n        /// </summary>\n        [Category(\"Appearance Details View\"), Description(\"Gets or sets the foreground color of alternating cells text in Details View.\")]\n        [DefaultValue(typeof(Color), \"ControlText\")]\n        public Color AlternateCellForeColor\n        {\n            get { return mAlternateCellForeColor; }\n            set { mAlternateCellForeColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the background color of the image pane.\n        /// </summary>\n        [Category(\"Appearance Pane View\"), Description(\"Gets or sets the background color of the image pane.\")]\n        [DefaultValue(typeof(Color), \"16, 128, 128, 128\")]\n        public Color PaneBackColor\n        {\n            get { return mPaneBackColor; }\n            set { mPaneBackColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the separator line color between image pane and thumbnail view.\n        /// </summary>\n        [Category(\"Appearance Pane View\"), Description(\"Gets or sets the separator line color between image pane and thumbnail view.\")]\n        [DefaultValue(typeof(Color), \"128, 128, 128, 128\")]\n        public Color PaneSeparatorColor\n        {\n            get { return mPaneSeparatorColor; }\n            set { mPaneSeparatorColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the color of labels in pane view.\n        /// </summary>\n        [Category(\"Appearance Pane View\"), Description(\"Gets or sets the color of labels in pane view.\")]\n        [DefaultValue(typeof(Color), \"196, 0, 0, 0\")]\n        public Color PaneLabelColor\n        {\n            get { return mPaneLabelColor; }\n            set { mPaneLabelColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the image inner border color for thumbnails and pane.\n        /// </summary>\n        [Category(\"Appearance Image\"), Description(\"Gets or sets the image inner border color for thumbnails and pane.\")]\n        [DefaultValue(typeof(Color), \"128, 255, 255, 255\")]\n        public Color ImageInnerBorderColor\n        {\n            get { return mImageInnerBorderColor; }\n            set { mImageInnerBorderColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the image outer border color for thumbnails and pane.\n        /// </summary>\n        [Category(\"Appearance Image\"), Description(\"Gets or sets the image outer border color for thumbnails and pane.\")]\n        [DefaultValue(typeof(Color), \"128, 128, 128, 128\")]\n        public Color ImageOuterBorderColor\n        {\n            get { return mImageOuterBorderColor; }\n            set { mImageOuterBorderColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the background color1 of the selection rectangle.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the background color1 of the selection rectangle.\")]\n        [DefaultValue(typeof(Color), \"128, 10, 36, 106\")]\n        public Color SelectionRectangleColor1\n        {\n            get { return mSelectionRectangleColor1; }\n            set { mSelectionRectangleColor1 = value; }\n        }\n        /// <summary>\n        /// Gets or sets the background color2 of the selection rectangle.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the background color2 of the selection rectangle.\")]\n        [DefaultValue(typeof(Color), \"128, 10, 36, 106\")]\n        public Color SelectionRectangleColor2\n        {\n            get { return mSelectionRectangleColor2; }\n            set { mSelectionRectangleColor2 = value; }\n        }\n        /// <summary>\n        /// Gets or sets the color of the selection rectangle border.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the color of the selection rectangle border.\")]\n        [DefaultValue(typeof(Color), \"Highlight\")]\n        public Color SelectionRectangleBorderColor\n        {\n            get { return mSelectionRectangleBorderColor; }\n            set { mSelectionRectangleBorderColor = value; }\n        }\n        #endregion\n\n        #region Constructors\n        /// <summary>\n        /// Initializes a new instance of the ImageListViewColor class.\n        /// </summary>\n        public ShengImageListViewColor()\n        {\n            // control\n            mControlBackColor = SystemColors.Window;\n\n            // item\n            mBackColor = SystemColors.Window;\n            mForeColor = SystemColors.ControlText;\n\n            mBorderColor = Color.FromArgb(64, SystemColors.GrayText);\n\n            mUnFocusedColor1 = Color.FromArgb(16, SystemColors.GrayText);\n            mUnFocusedColor2 = Color.FromArgb(64, SystemColors.GrayText);\n            mUnFocusedBorderColor = Color.FromArgb(128, SystemColors.GrayText);\n            mUnFocusedForeColor = SystemColors.ControlText;\n\n            mHoverColor1 = Color.FromArgb(8, SystemColors.Highlight);\n            mHoverColor2 = Color.FromArgb(64, SystemColors.Highlight);\n            mHoverBorderColor = Color.FromArgb(64, SystemColors.Highlight);\n\n            mSelectedColor1 = Color.FromArgb(16, SystemColors.Highlight);\n            mSelectedColor2 = Color.FromArgb(128, SystemColors.Highlight);\n            mSelectedBorderColor = Color.FromArgb(128, SystemColors.Highlight);\n            mSelectedForeColor = SystemColors.ControlText;\n\n            mInsertionCaretColor = SystemColors.Highlight;\n\n            // thumbnails\n            mImageInnerBorderColor = Color.FromArgb(128, Color.White);\n            mImageOuterBorderColor = Color.FromArgb(128, Color.Gray);\n\n            // details view\n            mColumnHeaderBackColor1 = Color.FromArgb(32, SystemColors.Control);\n            mColumnHeaderBackColor2 = Color.FromArgb(196, SystemColors.Control);\n            mColumnHeaderHoverColor1 = Color.FromArgb(16, SystemColors.Highlight);\n            mColumnHeaderHoverColor2 = Color.FromArgb(64, SystemColors.Highlight);\n            mColumnHeaderForeColor = SystemColors.WindowText;\n            mColumnSelectColor = Color.FromArgb(16, SystemColors.GrayText);\n            mColumnSeparatorColor = Color.FromArgb(32, SystemColors.GrayText);\n            mCellForeColor = SystemColors.ControlText;\n            mAlternateBackColor = SystemColors.Window;\n            mAlternateCellForeColor = SystemColors.ControlText;\n\n            // image pane\n            mPaneBackColor = Color.FromArgb(16, SystemColors.GrayText);\n            mPaneSeparatorColor = Color.FromArgb(128, SystemColors.GrayText);\n            mPaneLabelColor = Color.FromArgb(196, Color.Black);\n\n            // selection rectangle\n            mSelectionRectangleColor1 = Color.FromArgb(128, SystemColors.Highlight);\n            mSelectionRectangleColor2 = Color.FromArgb(128, SystemColors.Highlight);\n            mSelectionRectangleBorderColor = SystemColors.Highlight;\n        }\n\n        /// <summary>\n        /// Initializes a new instance of the ImageListViewColor class\n        /// from its string representation.\n        /// </summary>\n        /// <param name=\"definition\">String representation of the object.</param>\n        public ShengImageListViewColor(string definition)\n            : this()\n        {\n            try\n            {\n                // First check if the color matches a predefined color setting\n                foreach (MemberInfo info in typeof(ShengImageListViewColor).GetMembers(BindingFlags.Static | BindingFlags.Public))\n                {\n                    if (info.MemberType == MemberTypes.Property)\n                    {\n                        PropertyInfo propertyInfo = (PropertyInfo)info;\n                        if (propertyInfo.PropertyType == typeof(ShengImageListViewColor))\n                        {\n                            // If the color setting is equal to a preset value\n                            // return the preset\n                            if (definition == string.Format(\"({0})\", propertyInfo.Name) ||\n                                definition == propertyInfo.Name)\n                            {\n                                ShengImageListViewColor presetValue = (ShengImageListViewColor)propertyInfo.GetValue(null, null);\n                                CopyFrom(presetValue);\n                                return;\n                            }\n                        }\n                    }\n                }\n\n                // Convert color values\n                foreach (string line in definition.Split(new string[] { \";\" }, StringSplitOptions.RemoveEmptyEntries))\n                {\n                    // Read the color setting\n                    string[] pair = line.Split(new string[] { \"=\" }, StringSplitOptions.RemoveEmptyEntries);\n                    string name = pair[0].Trim();\n                    Color color = Color.FromName(pair[1].Trim());\n                    // Set the property value\n                    PropertyInfo property = typeof(ShengImageListViewColor).GetProperty(name);\n                    property.SetValue(this, color, null);\n                }\n            }\n            catch\n            {\n                throw new ArgumentException(\"Invalid string format\", \"definition\");\n            }\n        }\n        #endregion\n\n        #region InstanceMethods\n        /// <summary>\n        /// Copies color values from the given object.\n        /// </summary>\n        /// <param name=\"source\">The source object.</param>\n        public void CopyFrom(ShengImageListViewColor source)\n        {\n            foreach (PropertyInfo info in typeof(ShengImageListViewColor).GetProperties())\n            {\n                // Walk through color properties\n                if (info.PropertyType == typeof(Color))\n                {\n                    Color color = (Color)info.GetValue(source, null);\n                    info.SetValue(this, color, null);\n                }\n            }\n        }\n        #endregion\n\n        #region Static Members\n        /// <summary>\n        /// Represents the default color theme.\n        /// </summary>\n        public static ShengImageListViewColor Default { get { return ShengImageListViewColor.GetDefaultTheme(); } }\n        /// <summary>\n        /// Represents the noir color theme.\n        /// </summary>\n        public static ShengImageListViewColor Noir { get { return ShengImageListViewColor.GetNoirTheme(); } }\n        /// <summary>\n        /// Represents the mandarin color theme.\n        /// </summary>\n        public static ShengImageListViewColor Mandarin { get { return ShengImageListViewColor.GetMandarinTheme(); } }\n\n        /// <summary>\n        /// Sets the color palette to default colors.\n        /// </summary>\n        private static ShengImageListViewColor GetDefaultTheme()\n        {\n            return new ShengImageListViewColor();\n        }\n        /// <summary>\n        /// Sets the color palette to mandarin colors.\n        /// </summary>\n        private static ShengImageListViewColor GetMandarinTheme()\n        {\n            ShengImageListViewColor c = new ShengImageListViewColor();\n\n            // control\n            c.ControlBackColor = Color.White;\n\n            // item\n            c.BackColor = Color.White;\n            c.ForeColor = Color.FromArgb(60, 60, 60);\n            c.BorderColor = Color.FromArgb(187, 190, 183);\n\n            c.UnFocusedColor1 = Color.FromArgb(235, 235, 235);\n            c.UnFocusedColor2 = Color.FromArgb(217, 217, 217);\n            c.UnFocusedBorderColor = Color.FromArgb(168, 169, 161);\n            c.UnFocusedForeColor = Color.FromArgb(40, 40, 40);\n\n            c.HoverColor1 = Color.Transparent;\n            c.HoverColor2 = Color.Transparent;\n            c.HoverBorderColor = Color.Transparent;\n\n            c.SelectedColor1 = Color.FromArgb(244, 125, 77);\n            c.SelectedColor2 = Color.FromArgb(235, 110, 60);\n            c.SelectedBorderColor = Color.FromArgb(240, 119, 70);\n            c.SelectedForeColor = Color.White;\n\n            c.InsertionCaretColor = Color.FromArgb(240, 119, 70);\n\n            // thumbnails & pane\n            c.ImageInnerBorderColor = Color.Transparent;\n            c.ImageOuterBorderColor = Color.White;\n\n            // details view\n            c.CellForeColor = Color.FromArgb(60, 60, 60);\n            c.ColumnHeaderBackColor1 = Color.FromArgb(247, 247, 247);\n            c.ColumnHeaderBackColor2 = Color.FromArgb(235, 235, 235);\n            c.ColumnHeaderHoverColor1 = Color.White;\n            c.ColumnHeaderHoverColor2 = Color.FromArgb(245, 245, 245);\n            c.ColumnHeaderForeColor = Color.FromArgb(60, 60, 60);\n            c.ColumnSelectColor = Color.FromArgb(34, 128, 128, 128);\n            c.ColumnSeparatorColor = Color.FromArgb(106, 128, 128, 128);\n            c.mAlternateBackColor = Color.FromArgb(234, 234, 234);\n            c.mAlternateCellForeColor = Color.FromArgb(40, 40, 40);\n\n            // image pane\n            c.PaneBackColor = Color.White;\n            c.PaneSeparatorColor = Color.FromArgb(216, 216, 216);\n            c.PaneLabelColor = Color.FromArgb(156, 156, 156);\n\n            // selection rectangle\n            c.SelectionRectangleColor1 = Color.FromArgb(64, 240, 116, 68);\n            c.SelectionRectangleColor2 = Color.FromArgb(64, 240, 116, 68);\n            c.SelectionRectangleBorderColor = Color.FromArgb(240, 119, 70);\n\n            return c;\n        }\n        /// <summary>\n        /// Sets the color palette to noir colors.\n        /// </summary>\n        private static ShengImageListViewColor GetNoirTheme()\n        {\n            ShengImageListViewColor c = new ShengImageListViewColor();\n\n            // control\n            c.ControlBackColor = Color.Black;\n\n            // item\n            c.BackColor = Color.FromArgb(0x31, 0x31, 0x31);\n            c.ForeColor = Color.LightGray;\n\n            c.BorderColor = Color.DarkGray;\n\n            c.UnFocusedColor1 = Color.FromArgb(16, SystemColors.GrayText);\n            c.UnFocusedColor2 = Color.FromArgb(64, SystemColors.GrayText);\n            c.UnFocusedBorderColor = Color.FromArgb(128, SystemColors.GrayText);\n            c.UnFocusedForeColor = Color.LightGray;\n\n            c.HoverColor1 = Color.FromArgb(64, Color.White);\n            c.HoverColor2 = Color.FromArgb(16, Color.White);\n            c.HoverBorderColor = Color.FromArgb(64, SystemColors.Highlight);\n\n            c.SelectedColor1 = Color.FromArgb(64, 96, 160);\n            c.SelectedColor2 = Color.FromArgb(64, 64, 96, 160);\n            c.SelectedBorderColor = Color.FromArgb(128, SystemColors.Highlight);\n            c.SelectedForeColor = Color.LightGray;\n\n            c.InsertionCaretColor = Color.FromArgb(96, 144, 240);\n\n            // thumbnails & pane\n            c.ImageInnerBorderColor = Color.FromArgb(128, Color.White);\n            c.ImageOuterBorderColor = Color.FromArgb(128, Color.Gray);\n\n            // details view\n            c.CellForeColor = Color.WhiteSmoke;\n            c.ColumnHeaderBackColor1 = Color.FromArgb(32, 128, 128, 128);\n            c.ColumnHeaderBackColor2 = Color.FromArgb(196, 128, 128, 128);\n            c.ColumnHeaderHoverColor1 = Color.FromArgb(64, 96, 144, 240);\n            c.ColumnHeaderHoverColor2 = Color.FromArgb(196, 96, 144, 240);\n            c.ColumnHeaderForeColor = Color.White;\n            c.ColumnSelectColor = Color.FromArgb(96, 128, 128, 128);\n            c.ColumnSeparatorColor = Color.Gold;\n            c.AlternateBackColor = Color.FromArgb(0x31, 0x31, 0x31);\n            c.AlternateCellForeColor = Color.WhiteSmoke;\n\n            // image pane\n            c.PaneBackColor = Color.FromArgb(0x31, 0x31, 0x31);\n            c.PaneSeparatorColor = Color.Gold;\n            c.PaneLabelColor = SystemColors.GrayText;\n\n            // selection rectangke\n            c.SelectionRectangleColor1 = Color.FromArgb(160, 96, 144, 240);\n            c.SelectionRectangleColor2 = Color.FromArgb(32, 96, 144, 240);\n            c.SelectionRectangleBorderColor = Color.FromArgb(64, 96, 144, 240);\n\n            return c;\n        }\n        #endregion\n\n        #region System.Object Overrides\n        /// <summary>\n        /// Determines whether all color values of the specified \n        /// ImageListViewColor are equal to this instance.\n        /// </summary>\n        /// <param name=\"obj\">The object to compare with this instance.</param>\n        /// <returns>true if the two instances have the same color values; \n        /// otherwise false.</returns>\n        public override bool Equals(object obj)\n        {\n            if (obj == null)\n                throw new NullReferenceException();\n\n            ShengImageListViewColor other = obj as ShengImageListViewColor;\n            if (other == null) return false;\n\n            foreach (PropertyInfo info in typeof(ShengImageListViewColor).GetProperties())\n            {\n                // Walk through color properties\n                if (info.PropertyType == typeof(Color))\n                {\n                    // Compare colors\n                    Color color1 = (Color)info.GetValue(this, null);\n                    Color color2 = (Color)info.GetValue(other, null);\n\n                    if (color1 != color2) return false;\n                }\n            }\n\n            return true;\n        }\n        /// <summary>\n        /// Returns a hash code for this instance.\n        /// </summary>\n        /// <returns>\n        /// A hash code for this instance, suitable for use in \n        /// hashing algorithms and data structures like a hash table. \n        /// </returns>\n        public override int GetHashCode()\n        {\n            return base.GetHashCode();\n        }\n\n        /// <summary>\n        /// Returns a string that represents this instance.\n        /// </summary>\n        /// <returns>\n        /// A string that represents this instance.\n        /// </returns>\n        public override string ToString()\n        {\n            ShengImageListViewColor colors = this;\n\n            // First check if the color matches a predefined color setting\n            foreach (MemberInfo info in typeof(ShengImageListViewColor).GetMembers(BindingFlags.Static | BindingFlags.Public))\n            {\n                if (info.MemberType == MemberTypes.Property)\n                {\n                    PropertyInfo propertyInfo = (PropertyInfo)info;\n                    if (propertyInfo.PropertyType == typeof(ShengImageListViewColor))\n                    {\n                        ShengImageListViewColor presetValue = (ShengImageListViewColor)propertyInfo.GetValue(null, null);\n                        // If the color setting is equal to a preset value\n                        // return the name of the preset\n                        if (colors.Equals(presetValue))\n                            return string.Format(\"({0})\", propertyInfo.Name);\n                    }\n                }\n            }\n\n            // Serialize all colors which are different from the default setting\n            List<string> lines = new List<string>();\n            foreach (PropertyInfo info in typeof(ShengImageListViewColor).GetProperties())\n            {\n                // Walk through color properties\n                if (info.PropertyType == typeof(Color))\n                {\n                    // Get property name\n                    string name = info.Name;\n                    // Get the current value\n                    Color color = (Color)info.GetValue(colors, null);\n                    // Find the default value atribute\n                    Attribute[] attributes = (Attribute[])info.GetCustomAttributes(typeof(DefaultValueAttribute), false);\n                    if (attributes.Length != 0)\n                    {\n                        // Get the default value\n                        DefaultValueAttribute attribute = (DefaultValueAttribute)attributes[0];\n                        Color defaultColor = (Color)attribute.Value;\n                        // Serialize only if colors are different\n                        if (color != defaultColor)\n                        {\n                            lines.Add(string.Format(\"{0} = {1}\", name, color.Name));\n                        }\n                    }\n                }\n            }\n\n            return string.Join(\"; \", lines.ToArray());\n        }\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengImageListView/ShengImageListViewHitInfo.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nnamespace Sheng.Winform.Controls\n{\n    /// <summary>\n    /// 测试坐标\n    /// </summary>\n    class ShengImageListViewHitInfo\n    {\n        /// <summary>\n        /// 项的坐标\n        /// </summary>\n        public int ItemIndex { get; private set; }\n\n        /// <summary>\n        /// 是否点击了项\n        /// </summary>\n        public bool ItemHit { get; private set; }\n\n        public ShengImageListViewHitInfo(int itemIndex,bool itemHit)\n        {\n            ItemIndex = itemIndex;\n            ItemHit = itemHit;\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengImageListView/ShengImageListViewItem.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Drawing;\n\nnamespace Sheng.Winform.Controls\n{\n    public class ShengImageListViewItem\n    {\n        #region 私有成员\n\n        /// <summary>\n        /// 获取项的图像\n        /// 加这个委托是为了延迟加载\n        /// 只在需要第一次呈现时才会调用，初始化ImageListViewItem时只传一个名子就可以\n        /// 无需在加载项时为所有项获取生成Image对象\n        /// </summary>\n        /// <param name=\"name\"></param>\n        /// <returns></returns>\n        public delegate Image GetImageHandler(object key);\n        private GetImageHandler _getImageHandler;\n\n        #endregion\n\n        #region 受保护的成员\n\n        private ShengImageListViewCollection _ownerCollection;\n        internal ShengImageListViewCollection OwnerCollection\n        {\n            get { return _ownerCollection; }\n            set { _ownerCollection = value; }\n        }\n\n        #endregion\n\n        #region 公开属性\n\n        public int Index\n        {\n            get\n            {\n                return _ownerCollection.IndexOf(this);\n            }\n        }\n\n        private ShengImageListViewItemState _state = ShengImageListViewItemState.None;\n        /// <summary>\n        /// 该项当前的选中状态\n        /// </summary>\n        public ShengImageListViewItemState State\n        {\n            get { return _state; }\n        }\n\n        public bool Selected\n        {\n            get\n            {\n                return (_state & ShengImageListViewItemState.Selected) == ShengImageListViewItemState.Selected;\n            }\n            set\n            {\n                bool selected = Selected;\n\n                if (value)\n                    _state = _state | ShengImageListViewItemState.Selected;\n                else\n                    _state = _state ^ ShengImageListViewItemState.Selected;\n\n                if (selected != Selected)\n                    Render();\n            }\n        }\n\n        public bool Hovered\n        {\n            get\n            {\n                return (_state & ShengImageListViewItemState.Hovered) == ShengImageListViewItemState.Hovered;\n            }\n            set\n            {\n                bool hovered = Hovered;\n\n                if (value)\n                    _state = _state | ShengImageListViewItemState.Hovered;\n                else\n                    _state = _state ^ ShengImageListViewItemState.Hovered;\n\n                if (hovered != Hovered)\n                    Render();\n            }\n        }\n\n        public bool Focused\n        {\n            get\n            {\n                return (_state & ShengImageListViewItemState.Focused) == ShengImageListViewItemState.Focused;\n            }\n            set\n            {\n                bool focused = Focused;\n\n                if (value)\n                    _state = _state | ShengImageListViewItemState.Focused;\n                else\n                    _state = _state ^ ShengImageListViewItemState.Focused;\n\n                if (focused != Focused)\n                    Render();\n            }\n        }\n\n        /// <summary>\n        /// 项的唯一标识\n        /// 可以是一个文件名，或者就是FileInfo\n        /// </summary>\n        public object Key\n        {\n            get;\n            set;\n        }\n\n        /// <summary>\n        /// 呈现在缩略图下方的标题文本\n        /// </summary>\n        public string Header\n        {\n            get;\n            set;\n        }\n\n        private Image _image;\n        public Image Image\n        {\n            get\n            {\n                if (_image == null)\n                    _image = _getImageHandler(Key);\n\n                return _image;\n            }\n        }\n\n        #endregion\n\n        #region 构造\n\n        public ShengImageListViewItem(object key, GetImageHandler getImageHandler)\n            : this(key, key.ToString(), getImageHandler)\n        {\n\n        }\n\n        public ShengImageListViewItem(object key, string header, GetImageHandler getImageHandler)\n        {\n            this.Key = key;\n            this.Header = header;\n            this._getImageHandler = getImageHandler;\n        }\n\n        #endregion\n\n        #region 私有方法\n\n        private void Render()\n        {\n            _ownerCollection.Owner.RenderItem(this);\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengImageListView/ShengImageListViewItemThumbnailsCache.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Drawing;\nusing System.Diagnostics;\n\nnamespace Sheng.Winform.Controls\n{\n    /// <summary>\n    /// 缓存项的缩略图\n    /// </summary>\n    class ShengImageListViewItemThumbnailsCache\n    {\n        #region 私有成员\n\n        private Dictionary<ShengImageListViewItem, Image> _thumbnails = new Dictionary<ShengImageListViewItem, Image>();\n\n        #endregion\n\n        #region 构造\n\n        public ShengImageListViewItemThumbnailsCache()\n        {\n\n        }\n\n        #endregion\n\n        #region 公开方法\n\n        public bool Container(ShengImageListViewItem item)\n        {\n            Debug.Assert(item != null, \"ImageListViewItem 为 null\");\n\n            if (item == null)\n                return false;\n\n            return _thumbnails.Keys.Contains(item);\n        }\n\n        public Image GetThumbnail(ShengImageListViewItem item)\n        {\n            Debug.Assert(item != null, \"ImageListViewItem 为 null\");\n\n            if (item == null)\n                throw new ArgumentNullException();\n\n            if (Container(item) == false)\n                throw new ArgumentOutOfRangeException();\n\n            return _thumbnails[item];\n        }\n\n        public void AddThumbnail(ShengImageListViewItem item, Image thumbnail)\n        {\n            Debug.Assert(item != null, \"ImageListViewItem 为 null\");\n            Debug.Assert(thumbnail != null, \"thumbnail 为 null\");\n\n            if (item == null || thumbnail == null)\n                return;\n\n            if (Container(item))\n            {\n                Debug.Assert(false, \"已经缓存过了指定 ImageListViewItem 的缩略图\");\n                return;\n            }\n\n            _thumbnails.Add(item, thumbnail);\n        }\n\n        /// <summary>\n        /// 移除指定项的缓存缩略图，并dispose\n        /// </summary>\n        /// <param name=\"item\"></param>\n        public void RemoveThumbnail(ShengImageListViewItem item)\n        {\n            Debug.Assert(item != null, \"ImageListViewItem 为 null\");\n\n            if (item == null)\n                return;\n\n            if (Container(item) == false)\n            {\n                Debug.Assert(false, \"不存在指定 ImageListViewItem 的缓存缩略图\");\n                return;\n            }\n\n            _thumbnails[item].Dispose();\n            _thumbnails.Remove(item);\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengImageListView/ShengImageListViewLayoutManager.cs",
    "content": "﻿using System;\r\nusing System.Collections.Generic;\r\nusing System.Linq;\r\nusing System.Text;\r\nusing System.Drawing;\r\nusing System.Windows.Forms;\r\nusing System.Diagnostics;\r\n\r\nnamespace Sheng.Winform.Controls\r\n{\r\n    public class ShengImageListViewLayoutManager\r\n    {\r\n        #region 常量\r\n\r\n        /// <summary>\r\n        /// 框选的最短开始长度\r\n        /// </summary>\r\n        private const int SELECTION_TOLERANCE = 5;\r\n\r\n        /// <summary>\r\n        /// 框选时滚动条的自动滚动速度\r\n        /// </summary>\r\n        private const int AUTOSCROLL_VALUE = 10;\r\n\r\n        #endregion\r\n\r\n        #region 私有成员\r\n\r\n        private ShengImageListView _imageListView;\r\n\r\n        //滚动条放到布局引擎中来定义，这样可以实现不同布局引擎完全不同的布局方式\r\n        //比如为图像分组显示的引擎可以同时显示多个水平滚动条\r\n        private VScrollBar _vScrollBar = new VScrollBar();\r\n\r\n        private int ScrollBarWidth\r\n        {\r\n            get { return _vScrollBar.Width; }\r\n        }\r\n\r\n        /// <summary>\r\n        /// 用于鼠标框选时，框出了控件中项的显示范围时，自动滚动滚动条\r\n        /// </summary>\r\n        private Timer _scrollTimer = new Timer();\r\n\r\n        /// <summary>\r\n        /// 自动滚动时，滚动值\r\n        /// </summary>\r\n        private int _autoScrollValue = 0;\r\n\r\n        /// <summary>\r\n        /// 是否处于框选状态中\r\n        /// </summary>\r\n        internal bool MouseSelecting { get; private set; }\r\n\r\n        private ShengImageListViewRenderer _renderer;\r\n        public ShengImageListViewRenderer Renderer\r\n        {\r\n            get { return _renderer; }\r\n            set { _renderer = value; }\r\n        }\r\n\r\n        /// <summary>\r\n        /// 内框offset，内框offset是绝对相对于滚动条的\r\n        /// </summary>\r\n        private int _itemsAreaOffset = 0;\r\n\r\n        /// <summary>\r\n        /// 整个可显示项的边界的offset，包括上下padding部分\r\n        /// </summary>\r\n        private int _itemsBoundsOffset\r\n        {\r\n            get\r\n            {\r\n                int offSet = _itemsAreaOffset - (ItemsArea.Location.Y - ItemsBounds.Location.Y);\r\n                if (offSet < 0)\r\n                    offSet = 0;\r\n                return offSet;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// 鼠标按下时项区域边界的offset，即 _itemsAreaOffset\r\n        /// 用于框选时，跨越可视部队画框\r\n        /// </summary>\r\n        private int _mouseItemsAreaOffset = 0;\r\n\r\n        /// <summary>\r\n        /// 当前所能显示的最大列数\r\n        /// </summary>\r\n        private int _columnCount;\r\n\r\n        /// <summary>\r\n        /// 当前所能显示的最大行数\r\n        /// </summary>\r\n        private int _rowCount;\r\n\r\n        #endregion\r\n\r\n        #region 公开属性\r\n\r\n        /// <summary>\r\n        /// 项的大小\r\n        /// </summary>\r\n        private Size _itemSize;\r\n        internal Size ItemSize\r\n        {\r\n            get { return _itemSize; }\r\n        }\r\n\r\n        /// <summary>\r\n        /// 项连同边距在内的大小\r\n        /// </summary>\r\n        private Size _itemSizeWithMargin;\r\n        internal Size ItemSizeWithMargin\r\n        {\r\n            get { return _itemSizeWithMargin; }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets whether the shift key is down.\r\n        /// </summary>\r\n        internal bool ShiftKey { get { return _imageListView.ShiftKey; } }\r\n        /// <summary>\r\n        /// Gets whether the control key is down.\r\n        /// </summary>\r\n        internal bool ControlKey { get { return _imageListView.ControlKey; } }\r\n\r\n        internal bool Focused { get { return _imageListView.Focused; } }\r\n\r\n        internal Rectangle SelectionRectangle { get; private set; }\r\n\r\n        internal bool Suspend\r\n        {\r\n            get { return _imageListView.Suspend; }\r\n        }\r\n\r\n        //TODO:在出现滚动条后，计算错误\r\n        //临时调用用，完成后改为internal\r\n        private int _firstPartiallyVisible;\r\n        public int FirstPartiallyVisible { get { return _firstPartiallyVisible; } }\r\n\r\n        private int _lastPartiallyVisible;\r\n        public int LastPartiallyVisible { get { return _lastPartiallyVisible; } }\r\n\r\n        private int _firstVisible;\r\n        public int FirstVisible { get { return _firstVisible; } }\r\n\r\n        private int _lastVisible;\r\n        public int LastVisible { get { return _lastVisible; } }\r\n\r\n        /// <summary>\r\n        /// 没有任何项\r\n        /// </summary>\r\n        public bool IsEmpty\r\n        {\r\n            get\r\n            {\r\n                return _imageListView.IsEmpty;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// 没有任何项处于可显示状态\r\n        /// </summary>\r\n        public bool NoneItemVisible\r\n        {\r\n            get\r\n            {\r\n                return _firstPartiallyVisible == -1 || _lastPartiallyVisible == -1;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// 整个控件区域\r\n        /// </summary>\r\n        public Rectangle ClientArea\r\n        {\r\n            get { return _imageListView.ClientRectangle; }\r\n        }\r\n\r\n        /// <summary>\r\n        /// 整个可用于绘制项的可视区域\r\n        /// 去除左右Padding部分，去除滚动条\r\n        /// </summary>\r\n        public Rectangle ItemsBounds\r\n        {\r\n            get\r\n            {\r\n                int scrollBarWidth = this.ScrollBarWidth;\r\n                Rectangle clientArea = this.ClientArea;\r\n                Padding padding = _imageListView.Padding;\r\n                int x = padding.Left;\r\n                int width = clientArea.Width - padding.Left - padding.Right - scrollBarWidth;\r\n\r\n                Rectangle itemsBounds = new Rectangle(x, clientArea.Y, width, clientArea.Height);\r\n                return itemsBounds;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// 用于绘制项的区域\r\n        /// </summary>\r\n        public Rectangle ItemsArea\r\n        {\r\n            //要考虑边距间隔大小和滚动条区域\r\n            get\r\n            {\r\n                int scrollBarWidth = this.ScrollBarWidth;\r\n                Rectangle clientArea = this.ClientArea;\r\n                Padding padding = _imageListView.Padding;\r\n                int x = padding.Left;\r\n                int y = padding.Top;\r\n                int width = clientArea.Width - padding.Left - padding.Right - scrollBarWidth;\r\n                int height = clientArea.Height - padding.Top - padding.Bottom;\r\n\r\n                //在最小化窗口后，clientArea的尺寸为0\r\n                if (width < 0) width = 1;\r\n                if (height < 0) height = 1;\r\n\r\n                Rectangle itemsArea = new Rectangle(x, y, width, height);\r\n                return itemsArea;\r\n            }\r\n        }\r\n\r\n        private int _imageSize = 100;\r\n        /// <summary>\r\n        /// 项的尺寸\r\n        /// </summary>\r\n        public int ImageSize\r\n        {\r\n            get { return _imageSize; }\r\n            set\r\n            {\r\n                _imageSize = value;\r\n                _itemSize.Height = _itemSize.Width = value;\r\n            }\r\n        }\r\n\r\n        private int _margin = 4;\r\n        /// <summary>\r\n        /// 项周围的边距\r\n        /// </summary>\r\n        public int Margin\r\n        {\r\n            get { return _margin; }\r\n            set\r\n            {\r\n                _margin = value;\r\n                _itemSizeWithMargin = _itemSize + new Size(value, value);\r\n            }\r\n        }\r\n\r\n        #endregion\r\n\r\n        #region debug 临时调试用\r\n\r\n        public int StartRow { get; set; }\r\n        public int EndRow { get; set; }\r\n        public int StartCol { get; set; }\r\n        public int EndCol { get; set; }\r\n\r\n        #endregion\r\n\r\n        #region 构造\r\n\r\n        public ShengImageListViewLayoutManager(ShengImageListView imageListView)\r\n        {\r\n            _imageListView = imageListView;\r\n\r\n            _itemSize = new Size(ImageSize, ImageSize);\r\n            _itemSizeWithMargin = _itemSize + new Size(Margin, Margin);\r\n\r\n            UpdateScrollBars();\r\n\r\n            _vScrollBar.Dock = DockStyle.Right;\r\n            _imageListView.Controls.Add(_vScrollBar);\r\n            _vScrollBar.Scroll += new ScrollEventHandler(_vScrollBar_Scroll);\r\n            _vScrollBar.ValueChanged += new EventHandler(_vScrollBar_ValueChanged);\r\n\r\n            _scrollTimer.Interval = 20;\r\n            _scrollTimer.Enabled = false;\r\n            _scrollTimer.Tick += new EventHandler(_scrollTimer_Tick);\r\n\r\n            _renderer = new ShengImageListViewStandardRenderer(this);\r\n            //_renderer = new ShengImageListViewRenderer(this);\r\n            _renderer.Theme = _imageListView.Theme;\r\n        }\r\n\r\n        #endregion\r\n\r\n        #region 事件处理\r\n\r\n        void _vScrollBar_Scroll(object sender, ScrollEventArgs e)\r\n        {\r\n            //这里判断的原因是在鼠标操作滚动条时，即使只点一下，这里也会进来两次，原因不明\r\n            if (_itemsAreaOffset != e.NewValue)\r\n            {\r\n                _itemsAreaOffset = e.NewValue;\r\n            }\r\n        }\r\n\r\n        void _vScrollBar_ValueChanged(object sender, EventArgs e)\r\n        {\r\n            //这里判断的原因是可能在 _vScrollBar_Scroll 事件里就赋值过了\r\n            if (_itemsAreaOffset != _vScrollBar.Value)\r\n            {\r\n                _itemsAreaOffset = _vScrollBar.Value;\r\n            }\r\n\r\n            _imageListView.SuspendLayout();\r\n\r\n            if (MouseSelecting)\r\n            {\r\n                //如果处于框选状态，在重新绘制控件之前需要计算新的 SelectionRectangle\r\n                //因为SelectionRectangle一开始是在MouseMove中计算的，而当鼠标拉出控件边界时\r\n                //滚动条会继续滚动，如果此时保持鼠标不动，就要靠这里计算 SelectionRectangle 了\r\n                SelectionRectangle = CreateSelectionRectangle();\r\n                SelectItemsByRectangle(SelectionRectangle);\r\n            }\r\n\r\n            Refresh();\r\n            _imageListView.ResumeLayout();\r\n\r\n            CalculateVisibleItemsRange();            \r\n        }\r\n\r\n        void _scrollTimer_Tick(object sender, EventArgs e)\r\n        {\r\n            //自动滚动之后，必须重新绘制控件\r\n            //借助 _vScrollBar_ValueChanged 事件实现\r\n\r\n            //另外，在自动滚动之后，光重绘还不行，必须重新计算 SelectionRectangle\r\n            //SelectionRectangle 一开始是在 MouseMove 中计算的，如果在自动滚动的过程中不移动鼠标\r\n            //那就靠 _vScrollBar_ValueChanged 计算了\r\n\r\n            int scrollValue = _vScrollBar.Value + _autoScrollValue;\r\n            if (scrollValue > _vScrollBar.Maximum)\r\n                _vScrollBar.Value = _vScrollBar.Maximum;\r\n            else if (scrollValue < 0)\r\n                _vScrollBar.Value = 0;\r\n            else\r\n                _vScrollBar.Value = scrollValue;\r\n        }\r\n\r\n        #endregion\r\n\r\n        #region 受保护的方法\r\n\r\n        internal void OnItemsRemoved(List<ShengImageListViewItem> items)\r\n        {\r\n            _renderer.OnItemsRemoved(items);\r\n        }\r\n\r\n        internal ShengImageListViewHitInfo HitTest(Point point)\r\n        {\r\n            int itemIndex = -1;\r\n\r\n            //这里对X，Y坐标的减，实现目的是平移坐标\r\n            //传进来的是相对控件左上角的坐标，应平移为Padding后的内框左上角相对坐标\r\n            //但是要考虑滚动时，上面的Padding也允许显示项\r\n            //X坐标直接向右平移即可\r\n            //Y坐标在没有滚动时，直接向下平移，如果存在滚动，当滚动值小于顶部Padding时\r\n            //将Y坐标平移至项的最层端Y坐标上，即：Padding-滚动值\r\n\r\n            //相对于Padding后的内框坐标系的坐标\r\n            Point relativePoint = point;\r\n\r\n            relativePoint.X -= ItemsBounds.Left;\r\n\r\n            //y即平移量\r\n            //此处y坐标需要在绘制项的区域（Padding后的区域）的基础上，考虑滚动条的offset\r\n            int y = ItemsArea.Top - _itemsAreaOffset;\r\n            if (y < 0) y = 0;\r\n            relativePoint.Y -= y;\r\n\r\n            if (relativePoint.X > 0 && relativePoint.Y > 0)\r\n            {\r\n                //当前点击的行和列的索引，从0开始\r\n                int col = relativePoint.X / _itemSizeWithMargin.Width;\r\n                int row = (relativePoint.Y + _itemsBoundsOffset) / _itemSizeWithMargin.Height;\r\n\r\n                //判断点的是不是右边的空白，可能右边会有比较大的空白，又没大到够完整的显示一列图像\r\n                bool isNotHitRightEmptyArea = col <= _columnCount - 1;\r\n                if (isNotHitRightEmptyArea)\r\n                {\r\n                    int index = row * _columnCount + col;\r\n\r\n                    //判断是不是点在图像区域内，还是图像边上，四周的Margin上\r\n                    Rectangle bounds = GetItemBounds(index);\r\n                    //判断点的坐标是不是在项的显示区域（Bounds)内，要用相对整个控件的原始坐标\r\n                    //因为项的bounds是相对整个控件的\r\n                    bool isHitInItem = bounds.Contains(point.X, point.Y);\r\n\r\n                    if (isHitInItem)\r\n                    {\r\n                        itemIndex = index;\r\n                    }\r\n                }\r\n            }\r\n\r\n            //是否点击在了有效项上\r\n            bool itemHit = itemIndex >= 0 && itemIndex < _imageListView.Items.Count;\r\n\r\n            ShengImageListViewHitInfo hitInfo = new ShengImageListViewHitInfo(itemIndex, itemHit);\r\n            return hitInfo;\r\n        }\r\n\r\n        #endregion\r\n\r\n        #region 公开方法\r\n\r\n        public void Render(Graphics graphics)\r\n        {\r\n            //Debug.Write(\"Render(Graphics graphics)\" + Environment.NewLine);\r\n\r\n            Update();\r\n\r\n            _renderer.Render(graphics);\r\n        }\r\n\r\n        public void RenderItem(Graphics graphics, ShengImageListViewItem item)\r\n        {\r\n            Debug.Assert(MouseSelecting == false, \"MouseSelecting 为 \" + MouseSelecting.ToString());\r\n\r\n            _renderer.RenderItem(graphics, item);\r\n        }\r\n\r\n        /// <summary>\r\n        /// 更新整个布局引擎的状态\r\n        /// </summary>\r\n        public void Update()\r\n        {\r\n            //Debug.Write(\"Update()\" + Environment.NewLine);\r\n\r\n            CalculateGrid();\r\n\r\n            CalculateVisibleItemsRange();\r\n\r\n            UpdateScrollBars();\r\n        }\r\n\r\n        /// <summary>\r\n        /// 判断指定的项是否处于可见状态\r\n        /// </summary>\r\n        /// <param name=\"item\"></param>\r\n        /// <returns></returns>\r\n        public ShengImageListViewItemVisibility IsItemVisible(ShengImageListViewItem item)\r\n        {\r\n            int itemIndex = _imageListView.Items.IndexOf(item);\r\n\r\n            if (_imageListView.Items.Count == 0)\r\n                return ShengImageListViewItemVisibility.NotVisible;\r\n\r\n            if (itemIndex < 0 || itemIndex > _imageListView.Items.Count - 1)\r\n                return ShengImageListViewItemVisibility.NotVisible;\r\n\r\n            if (itemIndex < _firstPartiallyVisible || itemIndex > _lastPartiallyVisible)\r\n                return ShengImageListViewItemVisibility.NotVisible;\r\n            else if (itemIndex >= _firstVisible && itemIndex <= _lastVisible)\r\n                return ShengImageListViewItemVisibility.Visible;\r\n            else\r\n                return ShengImageListViewItemVisibility.PartiallyVisible;\r\n        }\r\n\r\n        /// <summary>\r\n        /// 获取项的呈现区域\r\n        /// </summary>\r\n        /// <param name=\"item\"></param>\r\n        /// <returns></returns>\r\n        public Rectangle GetItemBounds(ShengImageListViewItem item)\r\n        {\r\n            int index = _imageListView.Items.IndexOf(item);\r\n\r\n            return GetItemBounds(index);\r\n        }\r\n\r\n        public Rectangle GetItemBounds(int index)\r\n        {\r\n            Point location = ItemsArea.Location;\r\n\r\n            //测算滚动条向下滚动过的高度，做为初始 Y 坐标\r\n            location.Y += _margin / 2 - _itemsAreaOffset;\r\n\r\n            //itemIndex % _columnCount 得到项在第几列\r\n            //itemIndex / _columnCount 得到项在第几行\r\n            location.X += _margin / 2 + (index % _columnCount) * _itemSizeWithMargin.Width;\r\n\r\n            //在初始 Y 坐标的基础上，算出此项所在行，计算出其应该在的Y坐标\r\n            location.Y += (index / _columnCount) * _itemSizeWithMargin.Height;\r\n\r\n            return new Rectangle(location, _itemSize);\r\n        }\r\n\r\n        public List<ShengImageListViewItem> GetItems()\r\n        {\r\n            return _imageListView.Items.ToList();\r\n        }\r\n\r\n        /// <summary>\r\n        /// 获取当前所有可见项\r\n        /// </summary>\r\n        /// <returns></returns>\r\n        public List<ShengImageListViewItem> GetVisibleItems()\r\n        {\r\n            List<ShengImageListViewItem> items = new List<ShengImageListViewItem>();\r\n\r\n            for (int i = _firstPartiallyVisible; i <= _lastPartiallyVisible; i++)\r\n            {\r\n                items.Add(_imageListView.Items[i]);\r\n            }\r\n\r\n            return items;\r\n        }\r\n\r\n        #endregion\r\n\r\n        #region 事件响应方法\r\n\r\n        public void MouseDown(MouseEventArgs e)\r\n        {\r\n            /*\r\n             * 如果按下的是鼠标右键\r\n             * 如果按在已选定的项上，只切换焦点，不改变选择\r\n             * 如果按在未选定项上，则切换为点的项为选中项\r\n             * 不考虑键盘按键\r\n             */\r\n\r\n            _mouseItemsAreaOffset = _itemsAreaOffset;\r\n\r\n            List<ShengImageListViewItem> oldSelectedItems = _imageListView.GetSelectedItems();\r\n\r\n            ShengImageListViewHitInfo hitInfo = HitTest(e.Location);\r\n\r\n            if (hitInfo.ItemHit)\r\n            {\r\n                ShengImageListViewItem item = _imageListView.Items[hitInfo.ItemIndex];\r\n                List<ShengImageListViewItem> allItems = _imageListView.Items.ToList();\r\n                ShengImageListViewItem currentFocusedItem = _imageListView.FocusedItem;\r\n\r\n                if (_imageListView.LeftButton)\r\n                {\r\n                    #region 如果不允许多选\r\n                    if (_imageListView.AllowMultiSelection == false)\r\n                    {\r\n                        //如果点击的项就是当前选择的项\r\n                        if (oldSelectedItems.Count > 0 && oldSelectedItems.Contains(item))\r\n                        {\r\n                            //判断Control键是否按下，如果按下了Control键，取消当前项的选择状态\r\n                            if (_imageListView.ControlKey)\r\n                                item.Selected = false;\r\n                        }\r\n                        else\r\n                        {\r\n                            //如果点击的项不是当前选择的项\r\n                            //清除原选定项的选定状态\r\n                            _imageListView.ClearSelect();\r\n                            //设置新项为选定项\r\n                            item.Selected = true;\r\n                        }\r\n                    }\r\n                    #endregion\r\n                    #region 如果允许多选\r\n                    //在同时按下 Control 和 Shift 的情况下，优先考虑 Shift\r\n                    else\r\n                    {\r\n                        #region 如果按下 Shift\r\n                        //判断是否按下了 Shift ，如果按下 Shift，不考虑 Control 的状态\r\n                        //也不用考虑是否点击的项是否是现有选定项之一\r\n                        if (_imageListView.ShiftKey)\r\n                        {\r\n                            //如果当前存在具有输入焦点的项\r\n                            if (currentFocusedItem != null && currentFocusedItem != item)\r\n                            {\r\n                                //连续选中从当前具有焦点的项至点击的项之间的所有项\r\n                                //并将不在此范围内的项取消选中状态\r\n                                int startIndex = Math.Min(currentFocusedItem.Index, hitInfo.ItemIndex);\r\n                                int endIndex = Math.Max(currentFocusedItem.Index, hitInfo.ItemIndex);\r\n                                foreach (var i in from c in oldSelectedItems where c.Index < startIndex || c.Index > endIndex select c)\r\n                                {\r\n                                    i.Selected = false;\r\n                                }\r\n                                for (int i = startIndex; i <= endIndex; i++)\r\n                                {\r\n                                    ShengImageListViewItem eachItem = allItems[i];\r\n                                    if (eachItem.Selected == false)\r\n                                        eachItem.Selected = true;\r\n                                }\r\n                            }\r\n                            //如果当前不存在具有输入焦点的项\r\n                            else\r\n                            {\r\n                                //清除原选定项的选定状态\r\n                                _imageListView.ClearSelect();\r\n                                item.Selected = true;\r\n                            }\r\n                        }\r\n                        #endregion\r\n                        #region 如果 Shift键没有处于按下状态\r\n                        else\r\n                        {\r\n                            #region 如果点击的项 是 当前选择的项之一\r\n                            if (oldSelectedItems.Count > 0 && oldSelectedItems.Contains(item))\r\n                            {\r\n                                //判断是否按下了 Control，且没有按下 Shift\r\n                                if (_imageListView.ControlKey && _imageListView.ShiftKey == false)\r\n                                {\r\n                                    item.Selected = false;\r\n                                }\r\n\r\n                                //判断是否什么键都没有按下\r\n                                if (_imageListView.ControlKey == false && _imageListView.ShiftKey == false)\r\n                                {\r\n                                    //清除原选定项的选定状态\r\n                                    _imageListView.ClearSelect();\r\n                                    item.Selected = true;\r\n                                }\r\n                            }\r\n                            #endregion\r\n                            #region 如果点击的项 不是 当前选择的项之一\r\n                            else\r\n                            {\r\n                                //判断Control键是否按下，如果按下了Control键，则保持原有选择的情况把新项也设置为选中\r\n                                //否则清除当前选择\r\n                                if (_imageListView.ControlKey == false)\r\n                                {\r\n                                    //清除原选定项的选定状态\r\n                                    _imageListView.ClearSelect();\r\n                                }\r\n                                item.Selected = true;\r\n                            }\r\n                            #endregion\r\n                        }\r\n                        #endregion\r\n                    }\r\n                    #endregion\r\n                }\r\n                else\r\n                {\r\n                    //如果点在未选中的项上\r\n                    if (oldSelectedItems.Contains(item) == false)\r\n                    {\r\n                        _imageListView.ClearSelect();\r\n                        //设置新项为选定项\r\n                        item.Selected = true;\r\n                    }\r\n                }\r\n\r\n                #region 为项设置输入焦点\r\n\r\n                //设置新的输入焦点要放在后面处理，因为在使用Shift连续选择时，需要用到原具有焦点的项\r\n                if (currentFocusedItem == null || (currentFocusedItem != null && currentFocusedItem != item))\r\n                {\r\n                    if (currentFocusedItem != null)\r\n                        currentFocusedItem.Focused = false;\r\n                    item.Focused = true;\r\n                }\r\n                #endregion\r\n            }\r\n            else\r\n            {\r\n                _imageListView.ClearSelect();\r\n            }\r\n\r\n            List<ShengImageListViewItem> newSelectedItems = _imageListView.GetSelectedItems();\r\n            if (oldSelectedItems.SequenceEqual(newSelectedItems) == false)\r\n            {\r\n                _imageListView.NeedPaint();\r\n                _imageListView.OnSelectedItemChanged();\r\n            }\r\n        }\r\n\r\n        public void MouseUp(MouseEventArgs e)\r\n        {\r\n            if (MouseSelecting)\r\n            {\r\n                MouseSelecting = false;\r\n                _scrollTimer.Enabled = false;\r\n                _autoScrollValue = 0;\r\n                _imageListView.NeedPaint();\r\n            }\r\n        }\r\n\r\n        public void MouseMove(MouseEventArgs e)\r\n        {\r\n            Point lastMouseDownLocation = _imageListView.LastMouseDownLocation;\r\n\r\n            #region 如果处于框选状态\r\n            if (MouseSelecting)\r\n            {\r\n                //处于框选状态时，框内的项被选中不能在 MouseMove 事件中处理\r\n                //因为当鼠标移出控件，滚动条自动滚动时，不动鼠标，就不会触发 MouseMove 事件\r\n\r\n                #region 判断是否需要自动滚动滚动条\r\n\r\n                if (_scrollTimer.Enabled == false)\r\n                {\r\n                    //需向下滚动\r\n                    if (e.Y > ItemsBounds.Bottom)\r\n                    {\r\n                        _autoScrollValue = AUTOSCROLL_VALUE;\r\n                        _scrollTimer.Enabled = true;\r\n                    }\r\n                    //需向上滚动\r\n                    else if (e.Y < ItemsBounds.Top)\r\n                    {\r\n                        _autoScrollValue = -AUTOSCROLL_VALUE;\r\n                        _scrollTimer.Enabled = true;\r\n                    }\r\n                }\r\n                //鼠标从控件外面又回到了控件内，则停止自动滚动\r\n                else if (_scrollTimer.Enabled && ItemsBounds.Contains(e.Location))\r\n                {\r\n                    _scrollTimer.Enabled = false;\r\n                    _autoScrollValue = 0;\r\n                }\r\n\r\n                #endregion\r\n\r\n                //创建选择框 Rectangle\r\n                SelectionRectangle = CreateSelectionRectangle();\r\n                SelectItemsByRectangle(SelectionRectangle);\r\n\r\n                _imageListView.NeedPaint();\r\n            }\r\n            #endregion\r\n            #region 如果不是处于框选状态\r\n            else\r\n            {\r\n                //如果允许多选，鼠标处于按下状态，且距上次点击的点，大于了最小框选开始尺寸\r\n                if (_imageListView.AllowMultiSelection && _imageListView.AnyMouseButton && (\r\n                    (Math.Abs(e.Location.X - lastMouseDownLocation.X) > SELECTION_TOLERANCE ||\r\n                    Math.Abs(e.Location.Y - lastMouseDownLocation.Y) > SELECTION_TOLERANCE)))\r\n                {\r\n                    MouseSelecting = true;\r\n                }\r\n            }\r\n            #endregion\r\n        }\r\n\r\n        public void OnMouseWheel(MouseEventArgs e)\r\n        {\r\n            int offSet = _itemsAreaOffset;\r\n            int newYOffset = offSet - (e.Delta / SystemInformation.MouseWheelScrollDelta)\r\n                   * _vScrollBar.SmallChange;\r\n            if (newYOffset > _vScrollBar.Maximum - _vScrollBar.LargeChange + 1)\r\n                newYOffset = _vScrollBar.Maximum - _vScrollBar.LargeChange + 1;\r\n            if (newYOffset < 0)\r\n                newYOffset = 0;\r\n            if (newYOffset < _vScrollBar.Minimum) newYOffset = _vScrollBar.Minimum;\r\n            if (newYOffset > _vScrollBar.Maximum) newYOffset = _vScrollBar.Maximum;\r\n            _vScrollBar.Value = newYOffset;\r\n        }\r\n\r\n        public void OnKeyDown(KeyEventArgs e)\r\n        {\r\n\r\n            // If the shift key or the control key is pressed and there is no focused item\r\n            // set the first item as the focused item.\r\n            if ((ShiftKey || ControlKey) && _imageListView.Items.Count != 0 &&\r\n                _imageListView.FocusedItem == null)\r\n            {\r\n                _imageListView.Items[0].Focused = true;\r\n            }\r\n\r\n            ShengImageListViewItem currentFocusedItem = _imageListView.FocusedItem;\r\n\r\n            if (_imageListView.Items.Count != 0)\r\n            {\r\n                int index = 0;\r\n                if (currentFocusedItem != null)\r\n                    index = currentFocusedItem.Index;\r\n\r\n                int newindex = ApplyNavKey(index, e.KeyCode);\r\n                if (index != newindex)\r\n                {\r\n                    #region 根据新index做选择\r\n\r\n                    if (ControlKey)\r\n                    {\r\n                        // Just move the focus\r\n                    }\r\n                    else if (_imageListView.AllowMultiSelection && ShiftKey)\r\n                    {\r\n                        int startIndex = 0;\r\n                        int endIndex = 0;\r\n                        List<ShengImageListViewItem> selectedItems = _imageListView.GetSelectedItems();\r\n                        if (selectedItems.Count != 0)\r\n                        {\r\n                            startIndex = selectedItems[0].Index;\r\n                            endIndex = selectedItems[selectedItems.Count - 1].Index;\r\n                            _imageListView.ClearSelect();\r\n                        }\r\n                        if (index == startIndex)\r\n                            startIndex = newindex;\r\n                        else if (index == endIndex)\r\n                            endIndex = newindex;\r\n                        for (int i = Math.Min(startIndex, endIndex); i <= Math.Max(startIndex, endIndex); i++)\r\n                        {\r\n                            _imageListView.Items[i].Selected = true;\r\n                        }\r\n                    }\r\n                    else\r\n                    {\r\n                        _imageListView.ClearSelect();\r\n                        _imageListView.Items[newindex].Selected = true;\r\n                    }\r\n\r\n                    currentFocusedItem.Focused = false;\r\n                    _imageListView.Items[newindex].Focused = true;\r\n\r\n                    EnsureVisible(newindex);\r\n\r\n                    #endregion\r\n\r\n                    //触发事件\r\n                    _imageListView.OnSelectedItemChanged();\r\n                }\r\n            }\r\n\r\n            _imageListView.NeedPaint();\r\n        }\r\n\r\n        public void OnKeyUp(KeyEventArgs e)\r\n        {\r\n            //Refresh();\r\n        }\r\n\r\n        #endregion\r\n\r\n        #region 私有方法\r\n        \r\n        private void Refresh()\r\n        {\r\n            _imageListView.Refresh();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calculates the maximum number of rows and columns \r\n        /// that can be fully displayed.\r\n        /// </summary>\r\n        private void CalculateGrid()\r\n        {\r\n            Rectangle itemArea = this.ItemsArea;\r\n            _columnCount = (int)System.Math.Floor((float)itemArea.Width / (float)_itemSizeWithMargin.Width);\r\n            _rowCount = (int)System.Math.Floor((float)itemArea.Height / (float)_itemSizeWithMargin.Height);\r\n\r\n            if (_columnCount < 1) _columnCount = 1;\r\n            if (_rowCount < 1) _rowCount = 1;\r\n        }\r\n\r\n        /// <summary>\r\n        /// 计算当前可见项的index范围\r\n        /// </summary>\r\n        private void CalculateVisibleItemsRange()\r\n        {\r\n            Rectangle itemsArea = this.ItemsArea;\r\n\r\n            //这里必须把控件的内部Padding值考虑进来\r\n            //_visibleOffset 是相对于 ItemsArea 的，此处要得到相对于整个控件可视区域的 offSet\r\n            //因为显示的图片项即使超出了 ItemsArea ，但还是在可视区域内，还是完全可见的，在计算时需要考虑\r\n            //ItemsArea.Location.Y - ItemsBounds.Location.Y 实际上就是Padding\r\n            //但是这样写逻辑上好些，因为实际意义在于 ItemsArea 和 ItemsBounds 之间的区域也是可以显示内容的，在意义上与Padding无关\r\n\r\n            int offSet = _itemsAreaOffset - (ItemsArea.Location.Y - ItemsBounds.Location.Y);\r\n            if (offSet < 0)\r\n                offSet = 0;\r\n\r\n            int itemAreaHeight = ItemsBounds.Height;\r\n\r\n            _firstPartiallyVisible = (int)System.Math.Floor((float)offSet / (float)_itemSizeWithMargin.Height) * _columnCount;\r\n            _lastPartiallyVisible = (int)System.Math.Ceiling((float)(offSet + itemAreaHeight) / (float)_itemSizeWithMargin.Height) * _columnCount - 1;\r\n\r\n            if (_firstPartiallyVisible < 0) _firstPartiallyVisible = 0;\r\n            if (_firstPartiallyVisible > _imageListView.Items.Count - 1) _firstPartiallyVisible = _imageListView.Items.Count - 1;\r\n            if (_lastPartiallyVisible < 0) _lastPartiallyVisible = 0;\r\n            if (_lastPartiallyVisible > _imageListView.Items.Count - 1) _lastPartiallyVisible = _imageListView.Items.Count - 1;\r\n\r\n            _firstVisible = (int)System.Math.Ceiling((float)offSet / (float)_itemSizeWithMargin.Height) * _columnCount;\r\n            _lastVisible = (int)System.Math.Floor((float)(offSet + itemAreaHeight) / (float)_itemSizeWithMargin.Height) * _columnCount - 1;\r\n\r\n            if (_firstVisible < 0) _firstVisible = 0;\r\n            if (_firstVisible > _imageListView.Items.Count - 1) _firstVisible = _imageListView.Items.Count - 1;\r\n            if (_lastVisible < 0) _lastVisible = 0;\r\n            if (_lastVisible > _imageListView.Items.Count - 1) _lastVisible = _imageListView.Items.Count - 1;\r\n        }\r\n\r\n        /// <summary>\r\n        /// 更新滚动条状态\r\n        /// </summary>\r\n        private void UpdateScrollBars()\r\n        {\r\n            if (_imageListView.Items.Count > 0)\r\n            {\r\n                _vScrollBar.Minimum = 0;\r\n                _vScrollBar.Maximum = Math.Max(0,\r\n                    (int)Math.Ceiling(\r\n                    (float)_imageListView.Items.Count / (float)_columnCount) * _itemSizeWithMargin.Height - 1);\r\n                _vScrollBar.LargeChange = ItemsArea.Height;\r\n                _vScrollBar.SmallChange = _itemSizeWithMargin.Height;\r\n\r\n                bool vScrollRequired = (_imageListView.Items.Count > 0) &&\r\n                    (_columnCount * _rowCount < _imageListView.Items.Count);\r\n                _vScrollBar.Visible = vScrollRequired;\r\n\r\n                //此处重新计算滚动条的滚动值\r\n                //当滚动条出现，并滚动到底部时，改变控件的高度，就是向下拉大窗体\r\n                //已经绘制的项下面会开始出现空白，就是因为滚动条的值还是旧值，_itemsAreaOffset也没有变化\r\n                //除非用鼠标点一下滚动条，否则滚动条的 ValueChanged 事件也不会触发\r\n                //所以绘制出的项的起始Y轴是不对的，必须在此重新计算滚动条的Value值\r\n                if (_itemsAreaOffset > _vScrollBar.Maximum - _vScrollBar.LargeChange + 1)\r\n                {\r\n                    _vScrollBar.Value = _vScrollBar.Maximum - _vScrollBar.LargeChange + 1;\r\n                    _itemsAreaOffset = _vScrollBar.Value;\r\n                }\r\n            }\r\n            else\r\n            {\r\n                _vScrollBar.Visible = false;\r\n                _vScrollBar.Value = 0;\r\n                _vScrollBar.Minimum = 0;\r\n                _vScrollBar.Maximum = 0;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// 创建框选框\r\n        /// </summary>\r\n        /// <returns></returns>\r\n        private Rectangle CreateSelectionRectangle()\r\n        {\r\n            Point mousePoint = _imageListView.PointToClient(Cursor.Position);\r\n            Point lastMouseDownLocation = _imageListView.LastMouseDownLocation;\r\n\r\n            #region 说明\r\n            \r\n            //当框选的同时，滚动滚动条\r\n            //计算offset:\r\n            //由于可视区域和项的一般显示区域之间有个padding，而滚动条是以内部区域为标准的\r\n            //所以当滚动条开始滚动时，可能项还是全部显示在可视范围内的（padding区也可以显示）\r\n            //那么此时 _itemsBoundsOffset 还是 0，而按下鼠标时 _mouseDownOffset 记录的也是当时的 _itemsBoundsOffset\r\n            //那么在计算 SelectionRectangle 的 Y 坐标时，\r\n            //如果直接用 _itemsBoundsOffset 参与计算，就会产生一个和padding有关的误差\r\n            //如 lastMouseDownLocation.Y - (viewOffset - _mouseDownOffset) ，假如此时向下滚动了一点\r\n            //但所有的项还在可视范围内，那么 就会是 lastMouseDownLocation.Y - (0 - 0) \r\n            //SelectionRectangle 的 Y 坐标就差生了误差\r\n            //解决的办法是使用 _itemsAreaOffset（既滚动条的Value），使框框的Y坐标与滚动条同步滚动即可\r\n\r\n            #endregion\r\n\r\n            int viewOffset = _itemsAreaOffset;\r\n            Point pt1 = new Point(lastMouseDownLocation.X, lastMouseDownLocation.Y - (viewOffset - _mouseItemsAreaOffset));\r\n            Point pt2 = new Point(mousePoint.X, mousePoint.Y);\r\n            Rectangle rect = new Rectangle(Math.Min(pt1.X, pt2.X), Math.Min(pt1.Y, pt2.Y),\r\n                Math.Abs(pt1.X - pt2.X), Math.Abs(pt1.Y - pt2.Y));\r\n\r\n            return rect;\r\n        }\r\n\r\n        /// <summary>\r\n        /// 根据矩形区域选择项\r\n        /// </summary>\r\n        /// <param name=\"rect\"></param>\r\n        private void SelectItemsByRectangle(Rectangle rect)\r\n        {\r\n            int viewOffset = _itemsAreaOffset;\r\n\r\n            Point pt1 = new Point(SelectionRectangle.Left, SelectionRectangle.Top);\r\n            Point pt2 = new Point(SelectionRectangle.Right, SelectionRectangle.Bottom);\r\n\r\n            //- ItemsArea.Y 和 - ItemsArea.X\r\n            //是因为，选择框的是以整个控件可视区域为坐标系的，而绘制的项是在Padding区内的\r\n            //那么就需要修正或者说同步这个偏差，才能得到正确的行列\r\n            int startRow = (int)Math.Floor((float)(Math.Min(pt1.Y, pt2.Y) + viewOffset - ItemsArea.Y) /\r\n                  (float)this._itemSizeWithMargin.Height);\r\n            int endRow = (int)Math.Floor((float)(Math.Max(pt1.Y, pt2.Y) + viewOffset - ItemsArea.Y) /\r\n                (float)this._itemSizeWithMargin.Height);\r\n            int startCol = (int)Math.Floor((float)(Math.Min(pt1.X, pt2.X) - ItemsArea.X) /\r\n                (float)this._itemSizeWithMargin.Width);\r\n            int endCol = (int)Math.Floor((float)(Math.Max(pt1.X, pt2.X) - ItemsArea.X) /\r\n                (float)this._itemSizeWithMargin.Width);\r\n\r\n            //行不能这样判断，因为_rowCount表示的只是控件可视范围内的可视行数\r\n            //在框选时，框会跨越可视区域的，这里的endRow要的是实际的项所在行数\r\n            //列不存在这个问题，因为不支持水平滚动\r\n            //if (endRow >= _rowCount)\r\n            //    endRow = _rowCount -1;\r\n            if (endCol >= _columnCount)\r\n                endCol = _columnCount - 1;\r\n            if (startCol < 0)\r\n                startCol = 0;\r\n\r\n            //创建一个应该被选定的项的index数组\r\n            int itemsCount = _imageListView.Items.Count;\r\n            List<int> selectItemsIndex = new List<int>();\r\n            for (int i = startRow; i <= endRow; i++)\r\n            {\r\n                for (int j = startCol; j <= endCol; j++)\r\n                {\r\n                    int index = i * _columnCount + j;\r\n                    if (index >= 0 && index < itemsCount)\r\n                        selectItemsIndex.Add(index);\r\n                }\r\n            }\r\n\r\n            //如果当前没有按下Shift键，那么\r\n            //判断当前选定的项中有没有不在框选区内的，如果有将其取消选定\r\n            if (ShiftKey == false)\r\n            {\r\n                List<ShengImageListViewItem> currentSlectedItems = _imageListView.GetSelectedItems();\r\n                foreach (var item in currentSlectedItems)\r\n                {\r\n                    if (selectItemsIndex.Contains(item.Index) == false)\r\n                        item.Selected = false;\r\n                }\r\n            }\r\n\r\n            ShengImageListViewCollection allItems = _imageListView.Items;\r\n            //使框选区内的项都处于选中状态\r\n            foreach (var index in selectItemsIndex)\r\n            {\r\n                if (allItems[index].Selected == false)\r\n                    allItems[index].Selected = true;\r\n            }\r\n\r\n            //debug\r\n            StartRow = startRow;\r\n            EndRow = endRow;\r\n            StartCol = startCol;\r\n            EndCol = endCol;\r\n        }\r\n\r\n        /// <summary>\r\n        /// 应用导航键，如上下左右，返回应用导航键之后的项的坐标\r\n        /// </summary>\r\n        private int ApplyNavKey(int index, Keys key)\r\n        {\r\n            int itemsCount = _imageListView.Items.Count;\r\n\r\n            if (key == Keys.Up && index >= _columnCount)\r\n                index -= _columnCount;\r\n            else if (key == Keys.Down && index < itemsCount - _columnCount)\r\n                index += _columnCount;\r\n            else if (key == Keys.Left && index > 0)\r\n                index--;\r\n            else if (key == Keys.Right && index < itemsCount - 1)\r\n                index++;\r\n            else if (key == Keys.PageUp && index >= _columnCount * (_rowCount - 1))\r\n                index -= _columnCount * (_rowCount - 1);\r\n            else if (key == Keys.PageDown && index < itemsCount - _columnCount * (_rowCount - 1))\r\n                index += _columnCount * (_rowCount - 1);\r\n            else if (key == Keys.Home)\r\n                index = 0;\r\n            else if (key == Keys.End)\r\n                index = itemsCount - 1;\r\n\r\n            if (index < 0)\r\n                index = 0;\r\n            else if (index > itemsCount - 1)\r\n                index = itemsCount - 1;\r\n\r\n            return index;\r\n        }\r\n\r\n        /// <summary>\r\n        /// 使指定下标的项处于可见状态\r\n        /// </summary>\r\n        /// <param name=\"itemIndex\"></param>\r\n        public void EnsureVisible(int itemIndex)\r\n        {\r\n            int itemCount = _imageListView.Items.Count;\r\n            if (itemCount == 0) return;\r\n            if (itemIndex < 0 || itemIndex >= itemCount) return;\r\n\r\n            // Already visible?\r\n            Rectangle bounds = this.ItemsBounds;\r\n            Rectangle itemBounds = GetItemBounds(itemIndex);\r\n\r\n            if (bounds.Contains(itemBounds) == false)\r\n            {\r\n                int delta = 0;\r\n                if (itemBounds.Top < bounds.Top)\r\n                    delta = bounds.Top - itemBounds.Top;\r\n                else\r\n                {\r\n                    int topItemIndex = itemIndex - (_rowCount - 1) * _columnCount;\r\n                    if (topItemIndex < 0) topItemIndex = 0;\r\n                    delta = bounds.Top - GetItemBounds(topItemIndex).Top;\r\n                }\r\n                int newYOffset = this._itemsBoundsOffset - delta;\r\n                if (newYOffset > _vScrollBar.Maximum - _vScrollBar.LargeChange + 1)\r\n                    newYOffset = _vScrollBar.Maximum - _vScrollBar.LargeChange + 1;\r\n                if (newYOffset < _vScrollBar.Minimum)\r\n                    newYOffset = _vScrollBar.Minimum;\r\n                //mViewOffset.X = 0;\r\n                //mViewOffset.Y = newYOffset;\r\n                //hScrollBar.Value = 0;\r\n                _vScrollBar.Value = newYOffset;\r\n            }\r\n        }\r\n\r\n        #endregion\r\n    }\r\n}\r\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengImageListView/ShengImageListViewRenderer.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Drawing;\nusing System.Drawing.Drawing2D;\nusing System.Windows.Forms;\nusing Sheng.Winform.Controls.Drawing;\n\nnamespace Sheng.Winform.Controls\n{\n    /// <summary>\n    /// 默认渲染器，不绘制项的实际内容，但是绘制DEBUG信息\n    /// </summary>\n    public class ShengImageListViewRenderer\n    {\n        #region 受保护的成员\n\n        private bool _disposed = false;\n        protected bool Disposed\n        {\n            get { return _disposed; }\n        }\n\n        private int _radius = 2;\n        protected int Radius\n        {\n            get { return _radius; }\n        }\r\n\r\n        #endregion\n\r\n        #region 公开属性\n\r\n        private ShengImageListViewTheme _theme = new ShengImageListViewTheme();\n        internal ShengImageListViewTheme Theme\r\n        {\r\n            get { return _theme; }\r\n            set { _theme = value; }\r\n        }\n\n        protected ShengImageListViewLayoutManager _layoutManager;\n        internal ShengImageListViewLayoutManager LayoutManager { get { return _layoutManager; } }\n\n        #region 构造\n\n        public ShengImageListViewRenderer(ShengImageListViewLayoutManager layoutManager)\n        {\n            _layoutManager = layoutManager;\n        }\n\n        #endregion\n\n        #endregion\n\n        #region 公开方法\n\n        public void Render(Graphics graphics)\n        {\n            if (LayoutManager.Suspend)\n                return;\n\n            if (_disposed) return;\n\n            RenderBackground(graphics);\n\n            RenderItems(graphics);\n\n            RenderSelectionRectangle(graphics);\n\n            DrawForeground(graphics);\n        }\n\n        public void RenderItem(Graphics g, ShengImageListViewItem item)\n        {\n            if (LayoutManager.Suspend)\n                return;\n\n            if (LayoutManager.IsItemVisible(item) == ShengImageListViewItemVisibility.NotVisible)\n                return;\n\n            DrawItem(g, item);\n        }\n\n        #endregion\n\n        #region 受保护方法\n\n        /// <summary>\n        /// 用于子类重写时删除相应的缓存\n        /// </summary>\n        /// <param name=\"items\"></param>\n        internal virtual void OnItemsRemoved(List<ShengImageListViewItem> items)\n        {\n\n        }\n\n        //不要直接调用这些Draw方法，internal的目的只是为了子类能够重写\n\n        /// <summary>\n        /// 绘制项的背景\n        /// </summary>\n        /// <param name=\"g\">The System.Drawing.Graphics to draw on.</param>\n        /// <param name=\"bounds\">The client coordinates of the item area.</param>\n        internal virtual void DrawBackground(Graphics g, Rectangle bounds)\n        {\n            // Clear the background\n            g.Clear(Theme.BackColor);\n        }\n\n        /// <summary>\n        /// 绘制最终的前景\n        /// </summary>\n        /// <param name=\"g\"></param>\n        /// <param name=\"bounds\"></param>\n        internal virtual void DrawForeground(Graphics g)\n        {\n            //输出debug信息\n            g.SetClip(LayoutManager.ClientArea);\n            g.DrawRectangle(Pens.Green, LayoutManager.ItemsArea);\n\n            Color brushColor = Color.FromArgb(150, Color.Black);\n            using (SolidBrush brush = new SolidBrush(brushColor))\n            {\n                g.FillRectangle(brush, new Rectangle(0, 0, 500, 50));\n            }\n            string debugInfo = \"ShiftKey:\" + LayoutManager.ShiftKey.ToString() +\n                \",ControlKey:\" + LayoutManager.ControlKey.ToString() + Environment.NewLine;\n            debugInfo += \"SelectionRectangle:\" + LayoutManager.SelectionRectangle.ToString() + Environment.NewLine;\n            debugInfo += \"StartRow:\" + LayoutManager.StartRow + \"，EndRow:\" + LayoutManager.EndRow + \"，StartCol:\" + LayoutManager.StartCol + \"，EndCol:\" + LayoutManager.EndCol;\n\n            g.DrawString(debugInfo, SystemFonts.DefaultFont, Brushes.White, LayoutManager.ClientArea);\n        }\n\n        /// <summary>\n        /// 绘制选择边框\n        /// </summary>\n        /// <param name=\"g\">The System.Drawing.Graphics to draw on.</param>\n        /// <param name=\"selection\">The client coordinates of the selection rectangle.</param>\n        internal virtual void DrawSelectionRectangle(Graphics g, Rectangle selection)\n        {\n            if (LayoutManager.Suspend)\n                return;\n\n            using (SolidBrush brush = new SolidBrush(Theme.SelectionRectangleColor))\n            using (Pen pen = new Pen(Theme.SelectionRectangleBorderColor))\n            {\n                g.FillRectangle(brush, selection);\n                g.DrawRectangle(pen, selection);\n            }\n        }\n\n        /// <summary>\n        /// 绘制项的边框\n        /// </summary>\n        /// <param name=\"g\"></param>\n        /// <param name=\"bounds\"></param>\n        internal virtual void DrawItemBorder(Graphics g, Rectangle bounds)\n        {\n            Rectangle backgroundRect = bounds;\n            backgroundRect.Width -= 1;\n            backgroundRect.Height -= 1;\n\n            using (Pen pWhite128 = new Pen(Color.FromArgb(128, Theme.ItemBorderColor)))\n            {\n                // ImageListViewUtility.DrawRoundedRectangle(g, pWhite128, bounds.Left, bounds.Top , bounds.Width - 1, bounds.Height - 1, _radius);\n                g.DrawPath(pWhite128, DrawingTool.RoundedRect(backgroundRect, _radius));\n            }\n        }\n\n        /// <summary>\n        /// 绘制项\n        /// </summary>\n        /// <param name=\"g\"></param>\n        /// <param name=\"item\"></param>\n        /// <param name=\"state\"></param>\n        /// <param name=\"bounds\"></param>\n        internal virtual void DrawItem(Graphics g, ShengImageListViewItem item)\n        {\n            Rectangle bounds = LayoutManager.GetItemBounds(item);\n            g.SetClip(bounds);\n\n            DrawItemBackground(g, bounds);\n\n            Rectangle backgroundRect = bounds;\n            backgroundRect.Width -= 1;\n            backgroundRect.Height -= 1;\n\n            // Paint background Selected\n            if ((LayoutManager.Focused && ((item.State & ShengImageListViewItemState.Selected) == ShengImageListViewItemState.Selected)) ||\n                (LayoutManager.Focused == false && ((item.State & ShengImageListViewItemState.Selected) == ShengImageListViewItemState.Selected) && ((item.State & ShengImageListViewItemState.Hovered) == ShengImageListViewItemState.Hovered)))\n            {\n                using (Brush bSelected = new LinearGradientBrush(backgroundRect, Theme.SelectedColorStart, Theme.SelectedColorEnd, LinearGradientMode.Vertical))\n                {\n                 //   ImageListViewUtility.FillRoundedRectangle(g, bSelected, bounds, 4);\n                    g.FillPath(bSelected, DrawingTool.RoundedRect(backgroundRect, _radius));\n                }\n            }\n            // Paint background unfocused\n            else if (LayoutManager.Focused == false && ((item.State & ShengImageListViewItemState.Selected) == ShengImageListViewItemState.Selected))\n            {\n                using (Brush bGray64 = new LinearGradientBrush(backgroundRect, Theme.UnFocusedColorStart, Theme.UnFocusedColorEnd, LinearGradientMode.Vertical))\n                {\n                   // ImageListViewUtility.FillRoundedRectangle(g, bGray64, bounds, 4);\n                    g.FillPath(bGray64, DrawingTool.RoundedRect(backgroundRect, _radius));\n                }\n            }\n\n            // Paint background Hovered\n            //如果正处于框选状态，不绘制Hover状态，减小闪烁\n            if (LayoutManager.MouseSelecting == false && (item.State & ShengImageListViewItemState.Hovered) == ShengImageListViewItemState.Hovered)\n            {\n                using (Brush bHovered = new LinearGradientBrush(backgroundRect, Theme.HoverColorStart, Theme.HoverColorEnd, LinearGradientMode.Vertical))\n                {\n                  //  ImageListViewUtility.FillRoundedRectangle(g, bHovered, bounds, 4);\n                    g.FillPath(bHovered, DrawingTool.RoundedRect(backgroundRect, _radius));\n                }\n            }\n\n            DrawItemBorder(g, bounds);\n\n            // Focus rectangle\n            if (LayoutManager.Focused && ((item.State & ShengImageListViewItemState.Focused) == ShengImageListViewItemState.Focused))\n            {\n                ControlPaint.DrawFocusRectangle(g, bounds);\n            }\n\n            DrawItemContent(g, bounds, item);\n        }\n\n        /// <summary>\n        /// 绘制项的背景\n        /// </summary>\n        /// <param name=\"g\"></param>\n        /// <param name=\"bounds\"></param>\n        internal virtual void DrawItemBackground(Graphics g, Rectangle bounds)\n        {\n            // Paint background\n            using (Brush bItemBack = new SolidBrush(Theme.ItemBackColor))\n            {\n                g.FillRectangle(bItemBack, bounds);\n            }\n        }\n\n        /// <summary>\n        /// 绘制项的内容\n        /// </summary>\n        /// <param name=\"g\"></param>\n        /// <param name=\"bounds\"></param>\n        /// <param name=\"item\"></param>\n        internal virtual void DrawItemContent(Graphics g, Rectangle bounds, ShengImageListViewItem item)\n        {\n            //显示debug信息\n            string debugInfo = item.Index + Environment.NewLine +\n                bounds.ToString() + Environment.NewLine +\n                item.State.ToString();\n            g.DrawString(debugInfo, SystemFonts.DefaultFont, Brushes.Black, bounds);\n        }\n\n        #endregion\n\n        #region 私有方法\n\n        /// <summary>\n        /// 绘制背景\n        /// </summary>\n        /// <param name=\"g\"></param>\n        private void RenderBackground(Graphics g)\n        {\n            if (LayoutManager.Suspend)\n                return;\n\n            g.SetClip(LayoutManager.ClientArea);\n            DrawBackground(g, LayoutManager.ClientArea);\n        }\n\n        /// <summary>\n        /// 绘制当前所有可见项\n        /// </summary>\n        /// <param name=\"g\"></param>\n        private void RenderItems(Graphics g)\n        {\n            if (LayoutManager.Suspend)\n                return;\n\n            // Is the control empty?\n            if (LayoutManager.IsEmpty)\n                return;\n\n            // No items visible?\n            if (LayoutManager.NoneItemVisible)\n                return;\n\n            List<ShengImageListViewItem> items = LayoutManager.GetVisibleItems();\n            foreach (ShengImageListViewItem item in items)\n            {\n                RenderItem(g, item);\n            }\n        }\n\n        /// <summary>\n        /// Renders the selection rectangle.\n        /// </summary>\n        /// <param name=\"g\">The graphics to draw on.</param>\n        private void RenderSelectionRectangle(Graphics g)\n        {\n            if (LayoutManager.Suspend)\n                return;\n\n            if (LayoutManager.MouseSelecting == false)\n                return;\n\n            Rectangle sel = LayoutManager.SelectionRectangle;\n            if (sel.Height > 0 && sel.Width > 0)\n            {\n                g.SetClip(LayoutManager.ClientArea);\n                    \n                DrawSelectionRectangle(g, sel);\n            }\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengImageListView/ShengImageListViewStandardRenderer.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Drawing;\nusing Sheng.Winform.Controls.Drawing;\n\nnamespace Sheng.Winform.Controls\n{\n    public class ShengImageListViewStandardRenderer : ShengImageListViewRenderer\n    {\n        #region 私有成员\n\n        /// <summary>\n        /// 缩略图的尺寸是否已初始化\n        /// 缩略图的尺寸受文本字体的大小的影响，所以要在第一次绘制时，测量文本的高度之后初始化\n        /// </summary>\n        bool _thumbnailSizeInited = false;\n        int _headerHeight;\n        Size _itemPadding = new Size(4, 4);\n        Size _thumbnailSize;\n        Rectangle _headerBounds;\n        StringFormat _itemHeaderStringFormat = new StringFormat();\n\n        ShengImageListViewItemThumbnailsCache _thumbnailsCache = new ShengImageListViewItemThumbnailsCache();\n\n        #endregion\n\n        #region 构造\n\n        public ShengImageListViewStandardRenderer(ShengImageListViewLayoutManager layoutManager)\n            : base(layoutManager)\n        {\n            _itemHeaderStringFormat.Alignment = StringAlignment.Center;\n            _itemHeaderStringFormat.FormatFlags = StringFormatFlags.LineLimit| StringFormatFlags.NoWrap;\n        }\n\n        #endregion\n\n        #region 受保护的方法\n\n        internal override void OnItemsRemoved(List<ShengImageListViewItem> items)\n        {\n            foreach (var item in items)\n            {\n                _thumbnailsCache.RemoveThumbnail(item);\n            }\n\n            base.OnItemsRemoved(items);\n        }\n\n        internal override void DrawForeground(Graphics g)\n        {\n\n        }\n\n        internal override void DrawItemContent(Graphics g, Rectangle bounds, ShengImageListViewItem item)\n        {\n            if (_thumbnailSizeInited == false)\n            {\n                SizeF headerSize = g.MeasureString(item.Header, Theme.ItemHeaderFont);\n                _headerHeight = (int)Math.Ceiling(headerSize.Height);\n\n                int width = LayoutManager.ItemSize.Width - _itemPadding.Width * 2;\n                //_itemPadding.Height * 3 是因为去掉缩略图顶部，底部，和与文本区域之间的Padding\n                int height = LayoutManager.ItemSize.Height - _itemPadding.Height * 3 - _headerHeight;\n                _thumbnailSize = new Size(width, height);\n\n                _thumbnailSizeInited = true;\n            }\n\n            #region  绘制缩略图\n\n            Image img = null;\n            if (_thumbnailsCache.Container(item))\n            {\n                img = _thumbnailsCache.GetThumbnail(item);\n            }\n            else\n            {\n                img = DrawingTool.GetScaleImage(item.Image, _thumbnailSize);\n                _thumbnailsCache.AddThumbnail(item, img);\n            }\n\n            if (img != null)\n            {\n                Rectangle pos = DrawingTool.GetSizedImageBounds(img, new Rectangle(bounds.Location + _itemPadding, _thumbnailSize));\n                g.DrawImage(img, pos);\n                // Draw image border\n                if (Math.Min(pos.Width, pos.Height) > 32)\n                {\n                    using (Pen pOuterBorder = new Pen(Theme.ImageOuterBorderColor))\n                    {\n                        g.DrawRectangle(pOuterBorder, pos);\n                    }\n                    if (System.Math.Min(_thumbnailSize.Width, _thumbnailSize.Height) > 32)\n                    {\n                        using (Pen pInnerBorder = new Pen(Theme.ImageInnerBorderColor))\n                        {\n                            //Rectangle.Inflate(pos, -1, -1) 用于取内框\n                            g.DrawRectangle(pInnerBorder, Rectangle.Inflate(pos, -1, -1));\n                        }\n                    }\n                }\n            }\n\n            #endregion\n\n            #region 绘制文本\n\n            _headerBounds = new Rectangle();\n            _headerBounds.X = _itemPadding.Width;\n            _headerBounds.Y = LayoutManager.ItemSize.Height - _headerHeight - _itemPadding.Height;\n            _headerBounds.Width = _thumbnailSize.Width;\n            _headerBounds.Height = _headerHeight;\n            _headerBounds.Offset(bounds.Location);\n\n            //g.DrawRectangle(Pens.Gray, _headerBounds);\n            using (SolidBrush brush = new SolidBrush(Theme.ItemHeaderColor))\n            {\n                g.DrawString(item.Header, Theme.ItemHeaderFont, brush, _headerBounds, _itemHeaderStringFormat);\n            }\n\n            #endregion\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengImageListView/ShengImageListViewTheme.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.ComponentModel;\nusing System.Drawing;\n\nnamespace Sheng.Winform.Controls\n{\n    public class ShengImageListViewTheme\n    {\n        #region 公开属性\n\n        private Font _itemHeaderFont = SystemFonts.DefaultFont;\n        public Font ItemHeaderFont\n        {\n            get { return _itemHeaderFont; }\n            set { _itemHeaderFont = value; }\n        }\n\n        private Color _itemHeaderColor = SystemColors.WindowText;\n        public Color ItemHeaderColor\n        {\n            get { return _itemHeaderColor; }\n            set { _itemHeaderColor = value; }\n        }\n\n        private Color _itemBackColor = SystemColors.Window;\n        /// <summary>\n        /// 项的背景色\n        /// </summary>\n        public Color ItemBackColor\n        {\n            get { return _itemBackColor; }\n            set { _itemBackColor = value; }\n        }\n\n        private Color _backColor = SystemColors.Window;\n        /// <summary>\n        /// 控件背景色\n        /// </summary>\n        public Color BackColor\n        {\n            get { return _backColor; }\n            set { _backColor = value; }\n        }\n\n        private Color _itemBorderColor = Color.FromArgb(64, SystemColors.GrayText);\n        /// <summary>\n        /// 项的边框色\n        /// </summary>\n        public Color ItemBorderColor\n        {\n            get { return _itemBorderColor; }\n            set { _itemBorderColor = value; }\n        }\n\n        private Color _selectionRectangleColor = Color.FromArgb(128, SystemColors.Highlight);\n        /// <summary>\n        /// 选择框颜色\n        /// </summary>\n        public Color SelectionRectangleColor\n        {\n            get { return _selectionRectangleColor; }\n            set { _selectionRectangleColor = value; }\n        }\n\n        private Color _selectionRectangleBorderColor = SystemColors.Highlight;\n        /// <summary>\n        /// 选择框的边框色\n        /// </summary>\n        public Color SelectionRectangleBorderColor\n        {\n            get { return _selectionRectangleBorderColor; }\n            set { _selectionRectangleBorderColor = value; }\n        }\n\n        private Color _selectedColorStart = Color.FromArgb(16, SystemColors.Highlight);\n        /// <summary>\n        /// 当控件具有焦点时选定项的背景色\n        /// </summary>\n        public Color SelectedColorStart\n        {\n            get { return _selectedColorStart; }\n            set { _selectedColorStart = value; }\n        }\n\n        private Color _selectedColorEnd = Color.FromArgb(128, SystemColors.Highlight);\n        public Color SelectedColorEnd\n        {\n            get { return _selectedColorEnd; }\n            set { _selectedColorEnd = value; }\n        }\n\n        private Color _unFocusedColorStart = Color.FromArgb(16, SystemColors.GrayText);\n        /// <summary>\n        /// 控件失去焦点时选定项的背景色\n        /// </summary>\n        public Color UnFocusedColorStart\n        {\n            get { return _unFocusedColorStart; }\n            set { _unFocusedColorStart = value; }\n        }\n\n        private Color _unFocusedColorEnd = Color.FromArgb(64, SystemColors.GrayText);\n        public Color UnFocusedColorEnd\n        {\n            get { return _unFocusedColorEnd; }\n            set { _unFocusedColorEnd = value; }\n        }\n\n        private Color _hoverColorStart = Color.FromArgb(8, SystemColors.Highlight);\n        /// <summary>\n        /// 热点项的背景色\n        /// </summary>\n        public Color HoverColorStart\n        {\n            get { return _hoverColorStart; }\n            set { _hoverColorStart = value; }\n        }\n\n        private Color _hoverColorEnd = Color.FromArgb(64, SystemColors.Highlight);\n        public Color HoverColorEnd\n        {\n            get { return _hoverColorEnd; }\n            set { _hoverColorEnd = value; }\n        }\n\n        private Color _imageInnerBorderColor = Color.FromArgb(128, Color.White);\n        /// <summary>\n        /// 图像内边框颜色\n        /// </summary>\n        public Color ImageInnerBorderColor\n        {\n            get { return _imageInnerBorderColor; }\n            set { _imageInnerBorderColor = value; }\n        }\n\n        private Color _imageOuterBorderColor = Color.FromArgb(128, Color.Gray);\n        /// <summary>\n        /// 图像外边框颜色\n        /// </summary>\n        public Color ImageOuterBorderColor\n        {\n            get { return _imageOuterBorderColor; }\n            set { _imageOuterBorderColor = value; }\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengImageListView/Utility.cs",
    "content": "﻿using System;\nusing System.Drawing;\nusing System.IO;\nusing System.Drawing.Drawing2D;\nusing System.Text;\n\nnamespace Sheng.SailingEase.Controls\n{\n    /// <summary>\n    /// Contains utility functions.\n    /// </summary>\n    public static class ImageListViewUtility\n    {\n        #region Text Utilities\n        /// <summary>\n        /// Formats the given file size as a human readable string.\n        /// </summary>\n        /// <param name=\"size\">File size in bytes.</param>\n        public static string FormatSize(long size)\n        {\n            double mod = 1024;\n            double sized = size;\n\n            // string[] units = new string[] { \"B\", \"KiB\", \"MiB\", \"GiB\", \"TiB\", \"PiB\" };\n            string[] units = new string[] { \"B\", \"KB\", \"MB\", \"GB\", \"TB\", \"PB\" };\n            int i;\n            for (i = 0; sized > mod; i++)\n            {\n                sized /= mod;\n            }\n\n            return string.Format(\"{0} {1}\", Math.Round(sized, 2), units[i]);\n        }\n        #endregion\n\n        #region Graphics Utilities\n        /// <summary>\n        /// Checks the stream header if it matches with\n        /// any of the supported image file types.\n        /// </summary>\n        /// <param name=\"stream\">An open stream pointing to an image file.</param>\n        /// <returns>true if the stream is an image file (BMP, TIFF, PNG, GIF, JPEG, WMF, EMF, ICO, CUR);\n        /// false otherwise.</returns>\n        internal static bool IsImage(Stream stream)\n        {\n            // Sniff some bytes from the start of the stream\n            // and check against magic numbers of supported \n            // image file formats\n            byte[] header = new byte[8];\n            stream.Seek(0, SeekOrigin.Begin);\n            if (stream.Read(header, 0, header.Length) != header.Length)\n                return false;\n\n            // BMP\n            string bmpHeader = Encoding.ASCII.GetString(header, 0, 2);\n            if (bmpHeader == \"BM\") // BM - Windows bitmap\n                return true;\n            else if (bmpHeader == \"BA\") // BA - Bitmap array\n                return true;\n            else if (bmpHeader == \"CI\") // CI - Color Icon\n                return true;\n            else if (bmpHeader == \"CP\") // CP - Color Pointer\n                return true;\n            else if (bmpHeader == \"IC\") // IC - Icon\n                return true;\n            else if (bmpHeader == \"PT\") // PI - Pointer\n                return true;\n\n            // TIFF\n            string tiffHeader = Encoding.ASCII.GetString(header, 0, 4);\n            if (tiffHeader == \"MM\\x00\\x2a\") // Big-endian\n                return true;\n            else if (tiffHeader == \"II\\x2a\\x00\") // Little-endian\n                return true;\n\n            // PNG\n            if (header[0] == 0x89 && header[1] == 0x50 && header[2] == 0x4E && header[3] == 0x47 &&\n                header[4] == 0x0D && header[5] == 0x0A && header[6] == 0x1A && header[7] == 0x0A)\n                return true;\n\n            // GIF\n            string gifHeader = Encoding.ASCII.GetString(header, 0, 4);\n            if (gifHeader == \"GIF8\")\n                return true;\n\n            // JPEG\n            if (header[0] == 0xFF && header[1] == 0xD8)\n                return true;\n\n            // WMF\n            if (header[0] == 0xD7 && header[1] == 0xCD && header[2] == 0xC6 && header[3] == 0x9A)\n                return true;\n\n            // EMF\n            if (header[0] == 0x01 && header[1] == 0x00 && header[2] == 0x00 && header[3] == 0x00)\n                return true;\n\n            // Windows Icons\n            if (header[0] == 0x00 && header[1] == 0x00 && header[2] == 0x01 && header[3] == 0x00) // ICO\n                return true;\n            else if (header[0] == 0x00 && header[1] == 0x00 && header[2] == 0x02 && header[3] == 0x00) // CUR\n                return true;\n\n            return false;\n        }\n        /// <summary>\n        /// Draws the given caption and text inside the given rectangle.\n        /// </summary>\n        internal static int DrawStringPair(Graphics g, Rectangle r, string caption, string text, Font font, Brush captionBrush, Brush textBrush)\n        {\n            using (StringFormat sf = new StringFormat())\n            {\n                sf.Alignment = StringAlignment.Near;\n                sf.LineAlignment = StringAlignment.Near;\n                sf.Trimming = StringTrimming.EllipsisCharacter;\n                sf.FormatFlags = StringFormatFlags.NoWrap;\n\n                SizeF szc = g.MeasureString(caption, font, r.Size, sf);\n                int y = (int)szc.Height;\n                if (szc.Width > r.Width) szc.Width = r.Width;\n                Rectangle txrect = new Rectangle(r.Location, Size.Ceiling(szc));\n                g.DrawString(caption, font, captionBrush, txrect, sf);\n                txrect.X += txrect.Width;\n                txrect.Width = r.Width;\n                if (txrect.X < r.Right)\n                {\n                    SizeF szt = g.MeasureString(text, font, r.Size, sf);\n                    y = Math.Max(y, (int)szt.Height);\n                    txrect = Rectangle.Intersect(r, txrect);\n                    g.DrawString(text, font, textBrush, txrect, sf);\n                }\n\n                return y;\n            }\n        }\n        /// <summary>\n        /// Gets the scaled size of an image required to fit\n        /// in to the given size keeping the image aspect ratio.\n        /// </summary>\n        /// <param name=\"image\">The source image.</param>\n        /// <param name=\"fit\">The size to fit in to.</param>\n        /// <returns>New image size.</returns>\n        internal static Size GetSizedImageBounds(Image image, Size fit)\n        {\n            float f = System.Math.Max((float)image.Width / (float)fit.Width, (float)image.Height / (float)fit.Height);\n            if (f < 1.0f) f = 1.0f; // Do not upsize small images\n            int width = (int)System.Math.Round((float)image.Width / f);\n            int height = (int)System.Math.Round((float)image.Height / f);\n            return new Size(width, height);\n        }\n        /// <summary>\n        /// Gets the bounding rectangle of an image required to fit\n        /// in to the given rectangle keeping the image aspect ratio.\n        /// </summary>\n        /// <param name=\"image\">The source image.</param>\n        /// <param name=\"fit\">The rectangle to fit in to.</param>\n        /// <param name=\"hAlign\">Horizontal image aligment in percent.</param>\n        /// <param name=\"vAlign\">Vertical image aligment in percent.</param>\n        /// <returns>New image size.</returns>\n        public static Rectangle GetSizedImageBounds(Image image, Rectangle fit, float hAlign, float vAlign)\n        {\n            if (hAlign < 0 || hAlign > 100.0f)\n                throw new ArgumentException(\"hAlign must be between 0.0 and 100.0 (inclusive).\", \"hAlign\");\n            if (vAlign < 0 || vAlign > 100.0f)\n                throw new ArgumentException(\"vAlign must be between 0.0 and 100.0 (inclusive).\", \"vAlign\");\n            Size scaled = GetSizedImageBounds(image, fit.Size);\n            int x = fit.Left + (int)(hAlign / 100.0f * (float)(fit.Width - scaled.Width));\n            int y = fit.Top + (int)(vAlign / 100.0f * (float)(fit.Height - scaled.Height));\n\n            return new Rectangle(x, y, scaled.Width, scaled.Height);\n        }\n        /// <summary>\n        /// Gets the bounding rectangle of an image required to fit\n        /// in to the given rectangle keeping the image aspect ratio.\n        /// The image will be centered in the fit box.\n        /// </summary>\n        /// <param name=\"image\">The source image.</param>\n        /// <param name=\"fit\">The rectangle to fit in to.</param>\n        /// <returns>New image size.</returns>\n        public static Rectangle GetSizedImageBounds(Image image, Rectangle fit)\n        {\n            return GetSizedImageBounds(image, fit, 50.0f, 50.0f);\n        }\n        /// <summary>\n        /// Gets a path representing a rounded rectangle.\n        /// </summary>\n        private static GraphicsPath GetRoundedRectanglePath(int x, int y, int width, int height, int radius)\n        {\n            GraphicsPath path = new GraphicsPath();\n            path.AddLine(x + radius, y, x + width - radius, y);\n            if (radius > 0)\n                path.AddArc(x + width - 2 * radius, y, 2 * radius, 2 * radius, 270.0f, 90.0f);\n            path.AddLine(x + width, y + radius, x + width, y + height - radius);\n            if (radius > 0)\n                path.AddArc(x + width - 2 * radius, y + height - 2 * radius, 2 * radius, 2 * radius, 0.0f, 90.0f);\n            path.AddLine(x + width - radius, y + height, x + radius, y + height);\n            if (radius > 0)\n                path.AddArc(x, y + height - 2 * radius, 2 * radius, 2 * radius, 90.0f, 90.0f);\n            path.AddLine(x, y + height - radius, x, y + radius);\n            if (radius > 0)\n                path.AddArc(x, y, 2 * radius, 2 * radius, 180.0f, 90.0f);\n            return path;\n        }\n        /// <summary>\n        /// Fills the interior of a rounded rectangle.\n        /// </summary>\n        public static void FillRoundedRectangle(System.Drawing.Graphics graphics, Brush brush, int x, int y, int width, int height, int radius)\n        {\n            using (GraphicsPath path = GetRoundedRectanglePath(x, y, width, height, radius))\n            {\n                graphics.FillPath(brush, path);\n            }\n        }\n        /// <summary>\n        /// Fills the interior of a rounded rectangle.\n        /// </summary>\n        public static void FillRoundedRectangle(System.Drawing.Graphics graphics, Brush brush, float x, float y, float width, float height, float radius)\n        {\n            FillRoundedRectangle(graphics, brush, (int)x, (int)y, (int)width, (int)height, (int)radius);\n        }\n        /// <summary>\n        /// Fills the interior of a rounded rectangle.\n        /// </summary>\n        public static void FillRoundedRectangle(System.Drawing.Graphics graphics, Brush brush, Rectangle rect, int radius)\n        {\n            FillRoundedRectangle(graphics, brush, rect.Left, rect.Top, rect.Width, rect.Height, radius);\n        }\n        /// <summary>\n        /// Fills the interior of a rounded rectangle.\n        /// </summary>\n        public static void FillRoundedRectangle(System.Drawing.Graphics graphics, Brush brush, RectangleF rect, float radius)\n        {\n            FillRoundedRectangle(graphics, brush, (int)rect.Left, (int)rect.Top, (int)rect.Width, (int)rect.Height, (int)radius);\n        }\n        /// <summary>\n        /// Draws the outline of a rounded rectangle.\n        /// </summary>\n        public static void DrawRoundedRectangle(System.Drawing.Graphics graphics, Pen pen, int x, int y, int width, int height, int radius)\n        {\n            using (GraphicsPath path = GetRoundedRectanglePath(x, y, width, height, radius))\n            {\n                graphics.DrawPath(pen, path);\n            }\n        }\n        /// <summary>\n        /// Draws the outline of a rounded rectangle.\n        /// </summary>\n        public static void DrawRoundedRectangle(System.Drawing.Graphics graphics, Pen pen, float x, float y, float width, float height, float radius)\n        {\n            DrawRoundedRectangle(graphics, pen, (int)x, (int)y, (int)width, (int)height, (int)radius);\n        }\n        /// <summary>\n        /// Draws the outline of a rounded rectangle.\n        /// </summary>\n        public static void DrawRoundedRectangle(System.Drawing.Graphics graphics, Pen pen, Rectangle rect, int radius)\n        {\n            DrawRoundedRectangle(graphics, pen, rect.Left, rect.Top, rect.Width, rect.Height, radius);\n        }\n        /// <summary>\n        /// Draws the outline of a rounded rectangle.\n        /// </summary>\n        public static void DrawRoundedRectangle(System.Drawing.Graphics graphics, Pen pen, RectangleF rect, float radius)\n        {\n            DrawRoundedRectangle(graphics, pen, (int)rect.Left, (int)rect.Top, (int)rect.Width, (int)rect.Height, (int)radius);\n        }\n        #endregion\n\n        #region Tuples\n        /// <summary>\n        /// Represents a factory class for creating tuples.\n        /// </summary>\n        public static class Tuple\n        {\n            /// <summary>\n            /// Creates a new 1-tuple.\n            /// </summary>\n            /// <typeparam name=\"T1\">The type of the only component of the tuple.</typeparam>\n            /// <param name=\"item1\">The value of the only component of the tuple.</param>\n            /// <returns>A 1-tuple whose value is (<paramref name=\"item1\"/>).</returns>\n            public static Tuple<T1> Create<T1>(T1 item1)\n            {\n                return new Tuple<T1>(item1);\n            }\n            /// <summary>\n            /// Creates a new 2-tuple.\n            /// </summary>\n            /// <typeparam name=\"T1\">The type of the first component of the tuple.</typeparam>\n            /// <typeparam name=\"T2\">The type of the second component of the tuple.</typeparam>\n            /// <param name=\"item1\">The value of the first component of the tuple.</param>\n            /// <param name=\"item2\">The value of the second component of the tuple.</param>\n            /// <returns>A 2-tuple whose value is (<paramref name=\"item1\"/>, <paramref name=\"item2\"/>).</returns>\n            public static Tuple<T1, T2> Create<T1, T2>(T1 item1, T2 item2)\n            {\n                return new Tuple<T1, T2>(item1, item2);\n            }\n            /// <summary>\n            /// Creates a new 3-tuple.\n            /// </summary>\n            /// <typeparam name=\"T1\">The type of the first component of the tuple.</typeparam>\n            /// <typeparam name=\"T2\">The type of the second component of the tuple.</typeparam>\n            /// <typeparam name=\"T3\">The type of the third component of the tuple.</typeparam>\n            /// <param name=\"item1\">The value of the first component of the tuple.</param>\n            /// <param name=\"item2\">The value of the second component of the tuple.</param>\n            /// <param name=\"item3\">The value of the third component of the tuple.</param>\n            /// <returns>A 3-tuple whose value is (<paramref name=\"item1\"/>, <paramref name=\"item2\"/>, <paramref name=\"item3\"/>).</returns>\n            public static Tuple<T1, T2, T3> Create<T1, T2, T3>(T1 item1, T2 item2, T3 item3)\n            {\n                return new Tuple<T1, T2, T3>(item1, item2, item3);\n            }\n        }\n        /// <summary>\n        /// Represents a tuple with one element.\n        /// </summary>\n        public class Tuple<T1>\n        {\n            private T1 mItem1;\n\n            /// <summary>\n            /// Gets the value of the first component.\n            /// </summary>\n            public T1 Item1 { get { return mItem1; } }\n\n            /// <summary>\n            /// Initializes a new instance of the <see cref=\"Tuple&lt;T1&gt;\"/> class.\n            /// </summary>\n            /// <param name=\"item1\">The value of the first component of the tuple.</param>\n            public Tuple(T1 item1)\n            {\n                mItem1 = item1;\n            }\n        }\n        /// <summary>\n        /// Represents a tuple with two elements.\n        /// </summary>\n        public class Tuple<T1, T2> : Tuple<T1>\n        {\n            private T2 mItem2;\n\n            /// <summary>\n            /// Gets the value of the second component.\n            /// </summary>\n            public T2 Item2 { get { return mItem2; } }\n\n            /// <summary>\n            /// Initializes a new instance of the <see cref=\"Tuple&lt;T1, T2&gt;\"/> class.\n            /// </summary>\n            /// <param name=\"item1\">The value of the first component of the tuple.</param>\n            /// <param name=\"item2\">The value of the second component of the tuple.</param>\n            public Tuple(T1 item1, T2 item2)\n                : base(item1)\n            {\n                mItem2 = item2;\n            }\n        }\n        /// <summary>\n        /// Represents a tuple with three elements.\n        /// </summary>\n        public class Tuple<T1, T2, T3> : Tuple<T1, T2>\n        {\n            private T3 mItem3;\n\n            /// <summary>\n            /// Gets the value of the third component.\n            /// </summary>\n            public T3 Item3 { get { return mItem3; } }\n\n            /// <summary>\n            /// Initializes a new instance of the <see cref=\"Tuple&lt;T1, T2, T3&gt;\"/> class.\n            /// </summary>\n            /// <param name=\"item1\">The value of the first component of the tuple.</param>\n            /// <param name=\"item2\">The value of the second component of the tuple.</param>\n            /// <param name=\"item3\">The value of the third component of the tuple.</param>\n            public Tuple(T1 item1, T2 item2, T3 item3)\n                : base(item1, item2)\n            {\n                mItem3 = item3;\n            }\n        }\n        #endregion\n\n        /// <summary>\n        /// 返回适应指定容器大小的图像\n        /// 在需要的情况下,此方法创建一个新对象,进行绘制\n        /// </summary>\n        /// <param name=\"image\"></param>\n        /// <param name=\"containerWidth\"></param>\n        /// <param name=\"containerHeight\"></param>\n        /// <returns></returns>\n        public static Image GetScaleImage(Image image, Size size)\n        {\n            if (image.Size.Width > size.Width ||\n                image.Size.Height > size.Height)\n            {\n                double width = size.Width;\n                double height = size.Height;\n\n                double new_width;\n                double new_height;\n                double scale;\n                new_height = height;\n                new_width = width;\n                if ((image.Width > width) || (image.Height > height))\n                {\n                    if (image.Width > width)\n                    {\n                        scale = image.Width / width;\n                        new_width = image.Width / scale;\n                        new_height = image.Height / scale;\n                    }\n                    else\n                    {\n                        scale = image.Height / height;\n                        new_width = image.Width / scale;\n                        new_height = image.Height / scale;\n                    }\n                }\n\n                Bitmap bitmap = new Bitmap(Convert.ToInt32(new_width), Convert.ToInt32(new_height));\n\n                Graphics g = Graphics.FromImage(bitmap);\n\n                g.DrawImage(image, 0, 0, bitmap.Width, bitmap.Height);\n\n                return bitmap;\n            }\n            else\n            {\n                return image;\n            }\n        }\n\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengLine.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Drawing;\nusing System.ComponentModel;\n\nnamespace Sheng.Winform.Controls\n{\n    \n    public class ShengLine:Control\n    {\n        public ShengLine()\n        {\n           \n        }\n\n        protected override void OnPaint(PaintEventArgs e)\n        {\n            base.OnPaint(e);\n            e.Graphics.DrawLine(Pens.Gray, 0, 0, this.Width, 0);\n            e.Graphics.DrawLine(Pens.White, 0, 1, this.Width, 1);\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengListView/Enums.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nnamespace Sheng.Winform.Controls\n{\n    /// <summary>\n    /// Represents the visual state of an image list view item.\n    /// </summary>\n    [Flags]\n    public enum ShengListViewItemState\n    {\n        /// <summary>\n        /// 没有任何选择状态，处于一般正常状态\n        /// </summary>\n        None = 0,\n        /// <summary>\n        /// 项处于选中状态\n        /// </summary>\n        Selected = 1,\n        /// <summary>\n        /// 该项具有输入焦点\n        /// </summary>\n        Focused = 2,\n        /// <summary>\n        /// 鼠标滑过\n        /// </summary>\n        Hovered = 4,\n    }\n\n    public enum ShengListViewItemVisibility\n    {\n        /// <summary>\n        /// The item is not visible.\n        /// </summary>\n        NotVisible,\n        /// <summary>\n        /// The item is partially visible.\n        /// </summary>\n        PartiallyVisible,\n        /// <summary>\n        /// The item is fully visible.\n        /// </summary>\n        Visible,\n    }\n\n    /// <summary>\n    /// 布局方式\n    /// </summary>\n    public enum ShengListViewLayoutMode\n    {\n        /// <summary>\n        /// 标准布局\n        /// </summary>\n        Standard = 0,\n        /// <summary>\n        /// 使项带有描述的布局\n        /// </summary>\n        Descriptive = 1\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengListView/Events.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nnamespace Sheng.Winform.Controls\n{\n\n    /// <summary>\n    /// 双击项事件参数\n    /// </summary>\n    public class ShengListViewItemDoubleClickEventArgs : EventArgs\n    {\n        public ShengListViewItem Item { get; private set; }\n\n        public ShengListViewItemDoubleClickEventArgs(ShengListViewItem item)\n        {\n            Item = item;\n        }\n    }\n\n    /// <summary>\n    /// 项被删除事件参数\n    /// </summary>\n    public class ShengListViewItemsRemovedEventArgs : EventArgs\n    {\n        public List<ShengListViewItem> Items { get; private set; }\n\n        public ShengListViewItemsRemovedEventArgs(List<ShengListViewItem> items)\n        {\n            Items = items;\n        }\n    }\n\n    public class ShengListViewGetItemTextEventArgs : EventArgs\n    {\n        public object Item { get; private set; }\n\n        public string Text { get; set; }\n\n        public ShengListViewGetItemTextEventArgs(object item)\n        {\n            Item = item;\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengListView/Layout/IShengListViewExtendMember.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nnamespace Sheng.Winform.Controls\n{\n    public interface IShengListViewExtendMember\n    {\n        Dictionary<string, string> GetExtendMembers();\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengListView/Layout/ShengListViewDescriptiveLayoutManager.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nnamespace Sheng.Winform.Controls\n{\n    class ShengListViewDescriptiveLayoutManager : ShengListViewLayoutManager\n    {\n        public ShengListViewDescriptiveLayoutManager(ShengListView imageListView)\n            : base(imageListView)\n        {\n            this.ItemHeight = 40;\n            this.Renderer = new ShengListViewDescriptiveRenderer(this);\n            this.Renderer.Theme = imageListView.Theme;\n        }\n    }\n\n   \n}"
  },
  {
    "path": "Sheng.Winform.Controls/ShengListView/Layout/ShengListViewDescriptiveMembers.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nnamespace Sheng.Winform.Controls\n{\n    public class ShengListViewDescriptiveMembers : IShengListViewExtendMember\n    {\n        public const string DescriptioinMember = \"Description\";\n        public string Description { get; set; }\n\n        #region ISEListViewExtendMember 成员\n\n        public Dictionary<string, string> GetExtendMembers()\n        {\n            Dictionary<string, string> members = new Dictionary<string, string>();\n\n            if (String.IsNullOrEmpty(Description) == false)\n                members.Add(DescriptioinMember, Description);\n\n            return members;\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengListView/Layout/ShengListViewDescriptiveRenderer.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Drawing;\n\nnamespace Sheng.Winform.Controls\n{\n    /// <summary>\n    /// 为项绘制带有描述信息的渲染器\n    /// </summary>\n    public class ShengListViewDescriptiveRenderer : ShengListViewRenderer\n    {\n        #region 私有成员\n\n        /// <summary>\n        /// 字的高度是否已初始化\n        /// 在第一次绘制时，测量文本的高度\n        /// </summary>\n        bool _headerHeightInited = false;\n\n        int _headerHeight;\n        Font _headerFont;\n        Size _itemPadding = new Size(8, 4);\n        StringFormat _itemHeaderStringFormat = new StringFormat();\n\n        #endregion\n\n        #region 构造\n\n        public ShengListViewDescriptiveRenderer(ShengListViewLayoutManager layoutManager)\n            : base(layoutManager)\n        {\n            layoutManager.ItemHeight = 40;\n\n            //_itemHeaderStringFormat.Alignment = StringAlignment.Center;\n            _itemHeaderStringFormat.FormatFlags = StringFormatFlags.LineLimit | StringFormatFlags.NoWrap;\n        }\n\n        #endregion\n\n        #region 受保护的方法\n\n        internal override void DrawForeground(Graphics g)\n        {\n            \n        }\n\n        internal override void DrawItemContent(Graphics g, Rectangle bounds, ShengListViewItem item)\n        {\n            string header = LayoutManager.GetItemText(item.Value);\n\n            //如果header为空则不南要绘制内容了\n            if (String.IsNullOrEmpty(header))\n                return;\n\n            string description = null;\n            if (LayoutManager.ContainerExtendMember(ShengListViewDescriptiveMembers.DescriptioinMember))\n            {\n                description = LayoutManager.GetItemText(item.Value,\n                    LayoutManager.GetExtendMember(ShengListViewDescriptiveMembers.DescriptioinMember));\n            }\n\n            if (_headerHeightInited == false)\n            {\n                _headerFont = new Font(Theme.ItemHeaderFont, FontStyle.Bold);\n\n                SizeF headerSize = g.MeasureString(header, _headerFont);\n                _headerHeight = (int)Math.Ceiling(headerSize.Height);\n\n                _headerHeightInited = true;\n            }\n\n            #region 绘制文本\n\n            Rectangle _headerBounds = new Rectangle();\n            _headerBounds.X = _itemPadding.Width;\n            _headerBounds.Y = _itemPadding.Height;//LayoutManager.ItemSize - _headerHeight - _itemPadding.Height;\n            _headerBounds.Width = bounds.Width;\n            _headerBounds.Height = _headerHeight;\n\n            Rectangle _descriptionBounds = new Rectangle();\n            _descriptionBounds.X = _itemPadding.Width;\n            _descriptionBounds.Y = _headerBounds.Y + _headerBounds.Height + _itemPadding.Height;\n            _descriptionBounds.Width = bounds.Width;\n            _descriptionBounds.Height = _headerHeight;\n\n            //注意，offset必须在最后，如果先offset了_headerBounds，再带入_headerBounds来计算_descriptionBounds\n            //就不对了\n            _headerBounds.Offset(bounds.Location);\n            _descriptionBounds.Offset(bounds.Location);\n\n            if (String.IsNullOrEmpty(header) == false)\n            {\n                using (SolidBrush brush = new SolidBrush(Theme.ItemHeaderColor))\n                {\n                    g.DrawString(header, _headerFont, brush, _headerBounds, _itemHeaderStringFormat);\n                }\n            }\n\n            if (String.IsNullOrEmpty(description) == false)\n            {\n                using (SolidBrush brush = new SolidBrush(Theme.ItemDescriptioniColor))\n                {\n                    g.DrawString(description, Theme.ItemHeaderFont, brush, _descriptionBounds, _itemHeaderStringFormat);\n                }\n            }\n\n            #endregion\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengListView/Layout/ShengListViewLayoutManager.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Drawing;\nusing System.Windows.Forms;\nusing System.Diagnostics;\n\nnamespace Sheng.Winform.Controls\n{\n    //默认布局引擎，以类似微软ListView的方式按行排列项\n    public class ShengListViewLayoutManager\n    {\n        #region 常量\n\n        /// <summary>\n        /// 框选的最短开始长度\n        /// </summary>\n        private const int SELECTION_TOLERANCE = 5;\n\n        /// <summary>\n        /// 框选时滚动条的自动滚动速度\n        /// </summary>\n        private const int AUTOSCROLL_VALUE = 10;\n\n        #endregion\n\n        #region 私有成员\n\n        private ShengListView _imageListView;\n\n        //滚动条放到布局引擎中来定义，这样可以实现不同布局引擎完全不同的布局方式\n        //比如为图像分组显示的引擎可以同时显示多个水平滚动条\n        private VScrollBar _vScrollBar = new VScrollBar();\n\n        private int ScrollBarWidth\n        {\n            get { return _vScrollBar.Width; }\n        }\n\n        /// <summary>\n        /// 用于鼠标框选时，框出了控件中项的显示范围时，自动滚动滚动条\n        /// </summary>\n        private Timer _scrollTimer = new Timer();\n\n        /// <summary>\n        /// 自动滚动时，滚动值\n        /// </summary>\n        private int _autoScrollValue = 0;\n\n        /// <summary>\n        /// 是否处于框选状态中\n        /// </summary>\n        internal bool MouseSelecting { get; private set; }\n\n        /// <summary>\n        /// 内框offset，内框offset是绝对相对于滚动条的\n        /// </summary>\n        private int _itemsAreaOffset = 0;\n\n        /// <summary>\n        /// 整个可显示项的边界的offset，包括上下padding部分\n        /// </summary>\n        private int _itemsBoundsOffset\n        {\n            get\n            {\n                int offSet = _itemsAreaOffset - (ItemsArea.Location.Y - ItemsBounds.Location.Y);\n                if (offSet < 0)\n                    offSet = 0;\n                return offSet;\n            }\n        }\n\n        /// <summary>\n        /// 鼠标按下时项区域边界的offset，即 _itemsAreaOffset\n        /// 用于框选时，跨越可视部队画框\n        /// </summary>\n        private int _mouseItemsAreaOffset = 0;\n\n        ///// <summary>\n        ///// 当前所能显示的最大列数\n        ///// </summary>\n        //private int _columnCount;\n\n        /// <summary>\n        /// 当前所能显示的最大行数\n        /// </summary>\n        private int _rowCount;\n\n        #endregion\n\n        #region 公开属性\n\n        private ShengListViewRenderer _renderer;\n        protected ShengListViewRenderer Renderer\n        {\n            get { return _renderer; }\n            set { _renderer = value; }\n        }\n\n        /// <summary>\n        /// Gets whether the shift key is down.\n        /// </summary>\n        internal bool ShiftKey { get { return _imageListView.ShiftKey; } }\n        /// <summary>\n        /// Gets whether the control key is down.\n        /// </summary>\n        internal bool ControlKey { get { return _imageListView.ControlKey; } }\n\n        internal bool Focused { get { return _imageListView.Focused; } }\n\n        internal Rectangle SelectionRectangle { get; private set; }\n\n        internal bool Suspend\n        {\n            get { return _imageListView.Suspend; }\n        }\n\n        internal string DisplayMember\n        {\n            get\n            {\n                return _imageListView.DisplayMember;\n            }\n        }\n\n        //TODO:在出现滚动条后，计算错误\n        //临时调用用，完成后改为internal\n        private int _firstPartiallyVisible;\n        public int FirstPartiallyVisible { get { return _firstPartiallyVisible; } }\n\n        private int _lastPartiallyVisible;\n        public int LastPartiallyVisible { get { return _lastPartiallyVisible; } }\n\n        private int _firstVisible;\n        public int FirstVisible { get { return _firstVisible; } }\n\n        private int _lastVisible;\n        public int LastVisible { get { return _lastVisible; } }\n\n        /// <summary>\n        /// 没有任何项\n        /// </summary>\n        public bool IsEmpty\n        {\n            get\n            {\n                return _imageListView.IsEmpty;\n            }\n        }\n\n        /// <summary>\n        /// 没有任何项处于可显示状态\n        /// </summary>\n        public bool NoneItemVisible\n        {\n            get\n            {\n                return _firstPartiallyVisible == -1 || _lastPartiallyVisible == -1;\n            }\n        }\n\n        /// <summary>\n        /// 整个控件区域\n        /// </summary>\n        public Rectangle ClientArea\n        {\n            get { return _imageListView.ClientRectangle; }\n        }\n\n        /// <summary>\n        /// 整个可用于绘制项的可视区域\n        /// 去除左右Padding部分，去除滚动条\n        /// </summary>\n        public Rectangle ItemsBounds\n        {\n            get\n            {\n                int scrollBarWidth = this.ScrollBarWidth;\n                Rectangle clientArea = this.ClientArea;\n                Padding padding = _imageListView.Padding;\n                int x = padding.Left;\n                int width = clientArea.Width - padding.Left - padding.Right - scrollBarWidth;\n\n                Rectangle itemsBounds = new Rectangle(x, clientArea.Y, width, clientArea.Height);\n                return itemsBounds;\n            }\n        }\n\n        /// <summary>\n        /// 用于绘制项的区域\n        /// 考虑边距间隔大小和滚动条区域\n        /// </summary>\n        public Rectangle ItemsArea\n        {\n            //要考虑边距间隔大小和滚动条区域\n            get\n            {\n                int scrollBarWidth = this.ScrollBarWidth;\n                Rectangle clientArea = this.ClientArea;\n                Padding padding = _imageListView.Padding;\n                int x = padding.Left;\n                int y = padding.Top;\n                int width = clientArea.Width - padding.Left - padding.Right - scrollBarWidth;\n                int height = clientArea.Height - padding.Top - padding.Bottom;\n\n                //在最小化窗口后，clientArea的尺寸为0\n                if (width < 0) width = 1;\n                if (height < 0) height = 1;\n\n                Rectangle itemsArea = new Rectangle(x, y, width, height);\n                return itemsArea;\n            }\n        }\n\n        //TODO:项的大小是不能固定死的，因为要考虑到操作系统的默认字体大小\n        private int _itemHeight = 24;\n        /// <summary>\n        /// 项的尺寸\n        /// 不放在ListView本身中定义而是放在LayoutManager中定义，是因为不同的布局方式\n        /// 可能会是带长宽的Size做为itemSize，比如平铺的方式\n        /// </summary>\n        internal int ItemHeight\n        {\n            get { return _itemHeight; }\n            set\n            {\n                _itemHeight = value;\n                _itemHeightWithMargin = _itemHeight + _margin;\n            }\n        }\n\n        private int _margin = 2;\n        /// <summary>\n        /// 项周围的边距\n        /// </summary>\n        public int Margin\n        {\n            get { return _margin; }\n            set\n            {\n                _margin = value;\n                _itemHeightWithMargin = _itemHeight + value;\n            }\n        }\n\n        private int _itemHeightWithMargin;\n        internal int ItemHeightWithMargin\n        {\n            get { return _itemHeightWithMargin; }\n        }\n\n        #endregion\n\n        #region debug 临时调试用\n\n        public int StartRow { get; set; }\n        public int EndRow { get; set; }\n        //public int StartCol { get; set; }\n        //public int EndCol { get; set; }\n\n        #endregion\n\n        #region 构造\n\n        public ShengListViewLayoutManager(ShengListView imageListView)\n        {\n            _imageListView = imageListView;\n\n            //_itemSize = new Size(ImageSize, ImageSize);\n            _itemHeightWithMargin = _itemHeight + _margin;\n\n            UpdateScrollBars();\n\n            _vScrollBar.Dock = DockStyle.Right;\n            _imageListView.Controls.Add(_vScrollBar);\n            _vScrollBar.Scroll += new ScrollEventHandler(_vScrollBar_Scroll);\n            _vScrollBar.ValueChanged += new EventHandler(_vScrollBar_ValueChanged);\n\n            _scrollTimer.Interval = 20;\n            _scrollTimer.Enabled = false;\n            _scrollTimer.Tick += new EventHandler(_scrollTimer_Tick);\n\n            //_renderer = new ListViewStandardRenderer(this);\n            //_renderer = new ListViewRenderer(this);\n            //_renderer = new ListViewDescriptiveRenderer(this);\n\n            //_renderer.Theme = _imageListView.Theme;\n        }\n\n        #endregion\n\n        #region 事件处理\n\n        void _vScrollBar_Scroll(object sender, ScrollEventArgs e)\n        {\n            //这里判断的原因是在鼠标操作滚动条时，即使只点一下，这里也会进来两次，原因不明\n            if (_itemsAreaOffset != e.NewValue)\n            {\n                _itemsAreaOffset = e.NewValue;\n            }\n        }\n\n        void _vScrollBar_ValueChanged(object sender, EventArgs e)\n        {\n            //这里判断的原因是可能在 _vScrollBar_Scroll 事件里就赋值过了\n            if (_itemsAreaOffset != _vScrollBar.Value)\n            {\n                _itemsAreaOffset = _vScrollBar.Value;\n            }\n\n            _imageListView.SuspendLayout();\n\n            if (MouseSelecting)\n            {\n                //如果处于框选状态，在重新绘制控件之前需要计算新的 SelectionRectangle\n                //因为SelectionRectangle一开始是在MouseMove中计算的，而当鼠标拉出控件边界时\n                //滚动条会继续滚动，如果此时保持鼠标不动，就要靠这里计算 SelectionRectangle 了\n                SelectionRectangle = CreateSelectionRectangle();\n                SelectItemsByRectangle(SelectionRectangle);\n            }\n\n            _imageListView.ResumeLayout(true);\n\n            CalculateVisibleItemsRange();            \n        }\n\n        void _scrollTimer_Tick(object sender, EventArgs e)\n        {\n            //自动滚动之后，必须重新绘制控件\n            //借助 _vScrollBar_ValueChanged 事件实现\n\n            //另外，在自动滚动之后，光重绘还不行，必须重新计算 SelectionRectangle\n            //SelectionRectangle 一开始是在 MouseMove 中计算的，如果在自动滚动的过程中不移动鼠标\n            //那就靠 _vScrollBar_ValueChanged 计算了\n\n            int scrollValue = _vScrollBar.Value + _autoScrollValue;\n            if (scrollValue > _vScrollBar.Maximum)\n                _vScrollBar.Value = _vScrollBar.Maximum;\n            else if (scrollValue < 0)\n                _vScrollBar.Value = 0;\n            else\n                _vScrollBar.Value = scrollValue;\n        }\n\n        #endregion\n\n        #region 受保护的方法\n\n        internal bool ContainerExtendMember(string member)\n        {\n            return _imageListView.ContainerExtendMember(member);\n        }\n\n        internal string GetExtendMember(string member)\n        {\n            return _imageListView.GetExtendMember(member);\n        }\n\n        internal string GetItemText(object itemValue)\n        {\n            return _imageListView.GetItemText(itemValue);\n        }\n\n        internal string GetItemText(object itemValue, string propertyName)\n        {\n            return _imageListView.GetItemText(itemValue, propertyName);\n        }\n\n        internal void OnItemsRemoved(List<ShengListViewItem> items)\n        {\n            _renderer.OnItemsRemoved(items);\n        }\n\n        internal void Dispose()\n        {\n            _imageListView.Controls.Remove(_vScrollBar);\n            _vScrollBar.Dispose();\n            _scrollTimer.Stop();\n            _scrollTimer.Enabled = false;\n            _scrollTimer.Dispose();\n            _renderer.Dispose();\n            _imageListView = null;\n        }\n\n        #endregion\n\n        #region 公开方法\n\n        ///// <summary>\n        ///// 测量当前项应该的高度\n        ///// </summary>\n        ///// <returns></returns>\n        //public int MeasureItemHeight()\n        //{\n        //    int textHeight = _imageListView.Font.Height;\n\n        //    int height = _borderSize * 2 + textHeight + Padding.Top + Padding.Bottom;\n\n        //    if (ShowDescription)\n        //        height = height + textHeight + _textSpaceBetween;\n\n        //    return height;\n        //}\n\n        public void Render(Graphics graphics)\n        {\n            //Debug.Write(\"Render(Graphics graphics)\" + Environment.NewLine);\n\n            Update();\n\n            _renderer.Render(graphics);\n        }\n\n        public void RenderItem(Graphics graphics, ShengListViewItem item)\n        {\n            Debug.Assert(MouseSelecting == false, \"MouseSelecting 为 \" + MouseSelecting.ToString());\n\n            _renderer.RenderItem(graphics, item);\n        }\n\n        /// <summary>\n        /// 更新整个布局引擎的状态\n        /// </summary>\n        public void Update()\n        {\n            //Debug.Write(\"Update()\" + Environment.NewLine);\n\n            CalculateGrid();\n\n            CalculateVisibleItemsRange();\n\n            UpdateScrollBars();\n        }\n\n        /// <summary>\n        /// 判断指定的项是否处于可见状态\n        /// </summary>\n        /// <param name=\"item\"></param>\n        /// <returns></returns>\n        public ShengListViewItemVisibility IsItemVisible(ShengListViewItem item)\n        {\n            int itemIndex = _imageListView.Items.IndexOf(item);\n\n            if (_imageListView.Items.Count == 0)\n                return ShengListViewItemVisibility.NotVisible;\n\n            if (itemIndex < 0 || itemIndex > _imageListView.Items.Count - 1)\n                return ShengListViewItemVisibility.NotVisible;\n\n            if (itemIndex < _firstPartiallyVisible || itemIndex > _lastPartiallyVisible)\n                return ShengListViewItemVisibility.NotVisible;\n            else if (itemIndex >= _firstVisible && itemIndex <= _lastVisible)\n                return ShengListViewItemVisibility.Visible;\n            else\n                return ShengListViewItemVisibility.PartiallyVisible;\n        }\n\n        /// <summary>\n        /// 获取项的呈现区域\n        /// </summary>\n        /// <param name=\"item\"></param>\n        /// <returns></returns>\n        public Rectangle GetItemBounds(ShengListViewItem item)\n        {\n            int index = _imageListView.Items.IndexOf(item);\n\n            return GetItemBounds(index);\n        }\n\n        public Rectangle GetItemBounds(int index)\n        {\n            Point location = ItemsArea.Location;\n\n            //测算滚动条向下滚动过的高度，做为初始 Y 坐标\n            location.Y += _margin / 2 - _itemsAreaOffset;\n\n            ////itemIndex % _columnCount 得到项在第几列\n            ////itemIndex / _columnCount 得到项在第几行\n            //location.X += _margin / 2 + (index % _columnCount) * _itemSizeWithMargin.Width;\n\n            ////在初始 Y 坐标的基础上，算出此项所在行，计算出其应该在的Y坐标\n            location.Y += index * _itemHeightWithMargin;\n\n            location.X = ItemsArea.X;\n\n            return new Rectangle(location, new Size(ItemsArea.Width, _itemHeight));\n        }\n\n        public List<ShengListViewItem> GetItems()\n        {\n            return _imageListView.Items.ToList();\n        }\n\n        /// <summary>\n        /// 获取当前所有可见项\n        /// </summary>\n        /// <returns></returns>\n        public List<ShengListViewItem> GetVisibleItems()\n        {\n            List<ShengListViewItem> items = new List<ShengListViewItem>();\n\n            for (int i = _firstPartiallyVisible; i <= _lastPartiallyVisible; i++)\n            {\n                items.Add(_imageListView.Items[i]);\n            }\n\n            return items;\n        }\n\n        public ShengListViewHitInfo HitTest(Point point)\n        {\n            int itemIndex = -1;\n\n            //这里对X，Y坐标的减，实现目的是平移坐标\n            //传进来的是相对控件左上角的坐标，应平移为Padding后的内框左上角相对坐标\n            //但是要考虑滚动时，上面的Padding也允许显示项\n            //X坐标直接向右平移即可\n            //Y坐标在没有滚动时，直接向下平移，如果存在滚动，当滚动值小于顶部Padding时\n            //将Y坐标平移至项的最层端Y坐标上，即：Padding-滚动值\n\n            //相对于Padding后的内框坐标系的坐标\n            Point relativePoint = point;\n\n            // Normalize to item area coordinates\n            relativePoint.X -= ItemsBounds.Left;\n\n            //y即平移量\n            //此处y坐标需要在绘制项的区域（Padding后的区域）的基础上，考虑滚动条的offset\n            int y = ItemsArea.Top - _itemsAreaOffset;\n            if (y < 0) y = 0;\n            relativePoint.Y -= y;\n\n            if (relativePoint.X > 0 && relativePoint.Y > 0)\n            {\n                //当前点击的行和列的索引，从0开始\n                //int col = relativePoint.X / _itemSizeWithMargin.Width;\n                int row = (relativePoint.Y + _itemsBoundsOffset) / _itemHeightWithMargin;\n\n                ////判断点的是不是右边的空白，可能右边会有比较大的空白，又没大到够完整的显示一列图像\n                //bool isNotHitRightEmptyArea = col <= _columnCount - 1;\n                //if (isNotHitRightEmptyArea)\n                //{\n                //    int index = row * _columnCount + col;\n\n                //    //判断是不是点在图像区域内，还是图像边上，四周的Margin上\n                //    Rectangle bounds = GetItemBounds(index);\n                //    //判断点的坐标是不是在项的显示区域（Bounds)内，要用相对整个控件的原始坐标\n                //    //因为项的bounds是相对整个控件的\n                //    bool isHitInItem = bounds.Contains(point.X, point.Y);\n\n                //    if (isHitInItem)\n                //    {\n                //        itemIndex = index;\n                //    }\n                //}\n\n                int index = row;\n                Rectangle bounds = GetItemBounds(index);\n                bool isHitInItem = bounds.Contains(point.X, point.Y);\n\n                if (isHitInItem)\n                {\n                    itemIndex = index;\n                }\n            }\n\n            //是否点击在了有效项上\n            bool itemHit = itemIndex >= 0 && itemIndex < _imageListView.Items.Count;\n\n            ShengListViewHitInfo hitInfo = new ShengListViewHitInfo(itemIndex, itemHit);\n            return hitInfo;\n        }\n\n        #endregion\n\n        #region 事件响应方法\n\n        public void MouseDown(MouseEventArgs e)\n        {\n            /*\n             * 如果按下的是鼠标右键\n             * 如果按在已选定的项上，只切换焦点，不改变选择\n             * 如果按在未选定项上，则切换为点的项为选中项\n             * 不考虑键盘按键\n             */\n\n            _mouseItemsAreaOffset = _itemsAreaOffset;\n\n            List<ShengListViewItem> oldSelectedItems = _imageListView.GetSelectedItems();\n\n            ShengListViewHitInfo hitInfo = HitTest(e.Location);\n\n            if (hitInfo.ItemHit)\n            {\n                ShengListViewItem item = _imageListView.Items[hitInfo.ItemIndex];\n                List<ShengListViewItem> allItems = _imageListView.Items.ToList();\n                ShengListViewItem currentFocusedItem = _imageListView.FocusedItem;\n\n                if (_imageListView.LeftButton)\n                {\n                    #region 如果不允许多选\n                    if (_imageListView.AllowMultiSelection == false)\n                    {\n                        //如果点击的项就是当前选择的项\n                        if (oldSelectedItems.Count > 0 && oldSelectedItems.Contains(item))\n                        {\n                            //判断Control键是否按下，如果按下了Control键，取消当前项的选择状态\n                            if (_imageListView.ControlKey)\n                                item.Selected = false;\n                        }\n                        else\n                        {\n                            //如果点击的项不是当前选择的项\n                            //清除原选定项的选定状态\n                            _imageListView.ClearSelect();\n                            //设置新项为选定项\n                            item.Selected = true;\n                        }\n                    }\n                    #endregion\n                    #region 如果允许多选\n                    //在同时按下 Control 和 Shift 的情况下，优先考虑 Shift\n                    else\n                    {\n                        #region 如果按下 Shift\n                        //判断是否按下了 Shift ，如果按下 Shift，不考虑 Control 的状态\n                        //也不用考虑是否点击的项是否是现有选定项之一\n                        if (_imageListView.ShiftKey)\n                        {\n                            //如果当前存在具有输入焦点的项\n                            if (currentFocusedItem != null && currentFocusedItem != item)\n                            {\n                                //连续选中从当前具有焦点的项至点击的项之间的所有项\n                                //并将不在此范围内的项取消选中状态\n                                int startIndex = Math.Min(currentFocusedItem.Index, hitInfo.ItemIndex);\n                                int endIndex = Math.Max(currentFocusedItem.Index, hitInfo.ItemIndex);\n                                foreach (var i in from c in oldSelectedItems where c.Index < startIndex || c.Index > endIndex select c)\n                                {\n                                    i.Selected = false;\n                                }\n                                for (int i = startIndex; i <= endIndex; i++)\n                                {\n                                    ShengListViewItem eachItem = allItems[i];\n                                    if (eachItem.Selected == false)\n                                        eachItem.Selected = true;\n                                }\n                            }\n                            //如果当前不存在具有输入焦点的项\n                            else\n                            {\n                                //清除原选定项的选定状态\n                                _imageListView.ClearSelect();\n                                item.Selected = true;\n                            }\n                        }\n                        #endregion\n                        #region 如果 Shift键没有处于按下状态\n                        else\n                        {\n                            #region 如果点击的项 是 当前选择的项之一\n                            if (oldSelectedItems.Count > 0 && oldSelectedItems.Contains(item))\n                            {\n                                //判断是否按下了 Control，且没有按下 Shift\n                                if (_imageListView.ControlKey && _imageListView.ShiftKey == false)\n                                {\n                                    item.Selected = false;\n                                }\n\n                                //判断是否什么键都没有按下\n                                if (_imageListView.ControlKey == false && _imageListView.ShiftKey == false)\n                                {\n                                    //清除原选定项的选定状态\n                                    _imageListView.ClearSelect();\n                                    item.Selected = true;\n                                }\n                            }\n                            #endregion\n                            #region 如果点击的项 不是 当前选择的项之一\n                            else\n                            {\n                                //判断Control键是否按下，如果按下了Control键，则保持原有选择的情况把新项也设置为选中\n                                //否则清除当前选择\n                                if (_imageListView.ControlKey == false)\n                                {\n                                    //清除原选定项的选定状态\n                                    _imageListView.ClearSelect();\n                                }\n                                item.Selected = true;\n                            }\n                            #endregion\n                        }\n                        #endregion\n                    }\n                    #endregion\n                }\n                else\n                {\n                    //如果点在未选中的项上\n                    if (oldSelectedItems.Contains(item) == false)\n                    {\n                        _imageListView.ClearSelect();\n                        //设置新项为选定项\n                        item.Selected = true;\n                    }\n                }\n\n                #region 为项设置输入焦点\n\n                //设置新的输入焦点要放在后面处理，因为在使用Shift连续选择时，需要用到原具有焦点的项\n                if (currentFocusedItem == null || (currentFocusedItem != null && currentFocusedItem != item))\n                {\n                    if (currentFocusedItem != null)\n                        currentFocusedItem.Focused = false;\n                    item.Focused = true;\n                }\n                #endregion\n            }\n            else\n            {\n                _imageListView.ClearSelect();\n            }\n\n            List<ShengListViewItem> newSelectedItems = _imageListView.GetSelectedItems();\n            if (oldSelectedItems.SequenceEqual(newSelectedItems) == false)\n            {\n                _imageListView.NeedPaint();\n                _imageListView.OnSelectedItemChanged();\n            }\n        }\n\n        public void MouseUp(MouseEventArgs e)\n        {\n            if (MouseSelecting)\n            {\n                MouseSelecting = false;\n                _scrollTimer.Enabled = false;\n                _autoScrollValue = 0;\n                _imageListView.NeedPaint();\n            }\n        }\n\n        public void MouseMove(MouseEventArgs e)\n        {\n            Point lastMouseDownLocation = _imageListView.LastMouseDownLocation;\n\n            #region 如果处于框选状态\n            if (MouseSelecting)\n            {\n                //处于框选状态时，框内的项被选中不能在 MouseMove 事件中处理\n                //因为当鼠标移出控件，滚动条自动滚动时，不动鼠标，就不会触发 MouseMove 事件\n\n                #region 判断是否需要自动滚动滚动条\n\n                if (_scrollTimer.Enabled == false)\n                {\n                    //需向下滚动\n                    if (e.Y > ItemsBounds.Bottom)\n                    {\n                        _autoScrollValue = AUTOSCROLL_VALUE;\n                        _scrollTimer.Enabled = true;\n                    }\n                    //需向上滚动\n                    else if (e.Y < ItemsBounds.Top)\n                    {\n                        _autoScrollValue = -AUTOSCROLL_VALUE;\n                        _scrollTimer.Enabled = true;\n                    }\n                }\n                //鼠标从控件外面又回到了控件内，则停止自动滚动\n                else if (_scrollTimer.Enabled && ItemsBounds.Contains(e.Location))\n                {\n                    _scrollTimer.Enabled = false;\n                    _autoScrollValue = 0;\n                }\n\n                #endregion\n\n                //创建选择框 Rectangle\n                SelectionRectangle = CreateSelectionRectangle();\n                SelectItemsByRectangle(SelectionRectangle);\n\n                _imageListView.NeedPaint();\n            }\n            #endregion\n            #region 如果不是处于框选状态\n            else\n            {\n                //如果允许多选，鼠标处于按下状态，且距上次点击的点，大于了最小框选开始尺寸\n                if (_imageListView.AllowMultiSelection && _imageListView.AnyMouseButton && (\n                    (Math.Abs(e.Location.X - lastMouseDownLocation.X) > SELECTION_TOLERANCE ||\n                    Math.Abs(e.Location.Y - lastMouseDownLocation.Y) > SELECTION_TOLERANCE)))\n                {\n                    MouseSelecting = true;\n                }\n            }\n            #endregion\n        }\n\n        public void OnMouseWheel(MouseEventArgs e)\n        {\n            int offSet = _itemsAreaOffset;\n            int newYOffset = offSet - (e.Delta / SystemInformation.MouseWheelScrollDelta)\n                   * _vScrollBar.SmallChange;\n            if (newYOffset > _vScrollBar.Maximum - _vScrollBar.LargeChange + 1)\n                newYOffset = _vScrollBar.Maximum - _vScrollBar.LargeChange + 1;\n            if (newYOffset < 0)\n                newYOffset = 0;\n            if (newYOffset < _vScrollBar.Minimum) newYOffset = _vScrollBar.Minimum;\n            if (newYOffset > _vScrollBar.Maximum) newYOffset = _vScrollBar.Maximum;\n            _vScrollBar.Value = newYOffset;\n        }\n\n        public void OnKeyDown(KeyEventArgs e)\n        {\n\n            // If the shift key or the control key is pressed and there is no focused item\n            // set the first item as the focused item.\n            if ((ShiftKey || ControlKey) && _imageListView.Items.Count != 0 &&\n                _imageListView.FocusedItem == null)\n            {\n                _imageListView.Items[0].Focused = true;\n            }\n\n            ShengListViewItem currentFocusedItem = _imageListView.FocusedItem;\n\n            if (_imageListView.Items.Count != 0)\n            {\n                int index = 0;\n                if (currentFocusedItem != null)\n                    index = currentFocusedItem.Index;\n\n                int newindex = ApplyNavKey(index, e.KeyCode);\n                if (index != newindex)\n                {\n                    #region 根据新index做选择\n\n                    if (ControlKey)\n                    {\n                        // Just move the focus\n                    }\n                    else if (_imageListView.AllowMultiSelection && ShiftKey)\n                    {\n                        int startIndex = 0;\n                        int endIndex = 0;\n                        List<ShengListViewItem> selectedItems = _imageListView.GetSelectedItems();\n                        if (selectedItems.Count != 0)\n                        {\n                            startIndex = selectedItems[0].Index;\n                            endIndex = selectedItems[selectedItems.Count - 1].Index;\n                            _imageListView.ClearSelect();\n                        }\n                        if (index == startIndex)\n                            startIndex = newindex;\n                        else if (index == endIndex)\n                            endIndex = newindex;\n                        for (int i = Math.Min(startIndex, endIndex); i <= Math.Max(startIndex, endIndex); i++)\n                        {\n                            _imageListView.Items[i].Selected = true;\n                        }\n                    }\n                    else\n                    {\n                        _imageListView.ClearSelect();\n                        _imageListView.Items[newindex].Selected = true;\n                    }\n\n                    currentFocusedItem.Focused = false;\n                    _imageListView.Items[newindex].Focused = true;\n\n                    EnsureVisible(newindex);\n\n                    #endregion\n\n                    //触发事件\n                    _imageListView.OnSelectedItemChanged();\n                }\n            }\n\n            _imageListView.NeedPaint();\n        }\n\n        public void OnKeyUp(KeyEventArgs e)\n        {\n            //Refresh();\n        }\n\n        #endregion\n\n        #region 私有方法\n        \n        private void Refresh()\n        {\n            _imageListView.Refresh();\n        }\n\n        /// <summary>\n        /// Calculates the maximum number of rows and columns \n        /// that can be fully displayed.\n        /// </summary>\n        private void CalculateGrid()\n        {\n            Rectangle itemArea = this.ItemsArea;\n            //_columnCount = (int)System.Math.Floor((float)itemArea.Width / (float)_itemSizeWithMargin.Width);\n            _rowCount = (int)System.Math.Floor((float)itemArea.Height / (float)_itemHeightWithMargin);\n\n            //if (_columnCount < 1) _columnCount = 1;\n            if (_rowCount < 1) _rowCount = 1;\n        }\n\n        /// <summary>\n        /// 计算当前可见项的index范围\n        /// </summary>\n        private void CalculateVisibleItemsRange()\n        {\n            Rectangle itemsArea = this.ItemsArea;\n\n            //这里必须把控件的内部Padding值考虑进来\n            //_visibleOffset 是相对于 ItemsArea 的，此处要得到相对于整个控件可视区域的 offSet\n            //因为显示的图片项即使超出了 ItemsArea ，但还是在可视区域内，还是完全可见的，在计算时需要考虑\n            //ItemsArea.Location.Y - ItemsBounds.Location.Y 实际上就是Padding\n            //但是这样写逻辑上好些，因为实际意义在于 ItemsArea 和 ItemsBounds 之间的区域也是可以显示内容的，在意义上与Padding无关\n\n            int offSet = _itemsAreaOffset - (ItemsArea.Location.Y - ItemsBounds.Location.Y);\n            if (offSet < 0)\n                offSet = 0;\n\n            int itemAreaHeight = ItemsBounds.Height;\n\n            _firstPartiallyVisible = (int)System.Math.Floor((float)offSet / (float)_itemHeightWithMargin);\n            _lastPartiallyVisible = (int)System.Math.Ceiling((float)(offSet + itemAreaHeight) / (float)_itemHeightWithMargin) - 1;\n\n            if (_firstPartiallyVisible < 0) _firstPartiallyVisible = 0;\n            if (_firstPartiallyVisible > _imageListView.Items.Count - 1) _firstPartiallyVisible = _imageListView.Items.Count - 1;\n            if (_lastPartiallyVisible < 0) _lastPartiallyVisible = 0;\n            if (_lastPartiallyVisible > _imageListView.Items.Count - 1) _lastPartiallyVisible = _imageListView.Items.Count - 1;\n\n            _firstVisible = (int)System.Math.Ceiling((float)offSet / (float)_itemHeightWithMargin);\n            _lastVisible = (int)System.Math.Floor((float)(offSet + itemAreaHeight) / (float)_itemHeightWithMargin) - 1;\n\n            if (_firstVisible < 0) _firstVisible = 0;\n            if (_firstVisible > _imageListView.Items.Count - 1) _firstVisible = _imageListView.Items.Count - 1;\n            if (_lastVisible < 0) _lastVisible = 0;\n            if (_lastVisible > _imageListView.Items.Count - 1) _lastVisible = _imageListView.Items.Count - 1;\n        }\n\n        /// <summary>\n        /// 更新滚动条状态\n        /// </summary>\n        private void UpdateScrollBars()\n        {\n            if (_imageListView.Items.Count > 0)\n            {\n                _vScrollBar.Minimum = 0;\n                _vScrollBar.Maximum = Math.Max(0,\n                    (int)Math.Ceiling(\n                    (float)_imageListView.Items.Count) * _itemHeightWithMargin - 1);\n                _vScrollBar.LargeChange = ItemsArea.Height;\n                _vScrollBar.SmallChange = _itemHeightWithMargin;\n\n                bool vScrollRequired = (_imageListView.Items.Count > 0) &&\n                    (_rowCount < _imageListView.Items.Count);\n                _vScrollBar.Visible = vScrollRequired;\n\n                //此处重新计算滚动条的滚动值\n                //当滚动条出现，并滚动到底部时，改变控件的高度，就是向下拉大窗体\n                //已经绘制的项下面会开始出现空白，就是因为滚动条的值还是旧值，_itemsAreaOffset也没有变化\n                //除非用鼠标点一下滚动条，否则滚动条的 ValueChanged 事件也不会触发\n                //所以绘制出的项的起始Y轴是不对的，必须在此重新计算滚动条的Value值\n                if (_itemsAreaOffset > _vScrollBar.Maximum - _vScrollBar.LargeChange + 1)\n                {\n                    _vScrollBar.Value = _vScrollBar.Maximum - _vScrollBar.LargeChange + 1;\n                    _itemsAreaOffset = _vScrollBar.Value;\n                }\n            }\n            else\n            {\n                _vScrollBar.Visible = false;\n                _vScrollBar.Value = 0;\n                _vScrollBar.Minimum = 0;\n                _vScrollBar.Maximum = 0;\n            }\n        }\n\n        /// <summary>\n        /// 创建框选框\n        /// </summary>\n        /// <returns></returns>\n        private Rectangle CreateSelectionRectangle()\n        {\n            Point mousePoint = _imageListView.PointToClient(Cursor.Position);\n            Point lastMouseDownLocation = _imageListView.LastMouseDownLocation;\n\n            #region 说明\n            \n            //当框选的同时，滚动滚动条\n            //计算offset:\n            //由于可视区域和项的一般显示区域之间有个padding，而滚动条是以内部区域为标准的\n            //所以当滚动条开始滚动时，可能项还是全部显示在可视范围内的（padding区也可以显示）\n            //那么此时 _itemsBoundsOffset 还是 0，而按下鼠标时 _mouseDownOffset 记录的也是当时的 _itemsBoundsOffset\n            //那么在计算 SelectionRectangle 的 Y 坐标时，\n            //如果直接用 _itemsBoundsOffset 参与计算，就会产生一个和padding有关的误差\n            //如 lastMouseDownLocation.Y - (viewOffset - _mouseDownOffset) ，假如此时向下滚动了一点\n            //但所有的项还在可视范围内，那么 就会是 lastMouseDownLocation.Y - (0 - 0) \n            //SelectionRectangle 的 Y 坐标就差生了误差\n            //解决的办法是使用 _itemsAreaOffset（既滚动条的Value），使框框的Y坐标与滚动条同步滚动即可\n\n            #endregion\n\n            int viewOffset = _itemsAreaOffset;\n            Point pt1 = new Point(lastMouseDownLocation.X, lastMouseDownLocation.Y - (viewOffset - _mouseItemsAreaOffset));\n            Point pt2 = new Point(mousePoint.X, mousePoint.Y);\n            Rectangle rect = new Rectangle(Math.Min(pt1.X, pt2.X), Math.Min(pt1.Y, pt2.Y),\n                Math.Abs(pt1.X - pt2.X), Math.Abs(pt1.Y - pt2.Y));\n\n            return rect;\n        }\n\n        /// <summary>\n        /// 根据矩形区域选择项\n        /// </summary>\n        /// <param name=\"rect\"></param>\n        private void SelectItemsByRectangle(Rectangle rect)\n        {\n            int viewOffset = _itemsAreaOffset;\n\n            Point pt1 = new Point(SelectionRectangle.Left, SelectionRectangle.Top);\n            Point pt2 = new Point(SelectionRectangle.Right, SelectionRectangle.Bottom);\n\n            //- ItemsArea.Y 和 - ItemsArea.X\n            //是因为，选择框的是以整个控件可视区域为坐标系的，而绘制的项是在Padding区内的\n            //那么就需要修正或者说同步这个偏差，才能得到正确的行列\n            int startRow = (int)Math.Floor((float)(Math.Min(pt1.Y, pt2.Y) + viewOffset - ItemsArea.Y) /\n                  (float)this._itemHeightWithMargin);\n            int endRow = (int)Math.Floor((float)(Math.Max(pt1.Y, pt2.Y) + viewOffset - ItemsArea.Y) /\n                (float)this._itemHeightWithMargin);\n            //int startCol = (int)Math.Floor((float)(Math.Min(pt1.X, pt2.X) - ItemsArea.X) /\n            //    (float)this._itemSizeWithMargin.Width);\n            //int endCol = (int)Math.Floor((float)(Math.Max(pt1.X, pt2.X) - ItemsArea.X) /\n            //    (float)this._itemSizeWithMargin.Width);\n\n            //行不能这样判断，因为_rowCount表示的只是控件可视范围内的可视行数\n            //在框选时，框会跨越可视区域的，这里的endRow要的是实际的项所在行数\n            //列不存在这个问题，因为不支持水平滚动\n            //if (endRow >= _rowCount)\n            //    endRow = _rowCount -1;\n            //if (endCol >= _columnCount)\n            //    endCol = _columnCount - 1;\n            //if (startCol < 0)\n            //    startCol = 0;\n\n            //创建一个应该被选定的项的index数组\n            int itemsCount = _imageListView.Items.Count;\n            List<int> selectItemsIndex = new List<int>();\n            for (int i = startRow; i <= endRow; i++)\n            {\n                int index = i;\n                if (index >= 0 && index < itemsCount)\n                    selectItemsIndex.Add(index);\n\n                //for (int j = startCol; j <= endCol; j++)\n                //{\n                //    int index = i * _columnCount + j;\n                //    if (index >= 0 && index < itemsCount)\n                //        selectItemsIndex.Add(index);\n                //}\n            }\n\n            //如果当前没有按下Shift键，那么\n            //判断当前选定的项中有没有不在框选区内的，如果有将其取消选定\n            if (ShiftKey == false)\n            {\n                List<ShengListViewItem> currentSlectedItems = _imageListView.GetSelectedItems();\n                foreach (var item in currentSlectedItems)\n                {\n                    if (selectItemsIndex.Contains(item.Index) == false)\n                        item.Selected = false;\n                }\n            }\n\n            ShengListViewItemCollection allItems = _imageListView.Items;\n            //使框选区内的项都处于选中状态\n            foreach (var index in selectItemsIndex)\n            {\n                if (allItems[index].Selected == false)\n                    allItems[index].Selected = true;\n            }\n\n            //debug\n            StartRow = startRow;\n            EndRow = endRow;\n            //StartCol = startCol;\n            //EndCol = endCol;\n        }\n\n        /// <summary>\n        /// 应用导航键，如上下左右，返回应用导航键之后的项的坐标\n        /// </summary>\n        private int ApplyNavKey(int index, Keys key)\n        {\n            int itemsCount = _imageListView.Items.Count;\n\n            if (key == Keys.Up && index > 0)\n                index -= 1;\n            else if (key == Keys.Down && index < itemsCount - 1)\n                index += 1;\n            else if (key == Keys.Left && index > 0)\n                index--;\n            else if (key == Keys.Right && index < itemsCount - 1)\n                index++;\n            else if (key == Keys.PageUp && index >= (_rowCount - 1))\n                index -= (_rowCount - 1);\n            else if (key == Keys.PageDown && index < itemsCount - (_rowCount - 1))\n                index += (_rowCount - 1);\n            else if (key == Keys.Home)\n                index = 0;\n            else if (key == Keys.End)\n                index = itemsCount - 1;\n\n            if (index < 0)\n                index = 0;\n            else if (index > itemsCount - 1)\n                index = itemsCount - 1;\n\n            return index;\n        }\n\n        /// <summary>\n        /// 使指定下标的项处于可见状态\n        /// </summary>\n        /// <param name=\"itemIndex\"></param>\n        public void EnsureVisible(int itemIndex)\n        {\n            int itemCount = _imageListView.Items.Count;\n            if (itemCount == 0) return;\n            if (itemIndex < 0 || itemIndex >= itemCount) return;\n\n            // Already visible?\n            Rectangle bounds = this.ItemsBounds;\n            Rectangle itemBounds = GetItemBounds(itemIndex);\n\n            if (bounds.Contains(itemBounds) == false)\n            {\n                int delta = 0;\n                if (itemBounds.Top < bounds.Top)\n                    delta = bounds.Top - itemBounds.Top;\n                else\n                {\n                    int topItemIndex = itemIndex - (_rowCount - 1) ;\n                    if (topItemIndex < 0) topItemIndex = 0;\n                    delta = bounds.Top - GetItemBounds(topItemIndex).Top;\n                }\n                int newYOffset = this._itemsBoundsOffset - delta;\n                if (newYOffset > _vScrollBar.Maximum - _vScrollBar.LargeChange + 1)\n                    newYOffset = _vScrollBar.Maximum - _vScrollBar.LargeChange + 1;\n                if (newYOffset < _vScrollBar.Minimum)\n                    newYOffset = _vScrollBar.Minimum;\n                //mViewOffset.X = 0;\n                //mViewOffset.Y = newYOffset;\n                //hScrollBar.Value = 0;\n                _vScrollBar.Value = newYOffset;\n            }\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengListView/Layout/ShengListViewRenderer.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Drawing;\nusing System.Drawing.Drawing2D;\nusing System.Windows.Forms;\nusing Sheng.Winform.Controls.Drawing;\n\nnamespace Sheng.Winform.Controls\n{\n    /// <summary>\n    /// 默认渲染器，不绘制项的实际内容，但是绘制DEBUG信息\n    /// </summary>\n    public class ShengListViewRenderer\n    {\n        #region 受保护的成员\n\n        private bool _disposed = false;\n        protected bool Disposed\n        {\n            get { return _disposed; }\n        }\n\n        private int _radius = 2;\n        protected int Radius\n        {\n            get { return _radius; }\n        }\n      \n        #endregion\n\n        #region 公开属性\n\n        internal ShengListViewTheme Theme { get; set; }\n\n        protected ShengListViewLayoutManager _layoutManager;\n        internal ShengListViewLayoutManager LayoutManager { get { return _layoutManager; } }\n\n        #region 构造\n\n        public ShengListViewRenderer(ShengListViewLayoutManager layoutManager)\n        {\n            _layoutManager = layoutManager;\n        }\n\n        #endregion\n\n        #endregion\n\n        #region 公开方法\n\n        public void Render(Graphics graphics)\n        {\n            if (LayoutManager.Suspend)\n                return;\n\n            if (_disposed) return;\n\n            RenderBackground(graphics);\n\n            RenderItems(graphics);\n\n            RenderSelectionRectangle(graphics);\n\n            DrawForeground(graphics);\n        }\n\n        public void RenderItem(Graphics g, ShengListViewItem item)\n        {\n            if (LayoutManager.Suspend)\n                return;\n\n            if (LayoutManager.IsItemVisible(item) == ShengListViewItemVisibility.NotVisible)\n                return;\n\n            DrawItem(g, item);\n        }\n\n        #endregion\n\n        #region 受保护方法\n\n        internal void Dispose()\n        {\n            Theme = null;\n        }\n\n        /// <summary>\n        /// 用于子类重写时删除相应的缓存\n        /// </summary>\n        /// <param name=\"items\"></param>\n        internal virtual void OnItemsRemoved(List<ShengListViewItem> items)\n        {\n\n        }\n\n        //不要直接调用这些Draw方法，internal的目的只是为了子类能够重写\n\n        /// <summary>\n        /// 绘制项的背景\n        /// </summary>\n        /// <param name=\"g\">The System.Drawing.Graphics to draw on.</param>\n        /// <param name=\"bounds\">The client coordinates of the item area.</param>\n        internal virtual void DrawBackground(Graphics g, Rectangle bounds)\n        {\n            // Clear the background\n            g.Clear(Theme.BackColor);\n        }\n\n        /// <summary>\n        /// 绘制最终的前景\n        /// </summary>\n        /// <param name=\"g\"></param>\n        /// <param name=\"bounds\"></param>\n        internal virtual void DrawForeground(Graphics g)\n        {\n            //输出debug信息\n            g.SetClip(LayoutManager.ClientArea);\n            g.DrawRectangle(Pens.Green, LayoutManager.ItemsArea);\n\n            Color brushColor = Color.FromArgb(150, Color.Black);\n            using (SolidBrush brush = new SolidBrush(brushColor))\n            {\n                g.FillRectangle(brush, new Rectangle(0, 0, 500, 50));\n            }\n            string debugInfo = \"ShiftKey:\" + LayoutManager.ShiftKey.ToString() +\n                \",ControlKey:\" + LayoutManager.ControlKey.ToString() + Environment.NewLine;\n            debugInfo += \"SelectionRectangle:\" + LayoutManager.SelectionRectangle.ToString() + Environment.NewLine;\n            debugInfo += \"StartRow:\" + LayoutManager.StartRow + \"，EndRow:\" + LayoutManager.EndRow;// +\"，StartCol:\" + LayoutManager.StartCol + \"，EndCol:\" + LayoutManager.EndCol;\n\n            g.DrawString(debugInfo, SystemFonts.DefaultFont, Brushes.White, LayoutManager.ClientArea);\n        }\n\n        /// <summary>\n        /// 绘制选择边框\n        /// </summary>\n        /// <param name=\"g\">The System.Drawing.Graphics to draw on.</param>\n        /// <param name=\"selection\">The client coordinates of the selection rectangle.</param>\n        internal virtual void DrawSelectionRectangle(Graphics g, Rectangle selection)\n        {\n            if (LayoutManager.Suspend)\n                return;\n\n            using (SolidBrush brush = new SolidBrush(Theme.SelectionRectangleColor))\n            using (Pen pen = new Pen(Theme.SelectionRectangleBorderColor))\n            {\n                g.FillRectangle(brush, selection);\n                g.DrawRectangle(pen, selection);\n            }\n        }\n\n        /// <summary>\n        /// 绘制项的边框\n        /// </summary>\n        /// <param name=\"g\"></param>\n        /// <param name=\"bounds\"></param>\n        internal virtual void DrawItemBorder(Graphics g, Rectangle bounds, ShengListViewItem item)\n        {\n            if (item.Hovered || item.Selected)\n            {\n                Rectangle backgroundRect = bounds;\n                backgroundRect.Width -= 1;\n                backgroundRect.Height -= 1;\n\n                using (Pen pWhite128 = new Pen(Color.FromArgb(128, Theme.ItemBorderColor)))\n                {\n                   // ImageListViewUtility.DrawRoundedRectangle(g, pWhite128, bounds.Left, bounds.Top, bounds.Width - 1, bounds.Height - 1, _radius);\n                    g.DrawPath(pWhite128, DrawingTool.RoundedRect(backgroundRect, _radius));\n                }\n            }\n        }\n\n        /// <summary>\n        /// 绘制项\n        /// </summary>\n        /// <param name=\"g\"></param>\n        /// <param name=\"item\"></param>\n        /// <param name=\"state\"></param>\n        /// <param name=\"bounds\"></param>\n        internal virtual void DrawItem(Graphics g, ShengListViewItem item)\n        {\n            Rectangle bounds = LayoutManager.GetItemBounds(item);\n            g.SetClip(bounds);\n\n            DrawItemBackground(g, bounds);\n\n            Rectangle backgroundRect = bounds;\n            backgroundRect.Width -= 1;\n            backgroundRect.Height -= 1;\n\n            // Paint background Selected\n            if ((LayoutManager.Focused && ((item.State & ShengListViewItemState.Selected) == ShengListViewItemState.Selected)) ||\n                (LayoutManager.Focused == false && ((item.State & ShengListViewItemState.Selected) == ShengListViewItemState.Selected) && ((item.State & ShengListViewItemState.Hovered) == ShengListViewItemState.Hovered)))\n            {\n                using (Brush bSelected = new LinearGradientBrush(backgroundRect, Theme.SelectedColorStart, Theme.SelectedColorEnd, LinearGradientMode.Vertical))\n                {\n                  //  ImageListViewUtility.FillRoundedRectangle(g, bSelected, bounds, 4);\n                    g.FillPath(bSelected, DrawingTool.RoundedRect(backgroundRect, _radius));\n\n                }\n            }\n            // Paint background unfocused\n            else if (LayoutManager.Focused == false && ((item.State & ShengListViewItemState.Selected) == ShengListViewItemState.Selected))\n            {\n                using (Brush bGray64 = new LinearGradientBrush(backgroundRect, Theme.UnFocusedColorStart, Theme.UnFocusedColorEnd, LinearGradientMode.Vertical))\n                {\n                  //  ImageListViewUtility.FillRoundedRectangle(g, bGray64, bounds, 4);\n                    g.FillPath(bGray64, DrawingTool.RoundedRect(backgroundRect, _radius));\n                }\n            }\n\n            // Paint background Hovered\n            //如果正处于框选状态，不绘制Hover状态，减小闪烁\n            if (LayoutManager.MouseSelecting == false && (item.State & ShengListViewItemState.Hovered) == ShengListViewItemState.Hovered)\n            {\n                using (Brush bHovered = new LinearGradientBrush(backgroundRect, Theme.HoverColorStart, Theme.HoverColorEnd, LinearGradientMode.Vertical))\n                {\n                //    ImageListViewUtility.FillRoundedRectangle(g, bHovered, bounds, 4);\n                    g.FillPath(bHovered, DrawingTool.RoundedRect(backgroundRect, _radius));\n                }\n            }\n\n            DrawItemBorder(g, bounds, item);\n\n            // Focus rectangle\n            if (LayoutManager.Focused && ((item.State & ShengListViewItemState.Focused) == ShengListViewItemState.Focused))\n            {\n                ControlPaint.DrawFocusRectangle(g, bounds);\n            }\n\n            DrawItemContent(g, bounds, item);\n        }\n\n        /// <summary>\n        /// 绘制项的背景\n        /// </summary>\n        /// <param name=\"g\"></param>\n        /// <param name=\"bounds\"></param>\n        internal virtual void DrawItemBackground(Graphics g, Rectangle bounds)\n        {\n            // Paint background\n            using (Brush bItemBack = new SolidBrush(Theme.ItemBackColor))\n            {\n                g.FillRectangle(bItemBack, bounds);\n            }\n        }\n\n        /// <summary>\n        /// 绘制项的内容\n        /// </summary>\n        /// <param name=\"g\"></param>\n        /// <param name=\"bounds\"></param>\n        /// <param name=\"item\"></param>\n        internal virtual void DrawItemContent(Graphics g, Rectangle bounds, ShengListViewItem item)\n        {\n            //显示debug信息\n            string debugInfo = item.Index + Environment.NewLine +\n                bounds.ToString() + Environment.NewLine +\n                item.State.ToString();\n            g.DrawString(debugInfo, SystemFonts.DefaultFont, Brushes.Black, bounds);\n        }\n\n        #endregion\n\n        #region 私有方法\n\n        /// <summary>\n        /// 绘制背景\n        /// </summary>\n        /// <param name=\"g\"></param>\n        private void RenderBackground(Graphics g)\n        {\n            if (LayoutManager.Suspend)\n                return;\n\n            g.SetClip(LayoutManager.ClientArea);\n            DrawBackground(g, LayoutManager.ClientArea);\n        }\n\n        /// <summary>\n        /// 绘制当前所有可见项\n        /// </summary>\n        /// <param name=\"g\"></param>\n        private void RenderItems(Graphics g)\n        {\n            if (LayoutManager.Suspend)\n                return;\n\n            // Is the control empty?\n            if (LayoutManager.IsEmpty)\n                return;\n\n            // No items visible?\n            if (LayoutManager.NoneItemVisible)\n                return;\n\n            List<ShengListViewItem> items = LayoutManager.GetVisibleItems();\n            foreach (ShengListViewItem item in items)\n            {\n                RenderItem(g, item);\n            }\n        }\n\n        /// <summary>\n        /// Renders the selection rectangle.\n        /// </summary>\n        /// <param name=\"g\">The graphics to draw on.</param>\n        private void RenderSelectionRectangle(Graphics g)\n        {\n            if (LayoutManager.Suspend)\n                return;\n\n            if (LayoutManager.MouseSelecting == false)\n                return;\n\n            Rectangle sel = LayoutManager.SelectionRectangle;\n            if (sel.Height > 0 && sel.Width > 0)\n            {\n                g.SetClip(LayoutManager.ClientArea);\n                    \n                DrawSelectionRectangle(g, sel);\n            }\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengListView/Layout/ShengListViewStandardLayoutManager.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nnamespace Sheng.Winform.Controls\n{\n    class ShengListViewStandardLayoutManager : ShengListViewLayoutManager\n    {\n        public ShengListViewStandardLayoutManager(ShengListView imageListView)\n            : base(imageListView)\n        {\n            this.ItemHeight = 24;\n            this.Renderer = new ShengListViewStandardRenderer(this);\n            this.Renderer.Theme = imageListView.Theme;\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengListView/Layout/ShengListViewStandardRenderer.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Drawing;\n\nnamespace Sheng.Winform.Controls\n{\n    /// <summary>\n    /// 默认渲染器，以类似微软ListView的方式按行绘制项，只绘制简单的文本\n    /// </summary>\n    class ShengListViewStandardRenderer : ShengListViewRenderer\n    {\n        #region 私有成员\n\n        /// <summary>\n        /// 字的高度是否已初始化\n        /// 在第一次绘制时，测量文本的高度\n        /// </summary>\n        bool _headerHeightInited = false;\n\n        int _headerHeight;\n        Size _itemPadding = new Size(8, 4);\n        Rectangle _headerBounds;\n        StringFormat _itemHeaderStringFormat = new StringFormat();\n\n        #endregion\n\n        #region 构造\n\n        public ShengListViewStandardRenderer(ShengListViewLayoutManager layoutManager)\n            : base(layoutManager)\n        {\n            layoutManager.ItemHeight = 24;\n\n            //_itemHeaderStringFormat.Alignment = StringAlignment.Center;\n            _itemHeaderStringFormat.FormatFlags = StringFormatFlags.LineLimit| StringFormatFlags.NoWrap;\n        }\n\n        #endregion\n\n        #region 受保护的方法\n\n        internal override void DrawForeground(Graphics g)\n        {\n\n        }\n\n        internal override void DrawItemContent(Graphics g, Rectangle bounds, ShengListViewItem item)\n        {\n            string header = LayoutManager.GetItemText(item.Value);\n            if (String.IsNullOrEmpty(header))\n                return;\n\n            if (_headerHeightInited == false)\n            {\n                SizeF headerSize = g.MeasureString(header, Theme.ItemHeaderFont);\n                _headerHeight = (int)Math.Ceiling(headerSize.Height);\n\n                _headerHeightInited = true;\n            }\n\n            #region 绘制文本\n\n            _headerBounds = new Rectangle();\n            _headerBounds.X = _itemPadding.Width;\n            _headerBounds.Y = _itemPadding.Height;\n            _headerBounds.Width = bounds.Width;\n            _headerBounds.Height = _headerHeight;\n            _headerBounds.Offset(bounds.Location);\n\n            if (String.IsNullOrEmpty(header) == false)\n            {\n                using (SolidBrush brush = new SolidBrush(Theme.ItemHeaderColor))\n                {\n                    g.DrawString(header, Theme.ItemHeaderFont, brush, _headerBounds, _itemHeaderStringFormat);\n                }\n            }\n\n            #endregion\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengListView/Layout/ShengListViewTheme.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.ComponentModel;\nusing System.Drawing;\n\nnamespace Sheng.Winform.Controls\n{\n   public class ShengListViewTheme\n    {\n        private Font _itemHeaderFont = SystemFonts.DefaultFont;\n        public Font ItemHeaderFont\n        {\n            get { return _itemHeaderFont; }\n            set { _itemHeaderFont = value; }\n        }\n\n        private Color _itemHeaderColor = SystemColors.WindowText;\n        public Color ItemHeaderColor\n        {\n            get { return _itemHeaderColor; }\n            set { _itemHeaderColor = value; }\n        }\n\n        private Color _itemDescriptioniColor = SystemColors.GrayText;\n        public Color ItemDescriptioniColor\n        {\n            get { return _itemDescriptioniColor; }\n            set { _itemDescriptioniColor = value; }\n        }\n\n        private Color _itemBackColor = SystemColors.Window;\n        /// <summary>\n        /// 项的背景色\n        /// </summary>\n        public Color ItemBackColor\n        {\n            get { return _itemBackColor; }\n            set { _itemBackColor = value; }\n        }\n\n        private Color _backColor = SystemColors.Window;\n        /// <summary>\n        /// 控件背景色\n        /// </summary>\n        public Color BackColor\n        {\n            get { return _backColor; }\n            set { _backColor = value; }\n        }\n\n        private Color _itemBorderColor = Color.FromArgb(64, SystemColors.GrayText);\n        /// <summary>\n        /// 项的边框色\n        /// </summary>\n        public Color ItemBorderColor\n        {\n            get { return _itemBorderColor; }\n            set { _itemBorderColor = value; }\n        }\n\n        private Color _selectionRectangleColor = Color.FromArgb(128, SystemColors.Highlight);\n        /// <summary>\n        /// 选择框颜色\n        /// </summary>\n        public Color SelectionRectangleColor\n        {\n            get { return _selectionRectangleColor; }\n            set { _selectionRectangleColor = value; }\n        }\n\n        private Color _selectionRectangleBorderColor = SystemColors.Highlight;\n        /// <summary>\n        /// 选择框的边框色\n        /// </summary>\n        public Color SelectionRectangleBorderColor\n        {\n            get { return _selectionRectangleBorderColor; }\n            set { _selectionRectangleBorderColor = value; }\n        }\n\n        private Color _selectedColorStart = Color.FromArgb(16, SystemColors.Highlight);\n        /// <summary>\n        /// 当控件具有焦点时选定项的背景色\n        /// </summary>\n        public Color SelectedColorStart\n        {\n            get { return _selectedColorStart; }\n            set { _selectedColorStart = value; }\n        }\n\n        private Color _selectedColorEnd = Color.FromArgb(128, SystemColors.Highlight);\n        public Color SelectedColorEnd\n        {\n            get { return _selectedColorEnd; }\n            set { _selectedColorEnd = value; }\n        }\n\n        private Color _unFocusedColorStart = Color.FromArgb(16, SystemColors.GrayText);\n        /// <summary>\n        /// 控件失去焦点时选定项的背景色\n        /// </summary>\n        public Color UnFocusedColorStart\n        {\n            get { return _unFocusedColorStart; }\n            set { _unFocusedColorStart = value; }\n        }\n\n        private Color _unFocusedColorEnd = Color.FromArgb(64, SystemColors.GrayText);\n        public Color UnFocusedColorEnd\n        {\n            get { return _unFocusedColorEnd; }\n            set { _unFocusedColorEnd = value; }\n        }\n\n        private Color _hoverColorStart = Color.FromArgb(8, SystemColors.Highlight);\n        /// <summary>\n        /// 热点项的背景色\n        /// </summary>\n        public Color HoverColorStart\n        {\n            get { return _hoverColorStart; }\n            set { _hoverColorStart = value; }\n        }\n\n        private Color _hoverColorEnd = Color.FromArgb(64, SystemColors.Highlight);\n        public Color HoverColorEnd\n        {\n            get { return _hoverColorEnd; }\n            set { _hoverColorEnd = value; }\n        }\n\n        private Color _imageInnerBorderColor = Color.FromArgb(128, Color.White);\n        /// <summary>\n        /// 图像内边框颜色\n        /// </summary>\n        public Color ImageInnerBorderColor\n        {\n            get { return _imageInnerBorderColor; }\n            set { _imageInnerBorderColor = value; }\n        }\n\n        private Color _imageOuterBorderColor = Color.FromArgb(128, Color.Gray);\n        /// <summary>\n        /// 图像外边框颜色\n        /// </summary>\n        public Color ImageOuterBorderColor\n        {\n            get { return _imageOuterBorderColor; }\n            set { _imageOuterBorderColor = value; }\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengListView/ShengListView.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Windows.Forms.VisualStyles;\nusing System.Drawing;\nusing System.Diagnostics;\nusing System.Reflection;\nusing Sheng.Winform.Controls.Kernal;\nusing System.Collections;\n\nnamespace Sheng.Winform.Controls\n{\n    public class ShengListView : Control\n    {\n        #region 常量\n\n        /// <summary>\n        /// Creates a control with a border.\n        /// </summary>\n        private const int WS_BORDER = 0x00800000;\n        /// <summary>\n        /// Specifies that the control has a border with a sunken edge.\n        /// </summary>\n        private const int WS_EX_CLIENTEDGE = 0x00000200;\n\n        #endregion\n\n        #region 私有成员\n\n        private bool _suspendLayout = false;\n        public bool Suspend\n        {\n            get { return _suspendLayout; }\n        }\n\n        /// <summary>\n        /// 是否需要在调用 ResumeLayout 时重绘\n        /// </summary>\n        private bool _needPaint = false;\n\n        private ShengListViewLayoutManager _layoutManager;\n\n        /// <summary>\n        /// 为项扩展的用于呈现的属性\n        /// </summary>\n        private Dictionary<string, string> _extendMember = new Dictionary<string, string>();\n\n        //ToolTip _toolTip = new ToolTip();\n\n        //private System.Timers.Timer lazyRefreshTimer;\n\n        #endregion\n\n        #region 公开属性\n\n        /// <summary>\n        /// Gets whether the shift key is down.\n        /// </summary>\n        internal bool ShiftKey { get; private set; }\n        /// <summary>\n        /// Gets whether the control key is down.\n        /// </summary>\n        internal bool ControlKey { get; private set; }\n\n        /// <summary>\n        /// 鼠标左键是否处于按下状态\n        /// </summary>\n        internal bool LeftButton { get; private set; }\n\n        /// <summary>\n        /// 鼠标右键是否处于按下状态\n        /// </summary>\n        internal bool RightButton { get; private set; }\n\n        internal bool AnyMouseButton\n        {\n            get { return LeftButton || RightButton; }\n        }\n\n        //debug public\n        /// <summary>\n        /// 鼠标最后点击的位置\n        /// </summary>\n        internal Point LastMouseDownLocation { get; private set; }\n\n        private ShengListViewItem _hoveredItem;\n        /// <summary>\n        /// 当前鼠标经过的项\n        /// </summary>\n        internal ShengListViewItem HoveredItem\n        {\n            get { return _hoveredItem; }\n            private set\n            {\n                ShengListViewItem oldHoveredItem = _hoveredItem;\n                ShengListViewItem newHoveredItem = value;\n\n                _hoveredItem = value;\n\n                if (oldHoveredItem != null && oldHoveredItem != newHoveredItem)\n                {\n                    oldHoveredItem.Hovered = false;\n                }\n\n                if (newHoveredItem != null)\n                    newHoveredItem.Hovered = true;\n\n                if (oldHoveredItem != newHoveredItem)\n                {\n                    NeedPaint();\n                }\n            }\n        }\n\n        private ShengListViewLayoutMode _layoutMode;\n        public ShengListViewLayoutMode LayoutMode\n        {\n            get { return _layoutMode; }\n            set\n            {\n                _layoutMode = value;\n                ShengListViewLayoutManager layoutManager;\n                switch (_layoutMode)\n                {\n                    case ShengListViewLayoutMode.Standard:\n                        layoutManager = new ShengListViewStandardLayoutManager(this);\n                        break;\n                    case ShengListViewLayoutMode.Descriptive:\n                        layoutManager = new ShengListViewDescriptiveLayoutManager(this);\n                        break;\n                    default:\n                        layoutManager = new ShengListViewLayoutManager(this);\n                        Debug.Assert(false, \"没这ListViewRenderer\");\n                        break;\n                }\n\n                SetLayoutManager(layoutManager);\n            }\n        }\n\n        private BorderStyle _borderStyle = BorderStyle.Fixed3D;\n        public BorderStyle BorderStyle\n        {\n            get { return _borderStyle; }\n            set { _borderStyle = value; }\n        }\n\n        private ShengListViewTheme _theme = new ShengListViewTheme();\n        /// <summary>\n        /// 配色方案\n        /// </summary>\n        public ShengListViewTheme Theme\n        {\n            get\n            {\n                return _theme;\n            }\n            set\n            {\n                _theme = value;\n                Refresh();\n            }\n        }\n\n        /// <summary>\n        /// 当前布局中项的高度\n        /// </summary>\n        public int ItemHeight\n        {\n            get { return _layoutManager.ItemHeightWithMargin; }\n        }\n\n        private bool _allowMultiSelection = false;\n        public bool AllowMultiSelection\n        {\n            get { return _allowMultiSelection; }\n            set { _allowMultiSelection = value; }\n        }\n\n        /// <summary>\n        /// 是否没有任何项\n        /// </summary>\n        public bool IsEmpty\n        {\n            get\n            {\n                return Items.Count == 0;\n            }\n        }\n\n        private ShengListViewItemCollection _items = new ShengListViewItemCollection();\n        public ShengListViewItemCollection Items\n        {\n            get { return _items; }\n            set { _items = value; }\n        }\n\n        /// <summary>\n        /// 获取当前具有输入焦点的项\n        /// </summary>\n        public ShengListViewItem FocusedItem\n        {\n            get\n            {\n                foreach (var item in _items)\n                {\n                    if (item.Focused)\n                        return item;\n                }\n\n                return null;\n            }\n        }\n\n        /// <summary>\n        /// 默认的用于呈现为项中文本的Property\n        /// </summary>\n        public string DisplayMember\n        {\n            get;\n            set;\n        }\n\n        #endregion\n\n        #region 构造\n\n        public ShengListView()\n        {\n            SetStyle(ControlStyles.ResizeRedraw, true);\n            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);\n            SetStyle(ControlStyles.Selectable, true);\n\n            this.Padding = new System.Windows.Forms.Padding(10);\n\n            _items.Owner = this;\n\n            //设置一个默认布局\n            this.LayoutMode = ShengListViewLayoutMode.Standard;\n\n            //_layoutManager = new ListViewLayoutManager(this);\n\n            //lazyRefreshTimer = new System.Timers.Timer();\n            //lazyRefreshTimer.Interval = 10;\n            //lazyRefreshTimer.Enabled = false;\n            //lazyRefreshTimer.Elapsed += lazyRefreshTimer_Tick;\n            //lazyRefreshCallback = new RefreshDelegateInternal(Refresh);\n        }\n\n        //delegate void RefreshDelegateInternal();\n        //private RefreshDelegateInternal lazyRefreshCallback;\n        //void lazyRefreshTimer_Tick(object sender, EventArgs e)\n        //{\n        //    if (IsHandleCreated && IsDisposed == false)\n        //        BeginInvoke(lazyRefreshCallback);\n        //    lazyRefreshTimer.Stop();\n        //}\n\n        #endregion\n\n        #region 方法\n\n        #region internal\n\n        /// <summary>\n        /// 更改了选择的项\n        /// </summary>\n        internal void OnSelectedItemChanged()\n        {\n            if (SelectedItemChanaged != null)\n            {\n                SelectedItemChanaged(this, new EventArgs());\n            }\n        }\n\n        /// <summary>\n        /// 双击项\n        /// </summary>\n        /// <param name=\"item\"></param>\n        internal void OnItemDoubleClick(ShengListViewItem item)\n        {\n            if (ItemDoubleClick != null)\n            {\n                ItemDoubleClick(this, new ShengListViewItemDoubleClickEventArgs(item));\n            }\n        }\n\n        internal void OnItemsRemoved(List<ShengListViewItem> items)\n        {\n            _layoutManager.OnItemsRemoved(items);\n\n            if (ItemsRemoved != null)\n            {\n                ItemsRemoved(this, new ShengListViewItemsRemovedEventArgs(items));\n            }\n        }\n\n        /// <summary>\n        /// 请求在下次调用 ResumeLayout 时重绘\n        /// </summary>\n        internal void NeedPaint()\n        {\n            _needPaint = true;\n        }\n\n        internal void RenderItem(ShengListViewItem item)\n        {\n            if (Suspend == false)\n            {\n                _layoutManager.RenderItem(this.CreateGraphics(), item);\n            }\n        }\n\n        internal object GetItemPropertyValue(object itemValue, string propertyName)\n        {\n            if (itemValue == null || String.IsNullOrEmpty(propertyName))\n            {\n                Debug.Assert(false, \"itemValue 或 propertyName 为空\");\n                throw new ArgumentNullException();\n            }\n\n            return ReflectionPool.GetPropertyValue(itemValue, propertyName);\n\n        }\n\n        internal string GetItemText(object itemValue)\n        {\n            Debug.Assert(itemValue != null, \"itemValue 为 null\");\n\n            if (itemValue == null)\n                return String.Empty;\n\n            if (ItemTextGetting != null)\n            {\n                ShengListViewGetItemTextEventArgs args = new ShengListViewGetItemTextEventArgs(itemValue);\n                ItemTextGetting(this, args);\n                if (String.IsNullOrEmpty(args.Text) == false)\n                    return args.Text;\n            }\n\n            if (String.IsNullOrEmpty(DisplayMember))\n            {\n                return itemValue.ToString();\n            }\n            else\n            {\n                return GetItemText(itemValue, DisplayMember);\n            }\n        }\n\n        internal string GetItemText(object itemValue, string propertyName)\n        {\n            Debug.Assert(itemValue != null && String.IsNullOrEmpty(propertyName) == false, \"itemValue 为 null\");\n\n            object text = GetItemPropertyValue(itemValue, propertyName);\n            if (text == null)\n                return String.Empty;\n            else\n                return text.ToString();\n        }\n\n        /// <summary>\n        /// 获取当前选中的所有项\n        /// </summary>\n        /// <returns></returns>\n        internal List<ShengListViewItem> GetSelectedItems()\n        {\n            List<ShengListViewItem> items = new List<ShengListViewItem>();\n\n            foreach (var item in _items)\n            {\n                if (item.Selected)\n                    items.Add(item);\n            }\n\n            return items;\n        }\n\n        #endregion\n\n        #region public\n\n        public void AddExtendMember(IShengListViewExtendMember member)\n        {\n            Dictionary<string, string> extendMembers = member.GetExtendMembers();\n            foreach (var item in extendMembers)\n            {\n                SetExtendMember(item.Key, item.Value);\n            }\n        }\n\n        /// <summary>\n        /// 设置扩展属性供特定LayoutEngine使用\n        /// 如果指定的 ExtendMember 已存在，覆盖之\n        /// 用String.Empty 或 null 做为 propertyName传入，表示删除指定的 member\n        /// </summary>\n        /// <param name=\"member\"></param>\n        /// <param name=\"propertyName\"></param>\n        public void SetExtendMember(string member, string propertyName)\n        {\n            if (String.IsNullOrEmpty(member))\n            {\n                Debug.Assert(false, \"member  为空\");\n                throw new ArgumentNullException();\n            }\n\n            if (String.IsNullOrEmpty(propertyName))\n            {\n                _extendMember.Remove(member);\n            }\n            else\n            {\n                if (_extendMember.Keys.Contains(member))\n                {\n                    _extendMember[member] = propertyName;\n                }\n                else\n                {\n                    _extendMember.Add(member, propertyName);\n                }\n            }\n        }\n\n        public bool ContainerExtendMember(string member)\n        {\n            if (String.IsNullOrEmpty(member) )\n            {\n                Debug.Assert(false, \"member  为空\");\n                throw new ArgumentNullException();\n            }\n\n            return _extendMember.Keys.Contains(member);\n        }\n\n        public string GetExtendMember(string member)\n        {\n            if (ContainerExtendMember(member) == false)\n            {\n                Debug.Assert(false, \"指定的 member 不存在\" + member);\n                throw new ArgumentOutOfRangeException();\n            }\n\n            return _extendMember[member];\n        }\n\n        /// <summary>\n        /// 恢复正常的布局逻辑。\n        /// </summary>\n        public new void ResumeLayout()\n        {\n            _suspendLayout = false;\n\n            if (_needPaint)\n            {\n                this.Refresh();\n                _needPaint = false;\n            }\n\n            base.ResumeLayout();\n        }\n\n        public new void ResumeLayout(bool refreshNow)\n        {\n            _suspendLayout = false;\n\n            if (refreshNow)\n            {\n                this.Refresh();\n                _needPaint = false;\n            }\n            else\n            {\n                ResumeLayout();\n            }\n\n            base.ResumeLayout(refreshNow);\n        }\n\n        /// <summary>\n        /// 临时挂起控件的布局逻辑。\n        /// </summary>\n        public new void SuspendLayout()\n        {\n            _suspendLayout = true;\n\n            base.SuspendLayout();\n        }\n\n        public override void Refresh()\n        {\n            if (_suspendLayout)\n                return;\n\n            base.Refresh();\n        }\n\n        /// <summary>\n        /// 获取当前选中项所绑定的对象\n        /// 如果没有选中项，返回null，如果选中多项，返回选中项集合中的第一个\n        /// </summary>\n        /// <returns></returns>\n        public object GetSelectedValue()\n        {\n            List<ShengListViewItem> selectedItems = GetSelectedItems();\n            if (selectedItems.Count == 0)\n                return null;\n\n            return selectedItems[0].Value;\n        }\n\n        /// <summary>\n        /// 根据指定的绑定项对象\n        /// 设置当前列表中选定的项\n        /// </summary>\n        /// <param name=\"obj\"></param>\n        public void SetSelectedValue(object obj)\n        {\n            if (obj == null)\n            {\n                ClearSelect();\n                return;\n            }\n\n            var items = (from item in _items where item.Value == obj select item).ToList();\n            if (items.Count == 0)\n            {\n                Debug.Assert(false, \"没有指定的项\");\n                return;\n            }\n\n            var oldSelectedItems = GetSelectedItems();\n\n            //这里为什么用foreach\n            //考虑到多个项绑定到同一个对象的情况，不过理论上讲不应该出现这种情况\n            SuspendLayout();\n            ClearSelect();\n            foreach (var item in items)\n            {\n                item.Selected = true;\n            }\n            ResumeLayout();\n\n            if (items.SequenceEqual(oldSelectedItems) == false)\n                OnSelectedItemChanged();\n        }\n\n        /// <summary>\n        /// 获取当前选中的所有项的绑定对象集合\n        /// 如果当前没有选中任何项，返回空集合\n        /// </summary>\n        /// <returns></returns>\n        public List<object> GetSelectedValues()\n        {\n            List<object> selectedValues = new List<object>();\n\n            List<ShengListViewItem> selectedItems = GetSelectedItems();\n\n            foreach (var item in selectedItems)\n            {\n                selectedValues.Add(item.Value);\n            }\n\n            return selectedValues;\n        }\n\n        /// <summary>\n        /// 取消所有项的选择\n        /// </summary>\n        public void ClearSelect()\n        {\n            bool suspend = false;\n            if (this.Suspend == false)\n            {\n                this.SuspendLayout();\n                suspend = true;\n            }\n\n            foreach (var selectedItem in GetSelectedItems())\n            {\n                selectedItem.Selected = false;\n            }\n\n            if (suspend)\n                this.ResumeLayout();\n        }\n\n        public void DataBind(IList list)\n        {\n            if (list == null)\n            {\n                Debug.Assert(false, \"list 为 null\");\n                throw new ArgumentNullException();\n            }\n\n            SuspendLayout();\n            Items.Clear();\n            foreach (var item in list)\n            {\n                this.Items.Add(new ShengListViewItem(item));\n            }\n            ResumeLayout();\n        }\n\n        public void Clear()\n        {\n            SuspendLayout();\n            Items.Clear();\n            ResumeLayout();\n        }\n\n        #endregion\n\n        #region private\n\n        private void Hover(Point location)\n        {\n            ShengListViewHitInfo hitInfo = _layoutManager.HitTest(location);\n            if (hitInfo.ItemHit)\n            {\n                HoveredItem = Items[hitInfo.ItemIndex];\n            }\n            else\n            {\n                HoveredItem = null;\n            }\n        }\n\n        private void SetLayoutManager(ShengListViewLayoutManager layoutManager)\n        {\n            if (_layoutManager == layoutManager)\n                return;\n\n            if (_layoutManager != null)\n                _layoutManager.Dispose();\n\n            _layoutManager = layoutManager;\n\n            Refresh();\n        }\n\n        #endregion\n\n        #region protected\n\n        /// <summary>\n        /// 获取创建控件句柄时所需要的创建参数\n        /// </summary>\n        protected override CreateParams CreateParams\n        {\n            get\n            {\n                //设置控件的边框样式\n                CreateParams p = base.CreateParams;\n                p.Style &= ~WS_BORDER;\n                p.ExStyle &= ~WS_EX_CLIENTEDGE;\n                if (_borderStyle == BorderStyle.Fixed3D)\n                    p.ExStyle |= WS_EX_CLIENTEDGE;\n                else if (_borderStyle == BorderStyle.FixedSingle)\n                    p.Style |= WS_BORDER;\n                return p;\n            }\n        }\n\n        protected override void OnResize(EventArgs e)\n        {\n            base.OnResize(e);\n\n            //_layoutManager.Update();\n        }\n\n        #region Mouse\n\n        protected override void OnMouseDown(MouseEventArgs e)\n        {\n            SuspendLayout();\n\n            if (Focused == false)\n                Focus();\n\n            LeftButton = (e.Button & MouseButtons.Left) == MouseButtons.Left;\n            RightButton = (e.Button & MouseButtons.Right) == MouseButtons.Right;\n\n            LastMouseDownLocation = e.Location;\n\n            _layoutManager.MouseDown(e);\n\n            ResumeLayout();\n\n            base.OnMouseDown(e);\n        }\n\n        protected override void OnMouseUp(MouseEventArgs e)\n        {\n            if ((e.Button & MouseButtons.Left) == MouseButtons.Left)\n                LeftButton = false;\n            if ((e.Button & MouseButtons.Right) == MouseButtons.Right)\n                RightButton = false;\n\n            SuspendLayout();\n\n            _layoutManager.MouseUp(e);\n\n            ResumeLayout();\n\n            //显示上下文菜单\n            bool rightButton = (e.Button & MouseButtons.Right) == MouseButtons.Right;\n            if (rightButton && this.ContextMenuStrip != null)\n            {\n                this.ContextMenuStrip.Show(this.PointToScreen(e.Location));\n            }\n\n            base.OnMouseUp(e);\n        }\n\n        protected override void OnMouseMove(MouseEventArgs e)\n        {\n          //  if (_toolTip.Active)\n            //    _toolTip.Hide(this);\n\n            SuspendLayout();\n\n            //如果处于框选状态，不处理Hover\n            if (_layoutManager.MouseSelecting == false)\n            {\n                Hover(e.Location);\n            }\n\n            _layoutManager.MouseMove(e);\n\n            ResumeLayout();\n\n            base.OnMouseMove(e);\n        }\n\n        protected override void OnMouseWheel(MouseEventArgs e)\n        {\n            SuspendLayout();\n\n            _layoutManager.OnMouseWheel(e);\n\n            Hover(e.Location);\n\n            NeedPaint();\n            ResumeLayout();\n\n            base.OnMouseWheel(e);\n        }\n\n        protected override void OnMouseDoubleClick(MouseEventArgs e)\n        {\n            if (ItemDoubleClick != null)\n            {\n                ShengListViewHitInfo hitInfo = _layoutManager.HitTest(e.Location);\n                if (hitInfo.ItemHit)\n                {\n                    ShengListViewItem  item = Items[hitInfo.ItemIndex];\n                    OnItemDoubleClick(item);\n                }\n            }\n\n            base.OnMouseDoubleClick(e);\n        }\n\n        protected override void OnMouseHover(EventArgs e)\n        {\n            //Point toolTipPoint = this.PointToClient(Cursor.Position);\n            //_toolTip.Show(\"ff\", this, toolTipPoint);\n\n            base.OnMouseHover(e);\n        }\n\n        #endregion\n\n        #region Key\n\n        protected override bool IsInputKey(Keys keyData)\n        {\n            if ((keyData & Keys.Left) == Keys.Left ||\n               (keyData & Keys.Right) == Keys.Right ||\n               (keyData & Keys.Up) == Keys.Up ||\n               (keyData & Keys.Down) == Keys.Down)\n                return true;\n            else\n                return base.IsInputKey(keyData);\n        }\n\n        protected override void OnKeyDown(KeyEventArgs e)\n        {\n            ShiftKey = (e.Modifiers & Keys.Shift) == Keys.Shift;\n            ControlKey = (e.Modifiers & Keys.Control) == Keys.Control;\n\n            _layoutManager.OnKeyDown(e);\n\n            base.OnKeyDown(e);\n        }\n\n        protected override void OnKeyUp(KeyEventArgs e)\n        {\n            ShiftKey = (e.Modifiers & Keys.Shift) == Keys.Shift;\n            ControlKey = (e.Modifiers & Keys.Control) == Keys.Control;\n\n            _layoutManager.OnKeyUp(e);\n\n            base.OnKeyUp(e);\n        }\n\n        #endregion\n\n        #region Focus\n\n        protected override void OnGotFocus(EventArgs e)\n        {\n            base.OnGotFocus(e);\n            Refresh();\n        }\n\n        protected override void OnLostFocus(EventArgs e)\n        {\n            base.OnLostFocus(e);\n            Refresh();\n        }\n\n        #endregion\n\n        #region Paint\n\n        protected override void OnPaint(PaintEventArgs e)\n        {\n            if (_layoutManager != null)\n            {\n                _layoutManager.Render(e.Graphics);\n            }\n\n            //Size size1 = new Size(100, 100);\n            //Size size2 = new Size(50, 50);\n            //e.Graphics.DrawRectangle(Pens.Black, new Rectangle(new Point(10, 10), size1));\n            //size1 = Size.Add(size1, size2);\n            //e.Graphics.DrawRectangle(Pens.Red, new Rectangle(new Point(10, 10), size1));\n        }\n\n        #endregion\n\n        protected override void Dispose(bool disposing)\n        {\n            base.Dispose(disposing);\n        }\n\n        #endregion\n\n        #endregion\n\n        #region 事件\n\n        /// <summary>\n        /// 更改了选择的项\n        /// </summary>\n        public event EventHandler SelectedItemChanaged;\n\n        /// <summary>\n        /// 双击项\n        /// </summary>\n        public event EventHandler<ShengListViewItemDoubleClickEventArgs> ItemDoubleClick;\n\n        /// <summary>\n        /// 项被删除\n        /// </summary>\n        public event EventHandler<ShengListViewItemsRemovedEventArgs> ItemsRemoved;\n\n        /// <summary>\n        /// 通过外能事件获取用于绘制项的文本\n        /// </summary>\n        public event EventHandler<ShengListViewGetItemTextEventArgs> ItemTextGetting;\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengListView/ShengListViewColor.cs",
    "content": "using System.ComponentModel;\nusing System.Drawing;\nusing System;\nusing System.Reflection;\nusing System.Collections.Generic;\n\nnamespace Sheng.Winform.Controls\n{\n    /// <summary>\n    /// Represents the color palette of the image list view.\n    /// </summary>\n    public class ShengListViewColor\n    {\n        #region Member Variables\n        // control background color\n        Color mControlBackColor;\n\n        // item colors\n        Color mBackColor;\n        Color mBorderColor;\n        Color mUnFocusedColor1;\n        Color mUnFocusedColor2;\n        Color mUnFocusedBorderColor;\n        Color mUnFocusedForeColor;\n        Color mForeColor;\n        Color mHoverColor1;\n        Color mHoverColor2;\n        Color mHoverBorderColor;\n        Color mInsertionCaretColor;\n        Color mSelectedColor1;\n        Color mSelectedColor2;\n        Color mSelectedBorderColor;\n        Color mSelectedForeColor;\n\n        // thumbnail & pane\n        Color mImageInnerBorderColor;\n        Color mImageOuterBorderColor;\n\n        // details view\n        Color mCellForeColor;\n        Color mColumnHeaderBackColor1;\n        Color mColumnHeaderBackColor2;\n        Color mColumnHeaderForeColor;\n        Color mColumnHeaderHoverColor1;\n        Color mColumnHeaderHoverColor2;\n        Color mColumnSelectColor;\n        Color mColumnSeparatorColor;\n        Color mAlternateBackColor;\n        Color mAlternateCellForeColor;\n\n        // pane\n        Color mPaneBackColor;\n        Color mPaneSeparatorColor;\n        Color mPaneLabelColor;\n\n        // selection rectangle\n        Color mSelectionRectangleColor1;\n        Color mSelectionRectangleColor2;\n        Color mSelectionRectangleBorderColor;\n        #endregion\n\n        #region Properties\n        /// <summary>\n        /// Gets or sets the background color of the ImageListView control.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the background color of the ImageListView control.\")]\n        [DefaultValue(typeof(Color), \"Window\")]\n        public Color ControlBackColor\n        {\n            get { return mControlBackColor; }\n            set { mControlBackColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the background color of the ImageListViewItem.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the background color of the ImageListViewItem.\")]\n        [DefaultValue(typeof(Color), \"Window\")]\n        public Color BackColor\n        {\n            get { return mBackColor; }\n            set { mBackColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the background color of alternating cells in Details View.\n        /// </summary>\n        [Category(\"Appearance Details View\"), Description(\"Gets or sets the background color of alternating cells in Details View.\")]\n        [DefaultValue(typeof(Color), \"Window\")]\n        public Color AlternateBackColor\n        {\n            get { return mAlternateBackColor; }\n            set { mAlternateBackColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the border color of the ImageListViewItem.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the border color of the ImageListViewItem.\")]\n        [DefaultValue(typeof(Color), \"64, 128, 128, 128\")]\n        public Color BorderColor\n        {\n            get { return mBorderColor; }\n            set { mBorderColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the foreground color of the ImageListViewItem.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the foreground color of the ImageListViewItem.\")]\n        [DefaultValue(typeof(Color), \"ControlText\")]\n        public Color ForeColor\n        {\n            get { return mForeColor; }\n            set { mForeColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the background gradient color1 of the ImageListViewItem if the control is not focused.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the background gradient color1 of the ImageListViewItem if the control is not focused.\")]\n        [DefaultValue(typeof(Color), \"16, 128, 128, 128\")]\n        public Color UnFocusedColor1\n        {\n            get { return mUnFocusedColor1; }\n            set { mUnFocusedColor1 = value; }\n        }\n        /// <summary>\n        /// Gets or sets the background gradient color2 of the ImageListViewItem if the control is not focused.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the background gradient color2 of the ImageListViewItem if the control is not focused.\")]\n        [DefaultValue(typeof(Color), \"64, 128, 128, 128\")]\n        public Color UnFocusedColor2\n        {\n            get { return mUnFocusedColor2; }\n            set { mUnFocusedColor2 = value; }\n        }\n        /// <summary>\n        /// Gets or sets the border color of the ImageListViewItem if the control is not focused.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the border color of the ImageListViewItem if the control is not focused.\")]\n        [DefaultValue(typeof(Color), \"128, 128, 128, 128\")]\n        public Color UnFocusedBorderColor\n        {\n            get { return mUnFocusedBorderColor; }\n            set { mUnFocusedBorderColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the fore color of the ImageListViewItem if the control is not focused.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the fore color of the ImageListViewItem if the control is not focused.\")]\n        [DefaultValue(typeof(Color), \"ControlText\")]\n        public Color UnFocusedForeColor\n        {\n            get { return mUnFocusedForeColor; }\n            set { mUnFocusedForeColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the background gradient color1 if the ImageListViewItem is hovered.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the background gradient color1 if the ImageListViewItem is hovered.\")]\n        [DefaultValue(typeof(Color), \"8, 10, 36, 106\")]\n        public Color HoverColor1\n        {\n            get { return mHoverColor1; }\n            set { mHoverColor1 = value; }\n        }\n        /// <summary>\n        /// Gets or sets the background gradient color2 if the ImageListViewItem is hovered.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the background gradient color2 if the ImageListViewItem is hovered.\")]\n        [DefaultValue(typeof(Color), \"64, 10, 36, 106\")]\n        public Color HoverColor2\n        {\n            get { return mHoverColor2; }\n            set { mHoverColor2 = value; }\n        }\n        /// <summary>\n        /// Gets or sets the border color of the ImageListViewItem if the item is hovered.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the border color of the ImageListViewItem if the item is hovered.\")]\n        [DefaultValue(typeof(Color), \"64, 10, 36, 106\")]\n        public Color HoverBorderColor\n        {\n            get { return mHoverBorderColor; }\n            set { mHoverBorderColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the color of the insertion caret.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the color of the insertion caret.\")]\n        [DefaultValue(typeof(Color), \"Highlight\")]\n        public Color InsertionCaretColor\n        {\n            get { return mInsertionCaretColor; }\n            set { mInsertionCaretColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the background gradient color1 if the ImageListViewItem is selected.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the background gradient color1 if the ImageListViewItem is selected.\")]\n        [DefaultValue(typeof(Color), \"16, 10, 36, 106\")]\n        public Color SelectedColor1\n        {\n            get { return mSelectedColor1; }\n            set { mSelectedColor1 = value; }\n        }\n        /// <summary>\n        /// Gets or sets the background gradient color2 if the ImageListViewItem is selected.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the background gradient color2 if the ImageListViewItem is selected.\")]\n        [DefaultValue(typeof(Color), \"128, 10, 36, 106\")]\n        public Color SelectedColor2\n        {\n            get { return mSelectedColor2; }\n            set { mSelectedColor2 = value; }\n        }\n        /// <summary>\n        /// Gets or sets the border color of the ImageListViewItem if the item is selected.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the border color of the ImageListViewItem if the item is selected.\")]\n        [DefaultValue(typeof(Color), \"128, 10, 36, 106\")]\n        public Color SelectedBorderColor\n        {\n            get { return mSelectedBorderColor; }\n            set { mSelectedBorderColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the fore color of the ImageListViewItem if the item is selected.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the fore color of the ImageListViewItem if the item is selected.\")]\n        [DefaultValue(typeof(Color), \"ControlText\")]\n        public Color SelectedForeColor\n        {\n            get { return mSelectedForeColor; }\n            set { mSelectedForeColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the background gradient color1 of the column header.\n        /// </summary>\n        [Category(\"Appearance Details View\"), Description(\"Gets or sets the cells background color1 of the column header.\")]\n        [DefaultValue(typeof(Color), \"32, 212, 208, 200\")]\n        public Color ColumnHeaderBackColor1\n        {\n            get { return mColumnHeaderBackColor1; }\n            set { mColumnHeaderBackColor1 = value; }\n        }\n        /// <summary>\n        /// Gets or sets the background gradient color2 of the column header.\n        /// </summary>\n        [Category(\"Appearance Details View\"), Description(\"Gets or sets the cells background color2 of the column header.\")]\n        [DefaultValue(typeof(Color), \"196, 212, 208, 200\")]\n        public Color ColumnHeaderBackColor2\n        {\n            get { return mColumnHeaderBackColor2; }\n            set { mColumnHeaderBackColor2 = value; }\n        }\n        /// <summary>\n        /// Gets or sets the background hover gradient color1 of the column header.\n        /// </summary>\n        [Category(\"Appearance Details View\"), Description(\"Gets or sets the background hover color1 of the column header.\")]\n        [DefaultValue(typeof(Color), \"16, 10, 36, 106\")]\n        public Color ColumnHeaderHoverColor1\n        {\n            get { return mColumnHeaderHoverColor1; }\n            set { mColumnHeaderHoverColor1 = value; }\n        }\n        /// <summary>\n        /// Gets or sets the background hover gradient color2 of the column header.\n        /// </summary>\n        [Category(\"Appearance Details View\"), Description(\"Gets or sets the background hover color2 of the column header.\")]\n        [DefaultValue(typeof(Color), \"64, 10, 36, 106\")]\n        public Color ColumnHeaderHoverColor2\n        {\n            get { return mColumnHeaderHoverColor2; }\n            set { mColumnHeaderHoverColor2 = value; }\n        }\n        /// <summary>\n        /// Gets or sets the cells foreground color of the column header text.\n        /// </summary>\n        [Category(\"Appearance Details View\"), Description(\"Gets or sets the cells foreground color of the column header text.\")]\n        [DefaultValue(typeof(Color), \"WindowText\")]\n        public Color ColumnHeaderForeColor\n        {\n            get { return mColumnHeaderForeColor; }\n            set { mColumnHeaderForeColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the cells background color if column is selected in Details View.\n        /// </summary>\n        [Category(\"Appearance Details View\"), Description(\"Gets or sets the cells background color if column is selected in Details View.\")]\n        [DefaultValue(typeof(Color), \"16, 128, 128, 128\")]\n        public Color ColumnSelectColor\n        {\n            get { return mColumnSelectColor; }\n            set { mColumnSelectColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the color of the separator in Details View.\n        /// </summary>\n        [Category(\"Appearance Details View\"), Description(\"Gets or sets the color of the separator in Details View.\")]\n        [DefaultValue(typeof(Color), \"32, 128, 128, 128\")]\n        public Color ColumnSeparatorColor\n        {\n            get { return mColumnSeparatorColor; }\n            set { mColumnSeparatorColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the foreground color of the cell text in Details View.\n        /// </summary>\n        [Category(\"Appearance Details View\"), Description(\"Gets or sets the foreground color of the cell text in Details View.\")]\n        [DefaultValue(typeof(Color), \"ControlText\")]\n        public Color CellForeColor\n        {\n            get { return mCellForeColor; }\n            set { mCellForeColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the foreground color of alternating cells text in Details View.\n        /// </summary>\n        [Category(\"Appearance Details View\"), Description(\"Gets or sets the foreground color of alternating cells text in Details View.\")]\n        [DefaultValue(typeof(Color), \"ControlText\")]\n        public Color AlternateCellForeColor\n        {\n            get { return mAlternateCellForeColor; }\n            set { mAlternateCellForeColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the background color of the image pane.\n        /// </summary>\n        [Category(\"Appearance Pane View\"), Description(\"Gets or sets the background color of the image pane.\")]\n        [DefaultValue(typeof(Color), \"16, 128, 128, 128\")]\n        public Color PaneBackColor\n        {\n            get { return mPaneBackColor; }\n            set { mPaneBackColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the separator line color between image pane and thumbnail view.\n        /// </summary>\n        [Category(\"Appearance Pane View\"), Description(\"Gets or sets the separator line color between image pane and thumbnail view.\")]\n        [DefaultValue(typeof(Color), \"128, 128, 128, 128\")]\n        public Color PaneSeparatorColor\n        {\n            get { return mPaneSeparatorColor; }\n            set { mPaneSeparatorColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the color of labels in pane view.\n        /// </summary>\n        [Category(\"Appearance Pane View\"), Description(\"Gets or sets the color of labels in pane view.\")]\n        [DefaultValue(typeof(Color), \"196, 0, 0, 0\")]\n        public Color PaneLabelColor\n        {\n            get { return mPaneLabelColor; }\n            set { mPaneLabelColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the image inner border color for thumbnails and pane.\n        /// </summary>\n        [Category(\"Appearance Image\"), Description(\"Gets or sets the image inner border color for thumbnails and pane.\")]\n        [DefaultValue(typeof(Color), \"128, 255, 255, 255\")]\n        public Color ImageInnerBorderColor\n        {\n            get { return mImageInnerBorderColor; }\n            set { mImageInnerBorderColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the image outer border color for thumbnails and pane.\n        /// </summary>\n        [Category(\"Appearance Image\"), Description(\"Gets or sets the image outer border color for thumbnails and pane.\")]\n        [DefaultValue(typeof(Color), \"128, 128, 128, 128\")]\n        public Color ImageOuterBorderColor\n        {\n            get { return mImageOuterBorderColor; }\n            set { mImageOuterBorderColor = value; }\n        }\n        /// <summary>\n        /// Gets or sets the background color1 of the selection rectangle.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the background color1 of the selection rectangle.\")]\n        [DefaultValue(typeof(Color), \"128, 10, 36, 106\")]\n        public Color SelectionRectangleColor1\n        {\n            get { return mSelectionRectangleColor1; }\n            set { mSelectionRectangleColor1 = value; }\n        }\n        /// <summary>\n        /// Gets or sets the background color2 of the selection rectangle.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the background color2 of the selection rectangle.\")]\n        [DefaultValue(typeof(Color), \"128, 10, 36, 106\")]\n        public Color SelectionRectangleColor2\n        {\n            get { return mSelectionRectangleColor2; }\n            set { mSelectionRectangleColor2 = value; }\n        }\n        /// <summary>\n        /// Gets or sets the color of the selection rectangle border.\n        /// </summary>\n        [Category(\"Appearance\"), Description(\"Gets or sets the color of the selection rectangle border.\")]\n        [DefaultValue(typeof(Color), \"Highlight\")]\n        public Color SelectionRectangleBorderColor\n        {\n            get { return mSelectionRectangleBorderColor; }\n            set { mSelectionRectangleBorderColor = value; }\n        }\n        #endregion\n\n        #region Constructors\n        /// <summary>\n        /// Initializes a new instance of the ImageListViewColor class.\n        /// </summary>\n        public ShengListViewColor()\n        {\n            // control\n            mControlBackColor = SystemColors.Window;\n\n            // item\n            mBackColor = SystemColors.Window;\n            mForeColor = SystemColors.ControlText;\n\n            mBorderColor = Color.FromArgb(64, SystemColors.GrayText);\n\n            mUnFocusedColor1 = Color.FromArgb(16, SystemColors.GrayText);\n            mUnFocusedColor2 = Color.FromArgb(64, SystemColors.GrayText);\n            mUnFocusedBorderColor = Color.FromArgb(128, SystemColors.GrayText);\n            mUnFocusedForeColor = SystemColors.ControlText;\n\n            mHoverColor1 = Color.FromArgb(8, SystemColors.Highlight);\n            mHoverColor2 = Color.FromArgb(64, SystemColors.Highlight);\n            mHoverBorderColor = Color.FromArgb(64, SystemColors.Highlight);\n\n            mSelectedColor1 = Color.FromArgb(16, SystemColors.Highlight);\n            mSelectedColor2 = Color.FromArgb(128, SystemColors.Highlight);\n            mSelectedBorderColor = Color.FromArgb(128, SystemColors.Highlight);\n            mSelectedForeColor = SystemColors.ControlText;\n\n            mInsertionCaretColor = SystemColors.Highlight;\n\n            // thumbnails\n            mImageInnerBorderColor = Color.FromArgb(128, Color.White);\n            mImageOuterBorderColor = Color.FromArgb(128, Color.Gray);\n\n            // details view\n            mColumnHeaderBackColor1 = Color.FromArgb(32, SystemColors.Control);\n            mColumnHeaderBackColor2 = Color.FromArgb(196, SystemColors.Control);\n            mColumnHeaderHoverColor1 = Color.FromArgb(16, SystemColors.Highlight);\n            mColumnHeaderHoverColor2 = Color.FromArgb(64, SystemColors.Highlight);\n            mColumnHeaderForeColor = SystemColors.WindowText;\n            mColumnSelectColor = Color.FromArgb(16, SystemColors.GrayText);\n            mColumnSeparatorColor = Color.FromArgb(32, SystemColors.GrayText);\n            mCellForeColor = SystemColors.ControlText;\n            mAlternateBackColor = SystemColors.Window;\n            mAlternateCellForeColor = SystemColors.ControlText;\n\n            // image pane\n            mPaneBackColor = Color.FromArgb(16, SystemColors.GrayText);\n            mPaneSeparatorColor = Color.FromArgb(128, SystemColors.GrayText);\n            mPaneLabelColor = Color.FromArgb(196, Color.Black);\n\n            // selection rectangle\n            mSelectionRectangleColor1 = Color.FromArgb(128, SystemColors.Highlight);\n            mSelectionRectangleColor2 = Color.FromArgb(128, SystemColors.Highlight);\n            mSelectionRectangleBorderColor = SystemColors.Highlight;\n        }\n\n        /// <summary>\n        /// Initializes a new instance of the ImageListViewColor class\n        /// from its string representation.\n        /// </summary>\n        /// <param name=\"definition\">String representation of the object.</param>\n        public ShengListViewColor(string definition)\n            : this()\n        {\n            try\n            {\n                // First check if the color matches a predefined color setting\n                foreach (MemberInfo info in typeof(ShengListViewColor).GetMembers(BindingFlags.Static | BindingFlags.Public))\n                {\n                    if (info.MemberType == MemberTypes.Property)\n                    {\n                        PropertyInfo propertyInfo = (PropertyInfo)info;\n                        if (propertyInfo.PropertyType == typeof(ShengListViewColor))\n                        {\n                            // If the color setting is equal to a preset value\n                            // return the preset\n                            if (definition == string.Format(\"({0})\", propertyInfo.Name) ||\n                                definition == propertyInfo.Name)\n                            {\n                                ShengListViewColor presetValue = (ShengListViewColor)propertyInfo.GetValue(null, null);\n                                CopyFrom(presetValue);\n                                return;\n                            }\n                        }\n                    }\n                }\n\n                // Convert color values\n                foreach (string line in definition.Split(new string[] { \";\" }, StringSplitOptions.RemoveEmptyEntries))\n                {\n                    // Read the color setting\n                    string[] pair = line.Split(new string[] { \"=\" }, StringSplitOptions.RemoveEmptyEntries);\n                    string name = pair[0].Trim();\n                    Color color = Color.FromName(pair[1].Trim());\n                    // Set the property value\n                    PropertyInfo property = typeof(ShengListViewColor).GetProperty(name);\n                    property.SetValue(this, color, null);\n                }\n            }\n            catch\n            {\n                throw new ArgumentException(\"Invalid string format\", \"definition\");\n            }\n        }\n        #endregion\n\n        #region InstanceMethods\n        /// <summary>\n        /// Copies color values from the given object.\n        /// </summary>\n        /// <param name=\"source\">The source object.</param>\n        public void CopyFrom(ShengListViewColor source)\n        {\n            foreach (PropertyInfo info in typeof(ShengListViewColor).GetProperties())\n            {\n                // Walk through color properties\n                if (info.PropertyType == typeof(Color))\n                {\n                    Color color = (Color)info.GetValue(source, null);\n                    info.SetValue(this, color, null);\n                }\n            }\n        }\n        #endregion\n\n        #region Static Members\n        /// <summary>\n        /// Represents the default color theme.\n        /// </summary>\n        public static ShengListViewColor Default { get { return ShengListViewColor.GetDefaultTheme(); } }\n        /// <summary>\n        /// Represents the noir color theme.\n        /// </summary>\n        public static ShengListViewColor Noir { get { return ShengListViewColor.GetNoirTheme(); } }\n        /// <summary>\n        /// Represents the mandarin color theme.\n        /// </summary>\n        public static ShengListViewColor Mandarin { get { return ShengListViewColor.GetMandarinTheme(); } }\n\n        /// <summary>\n        /// Sets the color palette to default colors.\n        /// </summary>\n        private static ShengListViewColor GetDefaultTheme()\n        {\n            return new ShengListViewColor();\n        }\n        /// <summary>\n        /// Sets the color palette to mandarin colors.\n        /// </summary>\n        private static ShengListViewColor GetMandarinTheme()\n        {\n            ShengListViewColor c = new ShengListViewColor();\n\n            // control\n            c.ControlBackColor = Color.White;\n\n            // item\n            c.BackColor = Color.White;\n            c.ForeColor = Color.FromArgb(60, 60, 60);\n            c.BorderColor = Color.FromArgb(187, 190, 183);\n\n            c.UnFocusedColor1 = Color.FromArgb(235, 235, 235);\n            c.UnFocusedColor2 = Color.FromArgb(217, 217, 217);\n            c.UnFocusedBorderColor = Color.FromArgb(168, 169, 161);\n            c.UnFocusedForeColor = Color.FromArgb(40, 40, 40);\n\n            c.HoverColor1 = Color.Transparent;\n            c.HoverColor2 = Color.Transparent;\n            c.HoverBorderColor = Color.Transparent;\n\n            c.SelectedColor1 = Color.FromArgb(244, 125, 77);\n            c.SelectedColor2 = Color.FromArgb(235, 110, 60);\n            c.SelectedBorderColor = Color.FromArgb(240, 119, 70);\n            c.SelectedForeColor = Color.White;\n\n            c.InsertionCaretColor = Color.FromArgb(240, 119, 70);\n\n            // thumbnails & pane\n            c.ImageInnerBorderColor = Color.Transparent;\n            c.ImageOuterBorderColor = Color.White;\n\n            // details view\n            c.CellForeColor = Color.FromArgb(60, 60, 60);\n            c.ColumnHeaderBackColor1 = Color.FromArgb(247, 247, 247);\n            c.ColumnHeaderBackColor2 = Color.FromArgb(235, 235, 235);\n            c.ColumnHeaderHoverColor1 = Color.White;\n            c.ColumnHeaderHoverColor2 = Color.FromArgb(245, 245, 245);\n            c.ColumnHeaderForeColor = Color.FromArgb(60, 60, 60);\n            c.ColumnSelectColor = Color.FromArgb(34, 128, 128, 128);\n            c.ColumnSeparatorColor = Color.FromArgb(106, 128, 128, 128);\n            c.mAlternateBackColor = Color.FromArgb(234, 234, 234);\n            c.mAlternateCellForeColor = Color.FromArgb(40, 40, 40);\n\n            // image pane\n            c.PaneBackColor = Color.White;\n            c.PaneSeparatorColor = Color.FromArgb(216, 216, 216);\n            c.PaneLabelColor = Color.FromArgb(156, 156, 156);\n\n            // selection rectangle\n            c.SelectionRectangleColor1 = Color.FromArgb(64, 240, 116, 68);\n            c.SelectionRectangleColor2 = Color.FromArgb(64, 240, 116, 68);\n            c.SelectionRectangleBorderColor = Color.FromArgb(240, 119, 70);\n\n            return c;\n        }\n        /// <summary>\n        /// Sets the color palette to noir colors.\n        /// </summary>\n        private static ShengListViewColor GetNoirTheme()\n        {\n            ShengListViewColor c = new ShengListViewColor();\n\n            // control\n            c.ControlBackColor = Color.Black;\n\n            // item\n            c.BackColor = Color.FromArgb(0x31, 0x31, 0x31);\n            c.ForeColor = Color.LightGray;\n\n            c.BorderColor = Color.DarkGray;\n\n            c.UnFocusedColor1 = Color.FromArgb(16, SystemColors.GrayText);\n            c.UnFocusedColor2 = Color.FromArgb(64, SystemColors.GrayText);\n            c.UnFocusedBorderColor = Color.FromArgb(128, SystemColors.GrayText);\n            c.UnFocusedForeColor = Color.LightGray;\n\n            c.HoverColor1 = Color.FromArgb(64, Color.White);\n            c.HoverColor2 = Color.FromArgb(16, Color.White);\n            c.HoverBorderColor = Color.FromArgb(64, SystemColors.Highlight);\n\n            c.SelectedColor1 = Color.FromArgb(64, 96, 160);\n            c.SelectedColor2 = Color.FromArgb(64, 64, 96, 160);\n            c.SelectedBorderColor = Color.FromArgb(128, SystemColors.Highlight);\n            c.SelectedForeColor = Color.LightGray;\n\n            c.InsertionCaretColor = Color.FromArgb(96, 144, 240);\n\n            // thumbnails & pane\n            c.ImageInnerBorderColor = Color.FromArgb(128, Color.White);\n            c.ImageOuterBorderColor = Color.FromArgb(128, Color.Gray);\n\n            // details view\n            c.CellForeColor = Color.WhiteSmoke;\n            c.ColumnHeaderBackColor1 = Color.FromArgb(32, 128, 128, 128);\n            c.ColumnHeaderBackColor2 = Color.FromArgb(196, 128, 128, 128);\n            c.ColumnHeaderHoverColor1 = Color.FromArgb(64, 96, 144, 240);\n            c.ColumnHeaderHoverColor2 = Color.FromArgb(196, 96, 144, 240);\n            c.ColumnHeaderForeColor = Color.White;\n            c.ColumnSelectColor = Color.FromArgb(96, 128, 128, 128);\n            c.ColumnSeparatorColor = Color.Gold;\n            c.AlternateBackColor = Color.FromArgb(0x31, 0x31, 0x31);\n            c.AlternateCellForeColor = Color.WhiteSmoke;\n\n            // image pane\n            c.PaneBackColor = Color.FromArgb(0x31, 0x31, 0x31);\n            c.PaneSeparatorColor = Color.Gold;\n            c.PaneLabelColor = SystemColors.GrayText;\n\n            // selection rectangke\n            c.SelectionRectangleColor1 = Color.FromArgb(160, 96, 144, 240);\n            c.SelectionRectangleColor2 = Color.FromArgb(32, 96, 144, 240);\n            c.SelectionRectangleBorderColor = Color.FromArgb(64, 96, 144, 240);\n\n            return c;\n        }\n        #endregion\n\n        #region System.Object Overrides\n        /// <summary>\n        /// Determines whether all color values of the specified \n        /// ImageListViewColor are equal to this instance.\n        /// </summary>\n        /// <param name=\"obj\">The object to compare with this instance.</param>\n        /// <returns>true if the two instances have the same color values; \n        /// otherwise false.</returns>\n        public override bool Equals(object obj)\n        {\n            if (obj == null)\n                throw new NullReferenceException();\n\n            ShengListViewColor other = obj as ShengListViewColor;\n            if (other == null) return false;\n\n            foreach (PropertyInfo info in typeof(ShengListViewColor).GetProperties())\n            {\n                // Walk through color properties\n                if (info.PropertyType == typeof(Color))\n                {\n                    // Compare colors\n                    Color color1 = (Color)info.GetValue(this, null);\n                    Color color2 = (Color)info.GetValue(other, null);\n\n                    if (color1 != color2) return false;\n                }\n            }\n\n            return true;\n        }\n        /// <summary>\n        /// Returns a hash code for this instance.\n        /// </summary>\n        /// <returns>\n        /// A hash code for this instance, suitable for use in \n        /// hashing algorithms and data structures like a hash table. \n        /// </returns>\n        public override int GetHashCode()\n        {\n            return base.GetHashCode();\n        }\n\n        /// <summary>\n        /// Returns a string that represents this instance.\n        /// </summary>\n        /// <returns>\n        /// A string that represents this instance.\n        /// </returns>\n        public override string ToString()\n        {\n            ShengListViewColor colors = this;\n\n            // First check if the color matches a predefined color setting\n            foreach (MemberInfo info in typeof(ShengListViewColor).GetMembers(BindingFlags.Static | BindingFlags.Public))\n            {\n                if (info.MemberType == MemberTypes.Property)\n                {\n                    PropertyInfo propertyInfo = (PropertyInfo)info;\n                    if (propertyInfo.PropertyType == typeof(ShengListViewColor))\n                    {\n                        ShengListViewColor presetValue = (ShengListViewColor)propertyInfo.GetValue(null, null);\n                        // If the color setting is equal to a preset value\n                        // return the name of the preset\n                        if (colors.Equals(presetValue))\n                            return string.Format(\"({0})\", propertyInfo.Name);\n                    }\n                }\n            }\n\n            // Serialize all colors which are different from the default setting\n            List<string> lines = new List<string>();\n            foreach (PropertyInfo info in typeof(ShengListViewColor).GetProperties())\n            {\n                // Walk through color properties\n                if (info.PropertyType == typeof(Color))\n                {\n                    // Get property name\n                    string name = info.Name;\n                    // Get the current value\n                    Color color = (Color)info.GetValue(colors, null);\n                    // Find the default value atribute\n                    Attribute[] attributes = (Attribute[])info.GetCustomAttributes(typeof(DefaultValueAttribute), false);\n                    if (attributes.Length != 0)\n                    {\n                        // Get the default value\n                        DefaultValueAttribute attribute = (DefaultValueAttribute)attributes[0];\n                        Color defaultColor = (Color)attribute.Value;\n                        // Serialize only if colors are different\n                        if (color != defaultColor)\n                        {\n                            lines.Add(string.Format(\"{0} = {1}\", name, color.Name));\n                        }\n                    }\n                }\n            }\n\n            return string.Join(\"; \", lines.ToArray());\n        }\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengListView/ShengListViewHitInfo.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nnamespace Sheng.Winform.Controls\n{\n    /// <summary>\n    /// 测试坐标\n    /// </summary>\n    public class ShengListViewHitInfo\n    {\n        /// <summary>\n        /// 项的坐标\n        /// </summary>\n        public int ItemIndex { get; private set; }\n\n        /// <summary>\n        /// 是否点击了项\n        /// </summary>\n        public bool ItemHit { get; private set; }\n\n        public ShengListViewHitInfo(int itemIndex,bool itemHit)\n        {\n            ItemIndex = itemIndex;\n            ItemHit = itemHit;\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengListView/ShengListViewItem.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Drawing;\n\nnamespace Sheng.Winform.Controls\n{\n    public class ShengListViewItem\n    {\n        #region 私有成员\n\n\n        #endregion\n\n        #region 受保护的成员\n\n        private ShengListViewItemCollection _ownerCollection;\n        internal ShengListViewItemCollection OwnerCollection\n        {\n            get { return _ownerCollection; }\n            set { _ownerCollection = value; }\n        }\n\n        #endregion\n\n        #region 公开属性\n\n        public int Index\n        {\n            get\n            {\n                return _ownerCollection.IndexOf(this);\n            }\n        }\n\n        private ShengListViewItemState _state = ShengListViewItemState.None;\n        /// <summary>\n        /// 该项当前的选中状态\n        /// </summary>\n        public ShengListViewItemState State\n        {\n            get { return _state; }\n        }\n\n        public bool Selected\n        {\n            get\n            {\n                return (_state & ShengListViewItemState.Selected) == ShengListViewItemState.Selected;\n            }\n            set\n            {\n                bool selected = Selected;\n\n                if (value)\n                    _state = _state | ShengListViewItemState.Selected;\n                else\n                    _state = _state ^ ShengListViewItemState.Selected;\n\n                if (selected != Selected)\n                    Render();\n            }\n        }\n\n        public bool Hovered\n        {\n            get\n            {\n                return (_state & ShengListViewItemState.Hovered) == ShengListViewItemState.Hovered;\n            }\n            set\n            {\n                bool hovered = Hovered;\n\n                if (value)\n                    _state = _state | ShengListViewItemState.Hovered;\n                else\n                    _state = _state ^ ShengListViewItemState.Hovered;\n\n                if (hovered != Hovered)\n                    Render();\n            }\n        }\n\n        public bool Focused\n        {\n            get\n            {\n                return (_state & ShengListViewItemState.Focused) == ShengListViewItemState.Focused;\n            }\n            set\n            {\n                bool focused = Focused;\n\n                if (value)\n                    _state = _state | ShengListViewItemState.Focused;\n                else\n                    _state = _state ^ ShengListViewItemState.Focused;\n\n                if (focused != Focused)\n                    Render();\n            }\n        }\n\n        private object _value;\n        /// <summary>\n        /// 所绑定的对象\n        /// </summary>\n        public object Value\n        {\n            get { return _value; }\n        }\n\n        #endregion\n\n        #region 构造\n\n        public ShengListViewItem(object value)\n        {\n            _value = value;\n        }\n\n        #endregion\n\n        #region 私有方法\n\n        private void Render()\n        {\n            _ownerCollection.Owner.RenderItem(this);\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengListView/ShengListViewItemCollection.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Collections;\n\nnamespace Sheng.Winform.Controls\n{\n    public class ShengListViewItemCollection : CollectionBase, IList<ShengListViewItem>\n    {\n        #region 基本方法和属性\n\n        public ShengListViewItemCollection()\n        {\n        }\n\n        public ShengListViewItemCollection(ShengListViewItemCollection value)\n        {\n            this.AddRange(value);\n        }\n\n        public ShengListViewItemCollection(ShengListViewItem[] value)\n        {\n            this.AddRange(value);\n        }\n\n        public ShengListViewItem this[int index]\n        {\n            get\n            {\n                return ((ShengListViewItem)(List[index]));\n            }\n            set\n            {\n                List[index] = value;\n            }\n        }\n\n        public int Add(ShengListViewItem value)\n        {\n            value.OwnerCollection = this;\n            int index = List.Add(value);\n            _owner.Refresh();\n            return index;\n        }\n\n        public void AddRange(ShengListViewItem[] value)\n        {\n            _owner.SuspendLayout();\n\n            for (int i = 0; (i < value.Length); i = (i + 1))\n            {\n                this.Add(value[i]);\n            }\n\n            _owner.ResumeLayout(true);\n        }\n\n        public void AddRange(ShengListViewItemCollection value)\n        {\n            _owner.SuspendLayout();\n\n            for (int i = 0; (i < value.Count); i = (i + 1))\n            {\n                this.Add(value[i]);\n            }\n\n            _owner.ResumeLayout(true);\n        }\n\n        public bool Contains(ShengListViewItem value)\n        {\n            return List.Contains(value);\n        }\n\n        public void CopyTo(ShengListViewItem[] array, int index)\n        {\n            List.CopyTo(array, index);\n        }\n\n        public int IndexOf(ShengListViewItem value)\n        {\n            return List.IndexOf(value);\n        }\n\n        public void Insert(int index, ShengListViewItem value)\n        {\n            value.OwnerCollection = this;\n            List.Insert(index, value);\n        }\n\n        public void Remove(ShengListViewItem value)\n        {\n            value.OwnerCollection = null;\n            List.Remove(value);\n            _owner.Refresh();\n\n            _owner.OnItemsRemoved(new List<ShengListViewItem>() { value });\n        }\n\n        public void Remove(List<ShengListViewItem> items)\n        {\n            _owner.SuspendLayout();\n\n            foreach (var item in items)\n            {\n                item.OwnerCollection = null;\n                List.Remove(item);\n            }\n\n            _owner.ResumeLayout(true);\n\n            _owner.OnItemsRemoved(items);\n        }\n\n        protected override void OnClear()\n        {\n            _owner.SuspendLayout();\n            base.OnClear();\n            _owner.ResumeLayout(true);\n        }\n\n        #endregion\n\n        #region 加的方法和属性\n\n        private ShengListView _owner;\n        internal ShengListView Owner\n        {\n            get { return _owner; }\n            set { _owner = value; }\n        }\n\n        public ShengListViewItem[] ToArray()\n        {\n            return this.ToList().ToArray();\n        }\n\n        public List<ShengListViewItem> ToList()\n        {\n            List<ShengListViewItem> list = new List<ShengListViewItem>();\n\n            foreach (ShengListViewItem e in this)\n            {\n                list.Add(e);\n            }\n\n            return list;\n        }\n\n        /// <summary>\n        /// 将指定的事件移动到(紧邻)另一个事件之前\n        /// </summary>\n        /// <param name=\"targetEvent\"></param>\n        /// <param name=\"referEvent\"></param>\n        public void PreTo(ShengListViewItem targetEvent, ShengListViewItem referEvent)\n        {\n            if (targetEvent == null || referEvent == null)\n                return;\n\n            if (this.Contains(targetEvent) == false || this.Contains(referEvent) == false)\n                return;\n\n            //这里不能因为目标事件是最顶过就直接返回\n            //因为此方法的目的是把目标事件放在指定事件 紧挨着 的 前面 一个，而不是前面的任意位置\n            //有可能目标事件index是0，指定事件是3，那么此方法要把目标事件的index变为2\n            //如果指定事件已经是最顶个了，直接返回\n            //int targetIndex = this.IndexOf(targetEvent);\n            //if (targetIndex == 0)\n            //    return;\n\n            int referIndex = this.IndexOf(referEvent);\n\n            //如果目标事件在指定事件之前的某个位置，这里不能先直接remove目标事件\n            //因为这样会使指定事件提前一个index，此时在referIndex上insert，就跑到指定事件后面去了\n            //如果目标事件本身在指定事件之后，则无此问题\n            //先判断如果在前，就 referIndex--，再insert\n\n            if (this.IndexOf(targetEvent) < referIndex)\n                referIndex--;\n\n            this.Remove(targetEvent);\n            this.Insert(referIndex, targetEvent);\n        }\n\n        /// <summary>\n        /// 将指定的事件移动到(紧邻)另一个事件之后\n        /// </summary>\n        /// <param name=\"targetEvent\"></param>\n        /// <param name=\"referEvent\"></param>\n        public void NextTo(ShengListViewItem targetEvent, ShengListViewItem referEvent)\n        {\n            if (targetEvent == null || referEvent == null)\n                return;\n\n            if (this.Contains(targetEvent) == false || this.Contains(referEvent) == false)\n                return;\n\n            //如果指定事件已经是最后个了，直接返回\n            //int targetIndex = this.IndexOf(targetEvent);\n            //if (targetIndex == this.Count - 1)\n            //    return;\n\n            int referIndex = this.IndexOf(referEvent);\n\n            //这里在remove之前，也要先判断目标事件是在指定事件之前还是之后\n            //如果在指定事件之后，那么referIndex++,不然就insert到指定事件前面了\n            if (this.IndexOf(targetEvent) > referIndex)\n                referIndex++;\n\n            this.Remove(targetEvent);\n            this.Insert(referIndex, targetEvent);\n        }\n\n        #endregion\n\n        #region ImageListViewItemEnumerator\n\n        [Serializable]\n        public class ImageListViewItemEnumerator : object, IEnumerator, IEnumerator<ShengListViewItem>\n        {\n            private IEnumerator baseEnumerator;\n\n            private IEnumerable temp;\n\n            public ImageListViewItemEnumerator(ShengListViewItemCollection mappings)\n            {\n                this.temp = ((IEnumerable)(mappings));\n                this.baseEnumerator = temp.GetEnumerator();\n            }\n\n            public ShengListViewItem Current\n            {\n                get\n                {\n                    return ((ShengListViewItem)(baseEnumerator.Current));\n                }\n            }\n\n            object IEnumerator.Current\n            {\n                get\n                {\n                    return baseEnumerator.Current;\n                }\n            }\n\n            public bool MoveNext()\n            {\n                return baseEnumerator.MoveNext();\n            }\n\n            bool IEnumerator.MoveNext()\n            {\n                return baseEnumerator.MoveNext();\n            }\n\n            public void Reset()\n            {\n                baseEnumerator.Reset();\n            }\n\n            void IEnumerator.Reset()\n            {\n                baseEnumerator.Reset();\n            }\n\n            #region IDisposable 成员\n\n            public void Dispose()\n            {\n\n            }\n\n            #endregion\n        }\n\n        #endregion\n\n        #region ICollection<ImageListViewItem> 成员\n\n        void ICollection<ShengListViewItem>.Add(ShengListViewItem item)\n        {\n            this.Add(item);\n        }\n\n        public bool IsReadOnly\n        {\n            get { return false; }\n        }\n\n        bool ICollection<ShengListViewItem>.Remove(ShengListViewItem item)\n        {\n            this.Remove(item);\n            return true;\n        }\n\n        #endregion\n\n        #region IEnumerable<ImageListViewItem> 成员\n\n        public new IEnumerator<ShengListViewItem> GetEnumerator()\n        {\n            return new ImageListViewItemEnumerator(this);\n        }\n\n        #endregion\n    }\n}\n\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengLoadingCircle.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Data;\nusing System.Drawing;\nusing System.Drawing.Drawing2D;\nusing System.Text;\nusing System.Windows.Forms;\n\nnamespace Sheng.Winform.Controls\n{\n    \n    public partial class ShengLoadingCircle : Control\n    {\n        #region 常数\n\n        private const double NumberOfDegreesInCircle = 360;\n        private const double NumberOfDegreesInHalfCircle = NumberOfDegreesInCircle / 2;\n        private const int DefaultInnerCircleRadius = 8;\n        private const int DefaultOuterCircleRadius = 10;\n        private const int DefaultNumberOfSpoke = 10;\n        private const int DefaultSpokeThickness = 4;\n        private readonly Color DefaultColor = Color.DarkGray;\n\n        private const int MacOSXInnerCircleRadius = 5;\n        private const int MacOSXOuterCircleRadius = 11;\n        private const int MacOSXNumberOfSpoke = 12;\n        private const int MacOSXSpokeThickness = 2;\n\n        private const int FireFoxInnerCircleRadius = 6;\n        private const int FireFoxOuterCircleRadius = 7;\n        private const int FireFoxNumberOfSpoke = 9;\n        private const int FireFoxSpokeThickness = 4;\n\n        private const int IE7InnerCircleRadius = 8;\n        private const int IE7OuterCircleRadius = 9;\n        private const int IE7NumberOfSpoke = 24;\n        private const int IE7SpokeThickness = 4;\n\n        #endregion\n\n        #region 枚举\n\n        public enum StylePresets\n        {\n            MacOSX,\n            Firefox,\n            IE7,\n            Custom\n        }\n\n        #endregion\n\n        #region 局部变量\n\n        private Timer m_Timer;\n        private bool m_IsTimerActive;\n        private int m_NumberOfSpoke;\n        private int m_SpokeThickness;\n        private int m_ProgressValue;\n        private int m_OuterCircleRadius;\n        private int m_InnerCircleRadius;\n        private PointF m_CenterPoint;\n        private Color m_Color;\n        private Color[] m_Colors;\n        private double[] m_Angles;\n        private StylePresets m_StylePreset;\n\n        #endregion\n\n        #region 属性\n\n        /// <summary>\n        /// 获取和设置控件高亮色\n        /// </summary>\n        /// <value>高亮色</value>\n        [TypeConverter(\"System.Drawing.ColorConverter\"),\n        Category(\"LoadingCircle\"),\n        Description(\"获取和设置控件高亮色\")]\n        public Color Color\n        {\n            get\n            {\n                return m_Color;\n            }\n            set\n            {\n                m_Color = value;\n\n                GenerateColorsPallet();\n                Invalidate();\n            }\n        }\n\n        /// <summary>\n        /// 获取和设置外围半径\n        /// </summary>\n        /// <value>外围半径</value>\n        [System.ComponentModel.Description(\"获取和设置外围半径\"),\n         System.ComponentModel.Category(\"LoadingCircle\")]\n        public int OuterCircleRadius\n        {\n            get\n            {\n                if (m_OuterCircleRadius == 0)\n                    m_OuterCircleRadius = DefaultOuterCircleRadius;\n\n                return m_OuterCircleRadius;\n            }\n            set\n            {\n                m_OuterCircleRadius = value;\n                Invalidate();\n            }\n        }\n\n        /// <summary>\n        /// 获取和设置内圆半径\n        /// </summary>\n        /// <value>内圆半径</value>\n        [System.ComponentModel.Description(\"获取和设置内圆半径\"),\n         System.ComponentModel.Category(\"LoadingCircle\")]\n        public int InnerCircleRadius\n        {\n            get\n            {\n                if (m_InnerCircleRadius == 0)\n                    m_InnerCircleRadius = DefaultInnerCircleRadius;\n\n                return m_InnerCircleRadius;\n            }\n            set\n            {\n                m_InnerCircleRadius = value;\n                Invalidate();\n            }\n        }\n\n        /// <summary>\n        /// 获取和设置辐条数量\n        /// </summary>\n        /// <value>辐条数量</value>\n        [System.ComponentModel.Description(\"获取和设置辐条数量\"),\n        System.ComponentModel.Category(\"LoadingCircle\")]\n        public int NumberSpoke\n        {\n            get\n            {\n                if (m_NumberOfSpoke == 0)\n                    m_NumberOfSpoke = DefaultNumberOfSpoke;\n\n                return m_NumberOfSpoke;\n            }\n            set\n            {\n                if (m_NumberOfSpoke != value && m_NumberOfSpoke > 0)\n                {\n                    m_NumberOfSpoke = value;\n                    GenerateColorsPallet();\n                    GetSpokesAngles();\n\n                    Invalidate();\n                }\n            }\n        }\n\n        /// <summary>\n        /// 获取和设置一个布尔值，表示当前控件<see cref=\"T:LoadingCircle\"/>是否激活。\n        /// </summary>\n        /// <value><c>true</c> 表示激活；否则，为<c>false</c>。</value>\n        [System.ComponentModel.Description(\"获取和设置一个布尔值，表示当前控件是否激活。\"),\n        System.ComponentModel.Category(\"LoadingCircle\")]\n        public bool Active\n        {\n            get\n            {\n                return m_IsTimerActive;\n            }\n            set\n            {\n                m_IsTimerActive = value;\n                ActiveTimer();\n            }\n        }\n\n        /// <summary>\n        /// 获取和设置辐条粗细程度。\n        /// </summary>\n        /// <value>辐条粗细值</value>\n        [System.ComponentModel.Description(\"获取和设置辐条粗细程度。\"),\n        System.ComponentModel.Category(\"LoadingCircle\")]\n        public int SpokeThickness\n        {\n            get\n            {\n                if (m_SpokeThickness <= 0)\n                    m_SpokeThickness = DefaultSpokeThickness;\n\n                return m_SpokeThickness;\n            }\n            set\n            {\n                m_SpokeThickness = value;\n                Invalidate();\n            }\n        }\n\n        /// <summary>\n        /// 获取和设置旋转速度。\n        /// </summary>\n        /// <value>旋转速度</value>\n        [System.ComponentModel.Description(\"获取和设置旋转速度。\"),\n        System.ComponentModel.Category(\"LoadingCircle\")]\n        public int RotationSpeed\n        {\n            get\n            {\n                return m_Timer.Interval;\n            }\n            set\n            {\n                if (value > 0)\n                    m_Timer.Interval = value;\n            }\n        }\n\n        /// <summary>\n        /// 快速设置预定义风格。\n        /// </summary>\n        /// <value>风格的值</value>\n        [Category(\"LoadingCircle\"),\n        Description(\"快速设置预定义风格。\"),\n         DefaultValue(typeof(StylePresets), \"Custom\")]\n        public StylePresets StylePreset\n        {\n            get { return m_StylePreset; }\n            set\n            {\n                m_StylePreset = value;\n\n                switch (m_StylePreset)\n                {\n                    case StylePresets.MacOSX:\n                        SetCircleAppearance(MacOSXNumberOfSpoke,\n                            MacOSXSpokeThickness, MacOSXInnerCircleRadius,\n                            MacOSXOuterCircleRadius);\n                        break;\n                    case StylePresets.Firefox:\n                        SetCircleAppearance(FireFoxNumberOfSpoke,\n                            FireFoxSpokeThickness, FireFoxInnerCircleRadius,\n                            FireFoxOuterCircleRadius);\n                        break;\n                    case StylePresets.IE7:\n                        SetCircleAppearance(IE7NumberOfSpoke,\n                            IE7SpokeThickness, IE7InnerCircleRadius,\n                            IE7OuterCircleRadius);\n                        break;\n                    case StylePresets.Custom:\n                        SetCircleAppearance(DefaultNumberOfSpoke,\n                            DefaultSpokeThickness,\n                            DefaultInnerCircleRadius,\n                            DefaultOuterCircleRadius);\n                        break;\n                }\n            }\n        }\n\n        #endregion\n\n        #region 构造函数及事件处理\n\n        public ShengLoadingCircle()\n        {\n\n            SetStyle(ControlStyles.UserPaint, true);\n            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);\n            SetStyle(ControlStyles.ResizeRedraw, true);\n            SetStyle(ControlStyles.SupportsTransparentBackColor, true);\n\n            m_Color = DefaultColor;\n\n            GenerateColorsPallet();\n            GetSpokesAngles();\n            GetControlCenterPoint();\n\n            m_Timer = new Timer();\n            m_Timer.Tick += new EventHandler(aTimer_Tick);\n            ActiveTimer();\n\n            this.Resize += new EventHandler(LoadingCircle_Resize);\n        }\n\n        void LoadingCircle_Resize(object sender, EventArgs e)\n        {\n            GetControlCenterPoint();\n        }\n\n        void aTimer_Tick(object sender, EventArgs e)\n        {\n            m_ProgressValue = ++m_ProgressValue % m_NumberOfSpoke;\n            Invalidate();\n        }\n\n        protected override void OnPaint(PaintEventArgs e)\n        {\n            if (m_NumberOfSpoke > 0)\n            {\n                e.Graphics.SmoothingMode = SmoothingMode.HighQuality;\n\n                int intPosition = m_ProgressValue;\n                for (int intCounter = 0; intCounter < m_NumberOfSpoke; intCounter++)\n                {\n                    intPosition = intPosition % m_NumberOfSpoke;\n                    DrawLine(e.Graphics,\n                             GetCoordinate(m_CenterPoint, m_InnerCircleRadius, m_Angles[intPosition]),\n                             GetCoordinate(m_CenterPoint, m_OuterCircleRadius, m_Angles[intPosition]),\n                             m_Colors[intCounter], m_SpokeThickness);\n                    intPosition++;\n                }\n            }\n\n            base.OnPaint(e);\n        }\n\n        #endregion\n\n        #region 局部方法\n\n        private Color Darken(Color _objColor, int _intPercent)\n        {\n            int intRed = _objColor.R;\n            int intGreen = _objColor.G;\n            int intBlue = _objColor.B;\n            return Color.FromArgb(_intPercent, Math.Min(intRed, byte.MaxValue), Math.Min(intGreen, byte.MaxValue), Math.Min(intBlue, byte.MaxValue));\n        }\n\n        private void GenerateColorsPallet()\n        {\n            m_Colors = GenerateColorsPallet(m_Color, Active, m_NumberOfSpoke);\n        }\n\n        private Color[] GenerateColorsPallet(Color _objColor, bool _blnShadeColor, int _intNbSpoke)\n        {\n            Color[] objColors = new Color[NumberSpoke];\n\n            byte bytIncrement = (byte)(byte.MaxValue / NumberSpoke);\n\n            byte PERCENTAGE_OF_DARKEN = 0;\n\n            for (int intCursor = 0; intCursor < NumberSpoke; intCursor++)\n            {\n                if (_blnShadeColor)\n                {\n                    if (intCursor == 0 || intCursor < NumberSpoke - _intNbSpoke)\n                        objColors[intCursor] = _objColor;\n                    else\n                    {\n                        PERCENTAGE_OF_DARKEN += bytIncrement;\n\n                        if (PERCENTAGE_OF_DARKEN > byte.MaxValue)\n                            PERCENTAGE_OF_DARKEN = byte.MaxValue;\n\n                        objColors[intCursor] = Darken(_objColor, PERCENTAGE_OF_DARKEN);\n                    }\n                }\n                else\n                    objColors[intCursor] = _objColor;\n            }\n\n            return objColors;\n        }\n\n        private void GetControlCenterPoint()\n        {\n            m_CenterPoint = GetControlCenterPoint(this);\n        }\n\n        private PointF GetControlCenterPoint(Control _objControl)\n        {\n            return new PointF(_objControl.Width / 2, _objControl.Height / 2 - 1);\n        }\n\n        private void DrawLine(Graphics _objGraphics, PointF _objPointOne, PointF _objPointTwo,\n                              Color _objColor, int _intLineThickness)\n        {\n            using (Pen objPen = new Pen(new SolidBrush(_objColor), _intLineThickness))\n            {\n                objPen.StartCap = LineCap.Round;\n                objPen.EndCap = LineCap.Round;\n                _objGraphics.DrawLine(objPen, _objPointOne, _objPointTwo);\n            }\n        }\n\n        private PointF GetCoordinate(PointF _objCircleCenter, int _intRadius, double _dblAngle)\n        {\n            double dblAngle = Math.PI * _dblAngle / NumberOfDegreesInHalfCircle;\n\n            return new PointF(_objCircleCenter.X + _intRadius * (float)Math.Cos(dblAngle),\n                              _objCircleCenter.Y + _intRadius * (float)Math.Sin(dblAngle));\n        }\n\n        private void GetSpokesAngles()\n        {\n            m_Angles = GetSpokesAngles(NumberSpoke);\n        }\n\n        private double[] GetSpokesAngles(int _intNumberSpoke)\n        {\n            double[] Angles = new double[_intNumberSpoke];\n            double dblAngle = (double)NumberOfDegreesInCircle / _intNumberSpoke;\n\n            for (int shtCounter = 0; shtCounter < _intNumberSpoke; shtCounter++)\n                Angles[shtCounter] = (shtCounter == 0 ? dblAngle : Angles[shtCounter - 1] + dblAngle);\n\n            return Angles;\n        }\n\n        private void ActiveTimer()\n        {\n            if (m_IsTimerActive)\n                m_Timer.Start();\n            else\n            {\n                m_Timer.Stop();\n                m_ProgressValue = 0;\n            }\n\n            GenerateColorsPallet();\n            Invalidate();\n        }\n\n        #endregion\n\n        #region 全局方法\n\n        public override Size GetPreferredSize(Size proposedSize)\n        {\n            proposedSize.Width =\n                (m_OuterCircleRadius + m_SpokeThickness) * 2;\n\n            return proposedSize;\n        }\n\n        /// <summary>\n        /// 设置控件的外观\n        /// </summary>\n        /// <param name=\"numberSpoke\">条数</param>\n        /// <param name=\"spokeThickness\">粗细</param>\n        /// <param name=\"innerCircleRadius\">内圆半径</param>\n        /// <param name=\"outerCircleRadius\">外圆半径</param>\n        public void SetCircleAppearance(int numberSpoke, int spokeThickness,\n            int innerCircleRadius, int outerCircleRadius)\n        {\n            NumberSpoke = numberSpoke;\n            SpokeThickness = spokeThickness;\n            InnerCircleRadius = innerCircleRadius;\n            OuterCircleRadius = outerCircleRadius;\n\n            Invalidate();\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengNavigationTreeView/ShengNavigationTreeNode.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Diagnostics;\n\nnamespace Sheng.Winform.Controls\n{\n    public class ShengNavigationTreeNode : TreeNode\n    {\n        #region 构造 \n\n        public ShengNavigationTreeNode():base()\n        {\n\n        }\n\n        public ShengNavigationTreeNode(string name)\n            : base(name)\n        {\n        }\n\n        public ShengNavigationTreeNode(string name,Control panel)\n            : this(name)\n        {\n            this.Panel = panel;\n        }\n\n        #endregion\n\n        #region 公开属性\n\n        private Control _panel;\n        /// <summary>\n        /// 面板\n        /// </summary>\n        public Control Panel\n        {\n            get\n            {\n                return this._panel;\n            }\n            set\n            {\n                this._panel = value;\n            }\n        }\n\n        #endregion\n\n        #region AddNode\n\n        public ShengNavigationTreeNode AddNode(string name)\n        {\n            return AddNode(null, name, null, -1, null);\n        }\n\n        /// <summary>\n        /// 如果path为空或null，则在根节点下添加\n        /// </summary>\n        /// <param name=\"path\"></param>\n        /// <param name=\"name\"></param>\n        /// <returns></returns>\n        public ShengNavigationTreeNode AddNode(string path, string name)\n        {\n            return AddNode(path, name, null, -1, null);\n        }\n\n        /// <summary>\n        /// 如果path为空或null，则在根节点下添加\n        /// </summary>\n        /// <param name=\"path\"></param>\n        /// <param name=\"name\"></param>\n        /// <param name=\"text\"></param>\n        /// <returns></returns>\n        public ShengNavigationTreeNode AddNode(string path, string name, string text)\n        {\n            return AddNode(path, name, text, -1, null);\n        }\n\n        public ShengNavigationTreeNode AddNode(string name, Control panel)\n        {\n            return AddNode(null, name, null, -1, panel);\n        }\n\n        public ShengNavigationTreeNode AddNode(string name, string text, Control panel)\n        {\n            return AddNode(null, name, text, -1, panel);\n        }\n\n        /// <summary>\n        /// 如果path为空或null，则在根节点下添加\n        /// </summary>\n        /// <param name=\"path\"></param>\n        /// <param name=\"name\"></param>\n        /// <param name=\"text\"></param>\n        /// <param name=\"panel\"></param>\n        /// <returns></returns>\n        public ShengNavigationTreeNode AddNode(string path, string name, string text, Control panel)\n        {\n            return AddNode(path, name, text, -1, panel);\n        }\n\n        public ShengNavigationTreeNode AddNode(string path, string name, string text, int imageIndex, Control panel)\n        {\n            ShengNavigationTreeNode node = new ShengNavigationTreeNode();\n\n            if (name != null)\n                node.Name = name;\n\n            if (text != null)\n                node.Text = text;\n            else\n                node.Text = name;\n\n            if (panel != null)\n                node.Panel = panel;\n\n            //if (AutoDockFill)\n            //    node.Panel.Dock = DockStyle.Fill;\n\n            if (path == null || path == String.Empty)\n            {\n                this.Nodes.Add(node);\n            }\n            else\n            {\n                ShengNavigationTreeNode targetNode = GetNode(path);\n                if (targetNode == null)\n                {\n                    Debug.Assert(false, \"没有找到路径 \" + path);\n                    throw new Exception();\n                }\n                targetNode.Nodes.Add(node);\n            }\n\n            return node;\n        }\n\n\n        #endregion\n\n        #region GetNode\n\n        /// <summary>\n        /// 根据指定的路径查找节点\n        /// 如：Setup\\Color\n        /// 不区分大小写\n        /// </summary>\n        /// <param name=\"path\"></param>\n        /// <returns></returns>\n        public ShengNavigationTreeNode GetNode(string path)\n        {\n            return GetNode(path, null);\n        }\n\n        public ShengNavigationTreeNode GetNode(string path, TreeNodeCollection nodes)\n        {\n            TreeNodeCollection targetNodes;\n            if (nodes != null)\n                targetNodes = nodes;\n            else\n                targetNodes = this.Nodes;\n\n            if (targetNodes == null)\n                return null;\n\n            string[] paths = path.Split('\\\\');\n            TreeNode[] findTreeNodes;\n\n            for (int i = 0; i < paths.Length; i++)\n            {\n                findTreeNodes = targetNodes.Find(paths[i], false);\n\n                if (findTreeNodes.Length == 0)\n                {\n                    return null;\n                }\n\n                //如果已经是路径中的最后一级\n                if (i == paths.Length - 1)\n                {\n                    return findTreeNodes[0] as ShengNavigationTreeNode;\n                }\n                //如果还有子级\n                else\n                {\n                    targetNodes = findTreeNodes[0].Nodes;\n                }\n            }\n\n            return null;\n        }\n\n        #endregion\n\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengNavigationTreeView/ShengNavigationTreeView.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Diagnostics;\n\nnamespace Sheng.Winform.Controls\n{\n    public class ShengNavigationTreeView : TreeView\n    {\n        #region 私有成员\n\n        #endregion\n\n        #region 公开属性\n\n        private Panel _emptyPanel = new Panel();\n        /// <summary>\n        /// 空白Panel\n        /// 当选择的节点没有设置关联的面板Control时，返回此空白Panel\n        /// 也可以自定义空白面板\n        /// </summary>\n        public Panel EmptyPanel\n        {\n            get { return this._emptyPanel; }\n            set { this._emptyPanel = value; }\n        }\n\n        public ShengNavigationTreeNode SelectedNavigationNode\n        {\n            get { return this.SelectedNode as ShengNavigationTreeNode; }\n        }\n\n        /// <summary>\n        /// 是否存在有效的选中面板对象\n        /// </summary>\n        public bool IsAvailabilityNavigationPanel\n        {\n            get\n            {\n                if (SelectedNavigationNode != null && SelectedNavigationNode.Panel != null)\n                    return true;\n                else\n                    return false;\n            }\n        }\n\n        /// <summary>\n        /// 选中面板对象\n        /// 如果不存在选中的面板对象，返回一个空白Panel\n        /// </summary>\n        public Control AvailabilityNavigationPanel\n        {\n            get\n            {\n                if (SelectedNavigationNode != null && SelectedNavigationNode.Panel != null)\n                    return SelectedNavigationNode.Panel;\n                else\n                    return this.EmptyPanel;\n            }\n        }\n\n        private bool _autoDockFill = true;\n        /// <summary>\n        /// 是否在添加关联的面板控件时，自动设置DockFill\n        /// </summary>\n        public bool AutoDockFill\n        {\n            get { return this._autoDockFill; }\n            set { this._autoDockFill = value; }\n        }\n\n        #endregion\n\n        #region 构造\n\n        public ShengNavigationTreeView()\n        {\n            this.HideSelection = false;\n        }\n\n        #endregion\n\n        #region 公开方法\n\n        #region AddNode\n\n        public ShengNavigationTreeNode AddNode(string name)\n        {\n            return AddNode(null, name, null, -1, null);\n        }\n\n        /// <summary>\n        /// 如果path为空或null，则在根节点下添加\n        /// </summary>\n        /// <param name=\"path\"></param>\n        /// <param name=\"name\"></param>\n        /// <returns></returns>\n        public ShengNavigationTreeNode AddNode(string path, string name)\n        {\n            return AddNode(path, name, null, -1, null);\n        }\n\n        /// <summary>\n        /// 如果path为空或null，则在根节点下添加\n        /// </summary>\n        /// <param name=\"path\"></param>\n        /// <param name=\"name\"></param>\n        /// <param name=\"text\"></param>\n        /// <returns></returns>\n        public ShengNavigationTreeNode AddNode(string path, string name, string text)\n        {\n            return AddNode(path, name, text, -1, null);\n        }\n\n        public ShengNavigationTreeNode AddNode(string name, Control panel)\n        {\n            return AddNode(null, name, null, -1, panel);\n        }\n\n        public ShengNavigationTreeNode AddNode(string name, string text, Control panel)\n        {\n            return AddNode(null, name, text, -1, panel);\n        }\n\n        /// <summary>\n        /// 如果path为空或null，则在根节点下添加\n        /// </summary>\n        /// <param name=\"path\"></param>\n        /// <param name=\"name\"></param>\n        /// <param name=\"text\"></param>\n        /// <param name=\"panel\"></param>\n        /// <returns></returns>\n        public ShengNavigationTreeNode AddNode(string path, string name, string text, Control panel)\n        {\n            return AddNode(path, name, text, -1, panel);\n        }\n\n        public ShengNavigationTreeNode AddNode(string path, string name, string text, int imageIndex, Control panel)\n        {\n            ShengNavigationTreeNode node = new ShengNavigationTreeNode();\n\n            if (name != null)\n                node.Name = name;\n\n            if (text != null)\n                node.Text = text;\n            else\n                node.Text = name;\n\n            if (panel != null)\n                node.Panel = panel;\n\n            if (AutoDockFill)\n                node.Panel.Dock = DockStyle.Fill;\n\n            if (path == null || path == String.Empty)\n            {\n                this.Nodes.Add(node);\n            }\n            else\n            {\n                ShengNavigationTreeNode targetNode = GetNode(path);\n                if (targetNode == null)\n                {\n                    Debug.Assert(false, \"没有找到路径 \" + path);\n                    throw new Exception();\n                }\n                targetNode.Nodes.Add(node);\n            }\n\n            return node;\n        }\n\n\n        #endregion\n\n        #region GetNode\n\n        /// <summary>\n        /// 根据指定的路径查找节点\n        /// 如：Setup\\Color\n        /// 不区分大小写\n        /// </summary>\n        /// <param name=\"path\"></param>\n        /// <returns></returns>\n        public ShengNavigationTreeNode GetNode(string path)\n        {\n            return GetNode(path, null);\n        }\n\n        public ShengNavigationTreeNode GetNode(string path, TreeNodeCollection nodes)\n        {\n            TreeNodeCollection targetNodes;\n            if (nodes != null)\n                targetNodes = nodes;\n            else\n                targetNodes = this.Nodes;\n\n            if (targetNodes == null)\n                return null;\n\n            string[] paths = path.Split('\\\\');\n            TreeNode[] findTreeNodes;\n\n            for (int i = 0; i < paths.Length; i++)\n            {\n                findTreeNodes = targetNodes.Find(paths[i], false);\n\n                if (findTreeNodes.Length == 0)\n                {\n                    return null;\n                }\n\n                //如果已经是路径中的最后一级\n                if (i == paths.Length - 1)\n                {\n                    return findTreeNodes[0] as ShengNavigationTreeNode;\n                }\n                //如果还有子级\n                else\n                {\n                    targetNodes = findTreeNodes[0].Nodes;\n                }\n            }\n\n            return null;\n        }\n\n        #endregion\n\n        #region SetPanel\n\n        public ShengNavigationTreeNode SetPanel(string path, Control panel)\n        {\n            ShengNavigationTreeNode node = GetNode(path);\n            if (node == null)\n            {\n                Debug.Assert(false, \"没有找到路径 \" + path);\n                throw new Exception();\n            }\n\n            node.Panel = panel;\n\n            if (AutoDockFill)\n                node.Panel.Dock = DockStyle.Fill;\n\n            return node;\n        }\n\n        #endregion\n\n        #endregion\n\n        #region 公开事件\n\n        public delegate void OnAfterSelectNavigationNodeHandler(ShengNavigationTreeView treeView, ShengNavigationTreeNode node);\n        /// <summary>\n        /// 更改选择的节点\n        /// </summary>\n        public event OnAfterSelectNavigationNodeHandler OnAfterSelectNavigationNode;\n\n        #endregion\n\n        #region 事件处理\n\n        protected override void OnAfterSelect(TreeViewEventArgs e)\n        {\n            base.OnAfterSelect(e);\n\n            if (OnAfterSelectNavigationNode != null)\n            {\n                OnAfterSelectNavigationNode(this, e.Node as ShengNavigationTreeNode);\n            }\n        }\n\n        #endregion\n    }\n}"
  },
  {
    "path": "Sheng.Winform.Controls/ShengPad.cs",
    "content": "﻿//如何让复合控件的子控件获得设计时支持 \n//http://www.cnblogs.com/feiyun0112/archive/2007/04/30/733230.html\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Drawing;\nusing System.Drawing.Drawing2D;\nusing System.Windows.Forms.Design;\nusing System.ComponentModel;\n\nnamespace Sheng.Winform.Controls\n{\n    [Designer(typeof(ShengPadDesigner))]\n    public class ShengPad : ContainerControl\n    {\n        TitlePanel titlePanel;\n\n        Panel contentPanel = new Panel()\n        {\n            //BackColor = Color.Blue,\n\n            Name = \"contentPanel\",\n            Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)\n                     | System.Windows.Forms.AnchorStyles.Left)\n                     | System.Windows.Forms.AnchorStyles.Right))),\n            Location = new Point(3, 36 + 3),\n            AutoScroll = true\n        };\n        public Panel ContentPanel\n        {\n            get { return this.contentPanel; }\n        }\n\n        //TODO:\n        private FillStyle fillStyle = FillStyle.Solid;\n        /// <summary>\n        /// 填充样式\n        /// 纯色或渐变\n        /// </summary>\n        public FillStyle FillStyle\n        {\n            get\n            {\n                return this.fillStyle;\n            }\n            set\n            {\n                this.fillStyle = value;\n\n                InitBrush();\n            }\n        }\n\n        private bool showBorder = true;\n        /// <summary>\n        /// 是否显示边框\n        /// </summary>\n        public bool ShowBorder\n        {\n            get\n            {\n                return this.showBorder;\n            }\n            set\n            {\n                this.showBorder = value;\n\n                this.Refresh();\n            }\n        }\n\n        private Pen borderPen = new Pen(Color.Black);\n        /// <summary>\n        /// 边框画笔\n        /// </summary>\n        public Pen BorderPen\n        {\n            get\n            {\n                return this.borderPen;\n            }\n            set\n            {\n                this.borderPen = value;\n                this.Refresh();\n            }\n        }\n\n        private Color borderColor = Color.Black;\n        /// <summary>\n        /// 边框颜色\n        /// </summary>\n        public Color BorderColor\n        {\n            get\n            {\n                return this.borderColor;\n            }\n            set\n            {\n                this.borderColor = value;\n\n                InitPen();\n            }\n        }\n\n        /// <summary>\n        /// 绘制Rectangle\n        /// </summary>\n        private Rectangle BorderRectangle\n        {\n            get\n            {\n                if (this.ClientRectangle == new Rectangle())\n                {\n                    return new Rectangle(0, 0, 1, 1);\n                }\n\n                return new Rectangle(0, 0, this.ClientRectangle.Width - 1, this.ClientRectangle.Height - 1);\n            }\n        }\n\n        private LinearGradientMode fillMode;\n        /// <summary>\n        /// 填充模式\n        /// 如果是渐变,从四个方向的渐变中选一种\n        /// </summary>\n        public LinearGradientMode FillMode\n        {\n            get\n            {\n                return this.fillMode;\n            }\n            set\n            {\n                this.fillMode = value;\n\n                InitBrush();\n            }\n        }\n\n        private Color fillColorStart;\n        /// <summary>\n        /// 填充色(开始)\n        /// 如果是单色填充,使用此颜色\n        /// </summary>\n        public Color FillColorStart\n        {\n            get\n            {\n                if (this.fillColorStart == null)\n                {\n                    this.fillColorStart = this.Parent.BackColor;\n                }\n                return this.fillColorStart;\n            }\n            set\n            {\n                this.fillColorStart = value;\n\n                InitBrush();\n            }\n        }\n\n        private Color fillColorEnd;\n        /// <summary>\n        /// 填充色结束\n        /// </summary>\n        public Color FillColorEnd\n        {\n            get\n            {\n                if (this.fillColorEnd == null)\n                {\n                    this.fillColorEnd = this.Parent.BackColor;\n                }\n\n                return this.fillColorEnd;\n            }\n            set\n            {\n                this.fillColorEnd = value;\n\n                InitBrush();\n            }\n        }\n\n        private bool textVerticalCenter;\n        /// <summary>\n        /// 文本是否垂直居中\n        /// </summary>\n        public bool TextVerticalCenter\n        {\n            get\n            {\n                return this.textVerticalCenter;\n            }\n            set\n            {\n                this.textVerticalCenter = value;\n\n                //if (value)\n                //{\n                //    textFlags = (textFlags | TextFormatFlags.VerticalCenter);\n                //}\n                //else\n                //{\n                //    textFlags = (textFlags & TextFormatFlags.VerticalCenter);\n                //}\n\n                this.Refresh();\n            }\n        }\n\n        private bool textHorizontalCenter;\n        /// <summary>\n        /// 文本是否水平居中\n        /// </summary>\n        public bool TextHorizontalCenter\n        {\n            get\n            {\n                return this.textHorizontalCenter;\n            }\n            set\n            {\n                this.textHorizontalCenter = value;\n\n                //if (value)\n                //{\n                //    textFlags = (textFlags | TextFormatFlags.HorizontalCenter);\n                //}\n                //else\n                //{\n                //    textFlags = (textFlags & TextFormatFlags.HorizontalCenter);\n                //}\n\n                this.Refresh();\n            }\n        }\n\n        private bool singleLine;\n        /// <summary>\n        /// 文本是否保持单行显示\n        /// </summary>\n        public bool SingleLine\n        {\n            get\n            {\n                return this.singleLine;\n            }\n            set\n            {\n                this.singleLine = value;\n\n                //if (this.SingleLine)\n                //{\n                //    textFlags = (textFlags & TextFormatFlags.WordBreak);\n                //    textFlags = (textFlags | TextFormatFlags.SingleLine | TextFormatFlags.WordEllipsis);\n                //}\n                //else\n                //{\n                //    textFlags = (textFlags & TextFormatFlags.SingleLine & TextFormatFlags.WordEllipsis);\n                //    textFlags = (textFlags | TextFormatFlags.WordBreak);\n                //}\n\n                this.Refresh();\n            }\n        }\n\n        /// <summary>\n        /// 填充Rectangle\n        /// </summary>\n        private Rectangle FillRectangle\n        {\n            get\n            {\n                if (this.titlePanel.ClientRectangle == new Rectangle())\n                {\n                    return new Rectangle(0, 0, 1, 1);\n                }\n\n                Rectangle rect;\n\n                if (this.ShowBorder)\n                {\n                    rect = new Rectangle(1, 1, this.titlePanel.ClientRectangle.Width - 1, this.titlePanel.ClientRectangle.Height - 1);\n                }\n                else\n                {\n                    rect = this.titlePanel.ClientRectangle;\n                }\n\n                if (rect.Width == 0)\n                {\n                    rect.Width++;\n                }\n                if (rect.Height == 0)\n                {\n                    rect.Height++;\n                }\n\n                return rect;\n            }\n        }\n\n        /// <summary>\n        /// 绘制Rectangle\n        /// </summary>\n        private Rectangle DrawRectangle\n        {\n            get\n            {\n                if (this.titlePanel.ClientRectangle == new Rectangle())\n                {\n                    return new Rectangle(0, 0, 1, 1);\n                }\n\n                return new Rectangle(0, 0, this.titlePanel.ClientRectangle.Width - 1, this.titlePanel.ClientRectangle.Height - 1);\n            }\n        }\n\n        /// <summary>\n        /// 绘制文本的Rectangle\n        /// </summary>\n        private Rectangle DrawStringRectangle\n        {\n            get\n            {\n                if (this.titlePanel.ClientRectangle == new Rectangle())\n                {\n                    return new Rectangle(0, 0, 1, 1);\n                }\n\n                Rectangle drawStringRectangle;\n\n                if (this.ShowBorder)\n                {\n                    drawStringRectangle = new Rectangle(1, 1, this.titlePanel.ClientRectangle.Width - 2, this.titlePanel.ClientRectangle.Height - 2);\n                }\n                else\n                {\n                    drawStringRectangle = this.titlePanel.ClientRectangle;\n                }\n\n                drawStringRectangle.X = drawStringRectangle.X + this.titlePanel.Padding.Left;\n                drawStringRectangle.Y = drawStringRectangle.Y + this.titlePanel.Padding.Top;\n                drawStringRectangle.Width = drawStringRectangle.Width - this.titlePanel.Padding.Left - this.titlePanel.Padding.Right;\n                drawStringRectangle.Height = drawStringRectangle.Height - this.titlePanel.Padding.Top - this.titlePanel.Padding.Bottom;\n\n                return drawStringRectangle;\n            }\n        }\n\n        private Brush fillBrush;\n        /// <summary>\n        /// 填充对象\n        /// </summary>\n        public Brush FillBrush\n        {\n            get\n            {\n                return this.fillBrush;\n            }\n            set\n            {\n                this.fillBrush = value;\n                this.Refresh();\n            }\n        }\n\n        public ShengPad()\n        {\n            this.FillBrush = new SolidBrush(this.FillColorStart);\n            this.BorderPen = new Pen(this.BorderColor);\n\n            this.SingleLine = false;\n            this.TextHorizontalCenter = false;\n            this.TextVerticalCenter = true;\n\n            EnableDoubleBuffering();\n\n            this.ResizeRedraw = true;\n\n            titlePanel = new TitlePanel(this)\n            {\n                //titlePanel.BackColor = Color.Red;\n                Dock = DockStyle.Top,\n                Height = 36\n            };\n\n           \n        }\n\n        protected override void OnCreateControl()\n        {\n            base.OnCreateControl();\n\n            this.Controls.Add(titlePanel);\n            this.Controls.Add(contentPanel);\n        }\n\n        //void titlePanel_Paint(object sender, PaintEventArgs e)\n        //{\n        //    e.Graphics.FillRectangle(this.FillBrush, this.FillRectangle);\n\n        //    if (this.ShowBorder)\n        //    {\n        //        e.Graphics.DrawRectangle(this.BorderPen, this.DrawRectangle);\n        //    }\n\n        //    textFlags = textFlags & TextFormatFlags.WordBreak;\n\n        //    if (this.TextHorizontalCenter)\n        //    {\n        //        textFlags = (textFlags | TextFormatFlags.HorizontalCenter);\n        //    }\n\n        //    if (this.TextVerticalCenter)\n        //    {\n        //        textFlags = (textFlags | TextFormatFlags.VerticalCenter);\n        //    }\n\n        //    if (this.SingleLine)\n        //    {\n        //        textFlags = (textFlags | TextFormatFlags.SingleLine);\n        //    }\n\n        //    TextRenderer.DrawText(e.Graphics, this.Text, this.Font, this.DrawStringRectangle, this.ForeColor, textFlags);\n        //}\n\n        /// <summary>\n        /// 开启双倍缓冲\n        /// </summary>\n        private void EnableDoubleBuffering()\n        {\n            // Set the value of the double-buffering style bits to true.\n            this.SetStyle(ControlStyles.DoubleBuffer |\n               ControlStyles.UserPaint |\n               ControlStyles.AllPaintingInWmPaint,\n               true);\n            this.UpdateStyles();\n        }\n\n        /// <summary>\n        /// 初始化Pen\n        /// </summary>\n        private void InitPen()\n        {\n            if (this.ShowBorder)\n            {\n                this.BorderPen = new Pen(this.BorderColor);\n            }\n        }\n\n        /// <summary>\n        /// 初始化Brush\n        /// </summary>\n        private void InitBrush()\n        {\n            if (this.FillStyle == FillStyle.Solid)\n            {\n                this.FillBrush = new SolidBrush(this.FillColorStart);\n            }\n            else\n            {\n                this.FillBrush = new LinearGradientBrush(this.FillRectangle, this.FillColorStart, this.FillColorEnd, this.FillMode);\n            }\n        }\n\n        protected override void OnPaint(PaintEventArgs e)\n        {\n            Graphics g = e.Graphics;\n            if (this.ShowBorder)\n            {\n                g.DrawRectangle(this.BorderPen, BorderRectangle);\n            }\n        }\n\n        protected override void OnResize(EventArgs e)\n        {\n            base.OnResize(e);\n\n            contentPanel.Size = new Size(this.Size.Width - contentPanel.Left * 2, this.Size.Height - contentPanel.Top - 3);\n\n            //if (this.Height <= 0 || this.Width <= 0)\n            //{\n            //    return;\n            //}\n\n            //InitBrush();\n            //InitPen();\n\n            //this.Refresh();\n        }\n\n        internal class ShengPadDesigner : ControlDesigner\n        {\n            private ShengPad _pad;\n\n            public override void Initialize(IComponent component)\n            {\n\n\n                base.Initialize(component);\n\n                // Record instance of control we're designing\n                _pad = (ShengPad)component;\n                this.EnableDesignMode(_pad.ContentPanel, \"contentPanel\");\n            }\n        }\n\n        class TitlePanel : Panel\n        {\n            private TextFormatFlags textFlags;\n\n            public ShengPad Pad\n            {\n                get;\n                set;\n            }\n\n            public TitlePanel(ShengPad pad)\n            {\n                Pad = pad;\n\n                this.SetStyle(ControlStyles.DoubleBuffer |\n                   ControlStyles.UserPaint |\n                   ControlStyles.AllPaintingInWmPaint,\n                   true);\n                this.UpdateStyles();\n\n                this.ResizeRedraw = true;\n            }\n\n            protected override void OnPaint(PaintEventArgs e)\n            {\n                e.Graphics.FillRectangle(Pad.FillBrush, Pad.FillRectangle);\n\n                if (Pad.ShowBorder)\n                {\n                    e.Graphics.DrawRectangle(Pad.BorderPen, Pad.DrawRectangle);\n                }\n\n                textFlags = textFlags & TextFormatFlags.WordBreak;\n\n                if (Pad.TextHorizontalCenter)\n                {\n                    textFlags = (textFlags | TextFormatFlags.HorizontalCenter);\n                }\n\n                if (Pad.TextVerticalCenter)\n                {\n                    textFlags = (textFlags | TextFormatFlags.VerticalCenter);\n                }\n\n                if (Pad.SingleLine)\n                {\n                    textFlags = (textFlags | TextFormatFlags.SingleLine);\n                }\n\n                TextRenderer.DrawText(e.Graphics, Pad.Text, this.Font, Pad.DrawStringRectangle, this.ForeColor, textFlags);\n            }\n        }\n    }\n}"
  },
  {
    "path": "Sheng.Winform.Controls/ShengPaginationDataGridView.Designer.cs",
    "content": "﻿namespace Sheng.Winform.Controls\n{\n    partial class ShengPaginationDataGridView\n    {\n        /// <summary> \n        /// 必需的设计器变量。\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary> \n        /// 清理所有正在使用的资源。\n        /// </summary>\n        /// <param name=\"disposing\">如果应释放托管资源，为 true；否则为 false。</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region 组件设计器生成的代码\n\n        /// <summary> \n        /// 设计器支持所需的方法 - 不要\n        /// 使用代码编辑器修改此方法的内容。\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.lblRowCount = new System.Windows.Forms.Label();\n            this.txtPageCurrent = new System.Windows.Forms.TextBox();\n            this.lblPage = new System.Windows.Forms.Label();\n            this.lblPageCount = new System.Windows.Forms.Label();\n            this.dataGridView = new System.Windows.Forms.DataGridView();\n            this.linkLabelPageEnd = new System.Windows.Forms.LinkLabel();\n            this.linkLabelPageUp = new System.Windows.Forms.LinkLabel();\n            this.panelPagination = new System.Windows.Forms.Panel();\n            this.linkLabelPageHome = new System.Windows.Forms.LinkLabel();\n            this.linkLabelPageDown = new System.Windows.Forms.LinkLabel();\n            ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).BeginInit();\n            this.panelPagination.SuspendLayout();\n            this.SuspendLayout();\n            // \n            // lblRowCount\n            // \n            this.lblRowCount.AutoSize = true;\n            this.lblRowCount.Location = new System.Drawing.Point(0, 10);\n            this.lblRowCount.Name = \"lblRowCount\";\n            this.lblRowCount.Size = new System.Drawing.Size(143, 12);\n            this.lblRowCount.TabIndex = 7;\n            this.lblRowCount.Text = \"共 {0} 条 , 每页 {1} 条\";\n            // \n            // txtPageCurrent\n            // \n            this.txtPageCurrent.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));\n            this.txtPageCurrent.Location = new System.Drawing.Point(283, 4);\n            this.txtPageCurrent.Name = \"txtPageCurrent\";\n            this.txtPageCurrent.Size = new System.Drawing.Size(37, 21);\n            this.txtPageCurrent.TabIndex = 7;\n            this.txtPageCurrent.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.txtPageCurrent_KeyPress);\n            // \n            // lblPage\n            // \n            this.lblPage.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));\n            this.lblPage.AutoSize = true;\n            this.lblPage.Location = new System.Drawing.Point(326, 10);\n            this.lblPage.Name = \"lblPage\";\n            this.lblPage.Size = new System.Drawing.Size(17, 12);\n            this.lblPage.TabIndex = 6;\n            this.lblPage.Text = \"页\";\n            // \n            // lblPageCount\n            // \n            this.lblPageCount.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));\n            this.lblPageCount.Location = new System.Drawing.Point(156, 10);\n            this.lblPageCount.Name = \"lblPageCount\";\n            this.lblPageCount.Size = new System.Drawing.Size(121, 12);\n            this.lblPageCount.TabIndex = 5;\n            this.lblPageCount.Text = \"共 {0} 页 , 第\";\n            this.lblPageCount.TextAlign = System.Drawing.ContentAlignment.TopRight;\n            // \n            // dataGridView\n            // \n            this.dataGridView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)\n                        | System.Windows.Forms.AnchorStyles.Left)\n                        | System.Windows.Forms.AnchorStyles.Right)));\n            this.dataGridView.Location = new System.Drawing.Point(0, 0);\n            this.dataGridView.Name = \"dataGridView\";\n            this.dataGridView.RowTemplate.Height = 23;\n            this.dataGridView.Size = new System.Drawing.Size(550, 318);\n            this.dataGridView.TabIndex = 6;\n            // \n            // linkLabelPageEnd\n            // \n            this.linkLabelPageEnd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));\n            this.linkLabelPageEnd.AutoSize = true;\n            this.linkLabelPageEnd.Enabled = false;\n            this.linkLabelPageEnd.Location = new System.Drawing.Point(417, 10);\n            this.linkLabelPageEnd.Name = \"linkLabelPageEnd\";\n            this.linkLabelPageEnd.Size = new System.Drawing.Size(29, 12);\n            this.linkLabelPageEnd.TabIndex = 3;\n            this.linkLabelPageEnd.TabStop = true;\n            this.linkLabelPageEnd.Text = \"尾页\";\n            this.linkLabelPageEnd.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabelPageEnd_LinkClicked);\n            // \n            // linkLabelPageUp\n            // \n            this.linkLabelPageUp.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));\n            this.linkLabelPageUp.AutoSize = true;\n            this.linkLabelPageUp.Enabled = false;\n            this.linkLabelPageUp.Location = new System.Drawing.Point(457, 10);\n            this.linkLabelPageUp.Name = \"linkLabelPageUp\";\n            this.linkLabelPageUp.Size = new System.Drawing.Size(41, 12);\n            this.linkLabelPageUp.TabIndex = 1;\n            this.linkLabelPageUp.TabStop = true;\n            this.linkLabelPageUp.Text = \"上一页\";\n            this.linkLabelPageUp.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabelPageUp_LinkClicked);\n            // \n            // panelPagination\n            // \n            this.panelPagination.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)\n                        | System.Windows.Forms.AnchorStyles.Right)));\n            this.panelPagination.Controls.Add(this.lblRowCount);\n            this.panelPagination.Controls.Add(this.txtPageCurrent);\n            this.panelPagination.Controls.Add(this.lblPage);\n            this.panelPagination.Controls.Add(this.lblPageCount);\n            this.panelPagination.Controls.Add(this.linkLabelPageEnd);\n            this.panelPagination.Controls.Add(this.linkLabelPageHome);\n            this.panelPagination.Controls.Add(this.linkLabelPageUp);\n            this.panelPagination.Controls.Add(this.linkLabelPageDown);\n            this.panelPagination.Location = new System.Drawing.Point(0, 320);\n            this.panelPagination.Name = \"panelPagination\";\n            this.panelPagination.Padding = new System.Windows.Forms.Padding(10);\n            this.panelPagination.Size = new System.Drawing.Size(550, 30);\n            this.panelPagination.TabIndex = 7;\n            // \n            // linkLabelPageHome\n            // \n            this.linkLabelPageHome.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));\n            this.linkLabelPageHome.AutoSize = true;\n            this.linkLabelPageHome.Enabled = false;\n            this.linkLabelPageHome.Location = new System.Drawing.Point(377, 10);\n            this.linkLabelPageHome.Name = \"linkLabelPageHome\";\n            this.linkLabelPageHome.Size = new System.Drawing.Size(29, 12);\n            this.linkLabelPageHome.TabIndex = 2;\n            this.linkLabelPageHome.TabStop = true;\n            this.linkLabelPageHome.Text = \"首页\";\n            this.linkLabelPageHome.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabelPageHome_LinkClicked);\n            // \n            // linkLabelPageDown\n            // \n            this.linkLabelPageDown.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));\n            this.linkLabelPageDown.AutoSize = true;\n            this.linkLabelPageDown.Enabled = false;\n            this.linkLabelPageDown.Location = new System.Drawing.Point(509, 10);\n            this.linkLabelPageDown.Name = \"linkLabelPageDown\";\n            this.linkLabelPageDown.Size = new System.Drawing.Size(41, 12);\n            this.linkLabelPageDown.TabIndex = 0;\n            this.linkLabelPageDown.TabStop = true;\n            this.linkLabelPageDown.Text = \"下一页\";\n            this.linkLabelPageDown.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabelPageDown_LinkClicked);\n            // \n            // SEPaginationDataGridView\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.Controls.Add(this.dataGridView);\n            this.Controls.Add(this.panelPagination);\n            this.Name = \"SEPaginationDataGridView\";\n            this.Size = new System.Drawing.Size(550, 350);\n            ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).EndInit();\n            this.panelPagination.ResumeLayout(false);\n            this.panelPagination.PerformLayout();\n            this.ResumeLayout(false);\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.Label lblRowCount;\n        private System.Windows.Forms.TextBox txtPageCurrent;\n        private System.Windows.Forms.Label lblPage;\n        private System.Windows.Forms.Label lblPageCount;\n        private System.Windows.Forms.DataGridView dataGridView;\n        private System.Windows.Forms.LinkLabel linkLabelPageEnd;\n        private System.Windows.Forms.LinkLabel linkLabelPageUp;\n        private System.Windows.Forms.Panel panelPagination;\n        private System.Windows.Forms.LinkLabel linkLabelPageHome;\n        private System.Windows.Forms.LinkLabel linkLabelPageDown;\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengPaginationDataGridView.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Drawing;\nusing System.Data;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\n\nnamespace Sheng.Winform.Controls\n{\n    \n    public partial class ShengPaginationDataGridView : UserControl\n    {\n        /// <summary>\n        /// 导航条的位置\n        /// </summary>\n        public enum EnumNavigationLocation\n        {\n            /// <summary>\n            /// 顶部\n            /// </summary>\n            [LocalizedDescription(\"SEPaginationDataGridView_EnumNavigationLocation_Top\")]\n            Top = 0,\n            /// <summary>\n            /// 底部\n            /// </summary>\n            [LocalizedDescription(\"SEPaginationDataGridView_EnumNavigationLocation_Bottom\")]\n            Bottom = 1\n        }\n\n        /// <summary>\n        /// 是否正在绑定数据\n        /// </summary>\n        private bool _binding = false;\n        public bool Binding\n        {\n            get\n            {\n                return _binding;\n            }\n        }\n\n        private int pageCurrent;\n        /// <summary>\n        /// 当前页数\n        /// </summary>\n        public int PageCurrent\n        {\n            get\n            {\n                return pageCurrent;\n            }\n            private set\n            {\n                this.pageCurrent = value;\n            }\n        }\n\n        private int pageCount;\n        /// <summary>\n        /// 总页数\n        /// </summary>\n        public int PageCount\n        {\n            get\n            {\n                return pageCount;\n            }\n            private set\n            {\n                this.pageCount = value;\n            }\n        }\n\n        private int pageRowStart;\n        public int PageRowStart\n        {\n            get\n            {\n                return this.pageRowStart;\n            }\n            set\n            {\n                this.pageRowStart = value;\n            }\n        }\n\n        private int pageRowEnd;\n        public int PageRowEnd\n        {\n            get\n            {\n                return this.pageRowEnd;\n            }\n            set\n            {\n                this.pageRowEnd = value;\n            }\n        }\n\n        private int pageRowCount = 10;\n        /// <summary>\n        /// 每页显示条目数量 \n        /// </summary>\n        public int PageRowCount\n        {\n            get\n            {\n                return this.pageRowCount;\n            }\n            set\n            {\n                if (value < 1)\n                {\n                    value = 1;\n                }\n                else if (value > Int32.MaxValue)\n                {\n                    value = Int32.MaxValue;\n                }\n\n                this.pageRowCount = value;\n            }\n        }\n\n        private DataSet dataSet;\n        public DataSet DataSet\n        {\n            get\n            {\n                return this.dataSet;\n            }\n            protected set\n            {\n                this.dataSet = value;\n            }\n        }\n\n        private string dbCommandText;\n        /// <summary>\n        /// 针对数据源运行的文本命令\n        /// sql语句组合，以“;”分隔\n        /// 总条目数;未启用分页时的SQL;启用分页时的SQL\n        /// 后两项可选，但“;”是必需的\n        /// </summary>\n        public string DbCommandText\n        {\n            get\n            {\n                return this.dbCommandText;\n            }\n            set\n            {\n                this.dbCommandText = value;\n\n                if (value != null)\n                {\n                    string[] commandArray = this.DbCommandText.Split(';');\n                    if (commandArray.Length < 3)\n                    {\n                        throw new ArgumentException(\"针对数据源运行的文本命令设置错误\");\n                    }\n                    this.SumCommand = commandArray[0];\n                    this.ExcuteDataSetCommand = commandArray[1];\n                    this.ExcuteDataSetCommandWithPagination = commandArray[2];\n                }\n            }\n        }\n\n        private string sumCommand;\n        /// <summary>\n        /// 求总页数sql\n        /// </summary>\n        public string SumCommand\n        {\n            get\n            {\n                return this.sumCommand;\n            }\n            set\n            {\n                this.sumCommand = value;\n            }\n        }\n\n        private string excuteDataSetCommand;\n        /// <summary>\n        /// 未启用分页时取数据sql\n        /// </summary>\n        public string ExcuteDataSetCommand\n        {\n            get\n            {\n                return this.excuteDataSetCommand;\n            }\n            set\n            {\n                this.excuteDataSetCommand = value;\n            }\n        }\n\n        private string excuteDataSetCommandWithPagination;\n        /// <summary>\n        /// 启用分页时取数据sql\n        /// </summary>\n        public string ExcuteDataSetCommandWithPagination\n        {\n            get\n            {\n                return this.excuteDataSetCommandWithPagination;\n            }\n            set\n            {\n                this.excuteDataSetCommandWithPagination = value;\n            }\n        }\n\n        public DataGridView DataGridView\n        {\n            get\n            {\n                return this.dataGridView;\n            }\n        }\n\n        private EnumNavigationLocation navigationLocation =\n            EnumNavigationLocation.Bottom;\n        /// <summary>\n        /// 页导航位置\n        /// </summary>\n        public EnumNavigationLocation NavigationLocation\n        {\n            get\n            {\n                return this.navigationLocation;\n            }\n            set\n            {\n                this.navigationLocation = value;\n\n                //this.Pagination = this.Pagination;\n\n                this.SuspendLayout();\n\n                if (value == EnumNavigationLocation.Top)\n                {\n                    this.panelPagination.Anchor = ((System.Windows.Forms.AnchorStyles)\n                        (((System.Windows.Forms.AnchorStyles.Top |\n                        System.Windows.Forms.AnchorStyles.Left) |\n                        System.Windows.Forms.AnchorStyles.Right)));\n                    this.panelPagination.Location = new Point(0, 0);\n                    this.dataGridView.Location = new Point(0, this.panelPagination.Height + this.panelPagination.Margin.Bottom);\n                }\n                else\n                {\n                    this.panelPagination.Anchor = ((System.Windows.Forms.AnchorStyles)\n                        (((System.Windows.Forms.AnchorStyles.Bottom |\n                        System.Windows.Forms.AnchorStyles.Left) |\n                        System.Windows.Forms.AnchorStyles.Right)));\n                    this.panelPagination.Location = new Point(0, this.dataGridView.Height + this.dataGridView.Margin.Bottom);\n                    this.dataGridView.Location = new Point(0, 0);\n                }\n\n                if (this.Pagination)\n                {\n                    this.dataGridView.Height = this.Height - this.panelPagination.Height - this.panelPagination.Margin.Top;\n                }\n                else\n                {\n                    this.dataGridView.Height = this.Height;\n                }\n\n                this.ResumeLayout();\n            }\n        }\n\n        private bool pagination = true;\n        /// <summary>\n        /// 是否分页\n        /// </summary>\n        public bool Pagination\n        {\n            get\n            {\n                return this.pagination;\n            }\n            set\n            {\n                this.pagination = value;\n\n                if (Pagination)\n                {\n                    this.panelPagination.Visible = true;\n                    this.dataGridView.Height = this.Height - this.panelPagination.Height - this.panelPagination.Margin.Top;\n                }\n                else\n                {\n                    this.panelPagination.Visible = false;\n                    this.dataGridView.Height = this.Height;\n                }\n            }\n        }\n\n        private bool showItemCount = true;\n        /// <summary>\n        /// 是否显示条目数\n        /// </summary>\n        public bool ShowItemCount\n        {\n            get\n            {\n                return this.showItemCount;\n            }\n            set\n            {\n                this.showItemCount = value;\n\n                this.lblRowCount.Visible = value;\n            }\n        }\n\n        private bool showPageCount = true;\n        /// <summary>\n        /// 是否显示页数\n        /// </summary>\n        public bool ShowPageCount\n        {\n            get\n            {\n                return this.showPageCount;\n            }\n            set\n            {\n                this.showPageCount = value;\n\n                this.lblPageCount.Visible = value;\n                this.txtPageCurrent.Visible = value;\n                this.lblPage.Visible = value;\n            }\n        }\n\n        private bool showPageHomeEnd = true;\n        /// <summary>\n        /// 是否显示首页尾页\n        /// </summary>\n        public bool ShowPageHomeEnd\n        {\n            get\n            {\n                return this.showPageHomeEnd;\n            }\n            set\n            {\n                this.showPageHomeEnd = value;\n\n                this.linkLabelPageHome.Visible = value;\n                this.linkLabelPageEnd.Visible = value;\n            }\n        }\n\n        public ShengPaginationDataGridView()\n        {\n\n            InitializeComponent();\n\n            ResetNavigation();\n        }\n\n        /// <summary>\n        /// 执行绑定数据\n        /// </summary>\n        public void DataBind()\n        {\n            _binding = true;\n\n            pageCurrent = 1;\n            pageCount = 0;\n\n            DataBinding();\n\n            _binding = false;\n        }\n\n        /// <summary>\n        /// 刷新数据列表\n        /// 当前分页状态保留\n        /// </summary>\n        public void RefreshData()\n        {\n            DataBinding();\n        }\n\n        /// <summary>\n        /// 在当前分页（如果启用）设置下执行数据加载\n        /// 在shell中重写,因为获取数据涉及到与数据库交互\n        /// </summary>\n        private void DataBinding()\n        {\n            PageRowStart = (this.PageCurrent - 1) * this.PageRowCount + 1;\n            PageRowEnd = this.PageRowCount * this.PageCurrent;\n\n            this.GetDataSet();\n\n            this.DataGridView.DataSource = this.DataSet.Tables[0];\n\n            if (Pagination)\n            {\n                int rowCount = 0;\n\n                rowCount = this.GetRowCount(); //(int)RemoteObject.DataBaseOperator.ExecuteScalar(this.SumCommand);\n\n                PageCount = rowCount / this.PageRowCount;\n                if (rowCount % PageRowCount > 0)\n                {\n                    PageCount++;\n                }\n\n                //如果在删除当前页的最后一条数据后调用了刷新方法\n                //那么当前页就是多余的了（多出的一页）\n                if (this.PageCurrent > this.PageCount)\n                {\n                    this.PageCurrent = this.PageCount;\n                    DataBinding();\n                }\n\n                lblRowCount.Text = String.Format(\"共 {0} 条 , 每页 {1} 条\",\n                    rowCount, this.PageRowCount);\n\n                lblPageCount.Text = String.Format(\"共 {0} 页 , 第\", PageCount);\n\n                this.txtPageCurrent.Text = this.PageCurrent.ToString();\n\n                SetPageLink();\n            }\n        }\n\n        #region 导航条事件\n\n        /// <summary>\n        /// 重置导航条状态\n        /// </summary>\n        protected void ResetNavigation()\n        {\n            this.lblPageCount.Text = String.Empty;\n            this.lblRowCount.Text = String.Empty;\n\n            this.txtPageCurrent.Text = String.Empty;\n            this.txtPageCurrent.Enabled = false;\n\n            this.linkLabelPageHome.Enabled = false;\n            this.linkLabelPageEnd.Enabled = false;\n            this.linkLabelPageUp.Enabled = false;\n            this.linkLabelPageDown.Enabled = false;\n        }\n\n        /// <summary>\n        /// 设置导航按钮状态\n        /// </summary>\n        private void SetPageLink()\n        {\n            this.txtPageCurrent.Enabled = true;\n\n            if (pageCount > 1)\n            {\n                this.linkLabelPageHome.Enabled = true;\n                this.linkLabelPageEnd.Enabled = true;\n                this.linkLabelPageUp.Enabled = true;\n                this.linkLabelPageDown.Enabled = true;\n\n                if (this.pageCurrent == 1)\n                {\n                    this.linkLabelPageHome.Enabled = false;\n                    this.linkLabelPageUp.Enabled = false;\n                }\n\n                if (this.pageCurrent == pageCount)\n                {\n                    this.linkLabelPageEnd.Enabled = false;\n                    this.linkLabelPageDown.Enabled = false;\n                }\n            }\n            else\n            {\n                this.linkLabelPageHome.Enabled = false;\n                this.linkLabelPageEnd.Enabled = false;\n                this.linkLabelPageUp.Enabled = false;\n                this.linkLabelPageDown.Enabled = false;\n            }\n        }\n\n        private void linkLabelPageHome_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)\n        {\n            this.pageCurrent = 1;\n            DataBinding();\n        }\n\n        private void linkLabelPageEnd_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)\n        {\n            this.pageCurrent = this.pageCount;\n            DataBinding();\n        }\n\n        private void linkLabelPageUp_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)\n        {\n            this.pageCurrent--;\n            DataBinding();\n        }\n\n        private void linkLabelPageDown_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)\n        {\n            this.pageCurrent++;\n            DataBinding();\n        }\n\n        private void txtPageCurrent_KeyPress(object sender, KeyPressEventArgs e)\n        {\n            if (e.KeyChar == (char)Keys.Enter)\n            {\n                int newPageCurrent;\n                if (Int32.TryParse(txtPageCurrent.Text, out newPageCurrent))\n                {\n                    if (newPageCurrent > this.pageCount)\n                    {\n                        this.pageCurrent = this.pageCount;\n                    }\n                    else if (newPageCurrent < 1)\n                    {\n                        this.pageCurrent = 1;\n                    }\n                    else\n                    {\n                        this.pageCurrent = Int32.Parse(txtPageCurrent.Text);\n                    }\n\n                    DataBinding();\n                }\n                else\n                {\n                    txtPageCurrent.Text = this.pageCurrent.ToString();\n                }\n            }\n        }\n\n        #endregion\n\n        protected virtual void GetDataSet()\n        {\n\n        }\n\n        protected virtual int GetRowCount()\n        {\n            return 0;\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengPaginationDataGridView.resx",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n</root>"
  },
  {
    "path": "Sheng.Winform.Controls/ShengPanel.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Reflection;\nusing System.Drawing;\nusing System.ComponentModel;\nusing System.Drawing.Drawing2D;\n\nnamespace Sheng.Winform.Controls\n{\n    \n    public class ShengPanel : Panel, IShengValidate\n    {\n        #region \n\n        private bool showBorder = false;\n        /// <summary>\n        /// Ƿʾ߿\n        /// </summary>\n        public bool ShowBorder\n        {\n            get\n            {\n                return this.showBorder;\n            }\n            set\n            {\n                this.showBorder = value;\n\n                InitBrush();\n                InitPen();\n\n                this.Invalidate();\n            }\n        }\n\n        private Color borderColor = Color.Black;\n        /// <summary>\n        /// ߿ɫ\n        /// </summary>\n        public Color BorderColor\n        {\n            get\n            {\n                return this.borderColor;\n            }\n            set\n            {\n                this.borderColor = value;\n\n                InitPen();\n            }\n        }\n\n        private Color fillColorStart;\n        /// <summary>\n        /// ɫ(ʼ)\n        /// ǵɫ,ʹôɫ\n        /// </summary>\n        public Color FillColorStart\n        {\n            get\n            {\n                if (this.fillColorStart == null)\n                {\n                    this.fillColorStart = this.Parent.BackColor;\n                }\n                return this.fillColorStart;\n            }\n            set\n            {\n                this.fillColorStart = value;\n\n                InitBrush();\n            }\n        }\n\n        private Color fillColorEnd;\n        /// <summary>\n        /// ɫ\n        /// </summary>\n        public Color FillColorEnd\n        {\n            get\n            {\n                if (this.fillColorEnd == null)\n                {\n                    this.fillColorEnd = this.Parent.BackColor;\n                }\n\n                return this.fillColorEnd;\n            }\n            set\n            {\n                this.fillColorEnd = value;\n\n                InitBrush();\n            }\n        }\n\n        private Brush fillBrush;\n        /// <summary>\n        /// \n        /// </summary>\n        public Brush FillBrush\n        {\n            get\n            {\n                return this.fillBrush;\n            }\n            set\n            {\n                this.fillBrush = value;\n                this.Invalidate();\n            }\n        }\n\n        private Pen borderPen;\n        /// <summary>\n        /// ߿򻭱\n        /// </summary>\n        public Pen BorderPen\n        {\n            get\n            {\n                return this.borderPen;\n            }\n            set\n            {\n                this.borderPen = value;\n                this.Invalidate();\n            }\n        }\n\n        private FillStyle fillStyle = FillStyle.Solid;\n        /// <summary>\n        /// ʽ\n        /// ɫ򽥱\n        /// </summary>\n        public FillStyle FillStyle\n        {\n            get\n            {\n                return this.fillStyle;\n            }\n            set\n            {\n                this.fillStyle = value;\n\n                InitBrush();\n            }\n        }\n\n        private LinearGradientMode fillMode;\n        /// <summary>\n        /// ģʽ\n        /// ǽ,ĸĽѡһ\n        /// </summary>\n        public LinearGradientMode FillMode\n        {\n            get\n            {\n                return this.fillMode;\n            }\n            set\n            {\n                this.fillMode = value;\n\n                InitBrush();\n            }\n        }\n\n        #endregion\n\n        #region ˽гԱ\n\n        /// <summary>\n        /// Rectangle\n        /// </summary>\n        private Rectangle FillRectangle\n        {\n            get\n            {\n                if (this.ClientRectangle == new Rectangle())\n                {\n                    return new Rectangle(0, 0, 1, 1);\n                }\n\n                Rectangle rect;\n\n                if (this.ShowBorder)\n                {\n                    rect = new Rectangle(1, 1, this.ClientRectangle.Width - 1, this.ClientRectangle.Height - 1);\n                }\n                else\n                {\n                    rect = this.ClientRectangle;\n                }\n\n                if (rect.Width == 0)\n                {\n                    rect.Width++;\n                }\n                if (rect.Height == 0)\n                {\n                    rect.Height++;\n                }\n\n                return rect;\n            }\n        }\n\n        /// <summary>\n        /// Rectangle\n        /// </summary>\n        private Rectangle DrawRectangle\n        {\n            get\n            {\n                if (this.ClientRectangle == new Rectangle())\n                {\n                    return new Rectangle(0, 0, 1, 1);\n                }\n\n                return new Rectangle(0, 0, this.ClientRectangle.Width - 1, this.ClientRectangle.Height - 1);\n            }\n        }\n\n        #endregion\n\n        #region \n\n        public ShengPanel()\n        {\n\n            EnableDoubleBuffering();\n\n            this.FillBrush = new SolidBrush(this.FillColorStart);\n            this.BorderPen = new Pen(this.BorderColor);;\n        }\n\n        #endregion\n\n        #region ˽з\n\n        /// <summary>\n        /// ˫\n        /// </summary>\n        private void EnableDoubleBuffering()\n        {\n            // Set the value of the double-buffering style bits to true.\n            this.SetStyle(ControlStyles.DoubleBuffer |\n               ControlStyles.UserPaint |\n               ControlStyles.AllPaintingInWmPaint,\n               true);\n            this.UpdateStyles();\n        }\n\n        /// <summary>\n        /// ʼPen\n        /// </summary>\n        private void InitPen()\n        {\n            if (this.ShowBorder)\n            {\n                this.BorderPen = new Pen(this.BorderColor);\n            }\n        }\n\n        /// <summary>\n        /// ʼBrush\n        /// </summary>\n        private void InitBrush()\n        {\n            if (this.FillStyle == FillStyle.Solid)\n            {\n                this.FillBrush = new SolidBrush(this.FillColorStart);\n            }\n            else\n            {\n                this.FillBrush = new LinearGradientBrush(this.FillRectangle, this.FillColorStart, this.FillColorEnd, this.FillMode);\n            }\n        }\n\n        /// <summary>\n        /// ƿؼ\n        /// </summary>\n        /// <param name=\"e\"></param>\n        protected override void OnPaint(PaintEventArgs e)\n        {\n            //base.OnPaint(e);\n\n            e.Graphics.FillRectangle(this.FillBrush, this.FillRectangle);\n\n            if (this.ShowBorder)\n            {\n                e.Graphics.DrawRectangle(this.BorderPen, this.DrawRectangle);\n            }\n        }\n\n        /// <summary>\n        /// Сı\n        /// </summary>\n        /// <param name=\"e\"></param>\n        protected override void OnResize(EventArgs e)\n        {\n\n            base.OnResize(e);\n\n            if (this.Height <= 0 || this.Width <= 0)\n            {\n                return;\n            }\n\n            InitBrush();\n            InitPen();\n\n            this.Invalidate();\n        }\n\n        #endregion\n\n        #region ISEValidate Ա\n\n        private string title;\n        /// <summary>\n        /// \n        /// </summary>\n        [Description(\"\")]\n        [Category(\"Sheng.Winform.Controls\")]\n        public string Title\n        {\n            get\n            {\n                return this.title;\n            }\n            set\n            {\n                this.title = value;\n            }\n        }\n\n        private bool highLight = false;\n        /// <summary>\n        /// ֤ʧʱǷҪʾı䱳ɫ\n        /// </summary>\n        [Description(\"֤ʧʱǷҪʾı䱳ɫ\")]\n        [Category(\"Sheng.Winform.Controls\")]\n        public bool HighLight\n        {\n            get\n            {\n                return this.highLight;\n            }\n            set\n            {\n                this.highLight = value;\n            }\n        }\n\n        /// <summary>\n        /// ֤ؼ\n        /// </summary>\n        /// <param name=\"validateMsg\"></param>\n        /// <returns></returns>\n        public bool SEValidate(out string validateMsg)\n        {\n            return ShengValidateHelper.ValidateContainerControl(this, out validateMsg);\n        }\n\n        public CustomValidateMethod CustomValidate\n        {\n            get;\n            set;\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengSimpleCheckBox.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Drawing;\nusing System.ComponentModel;\n\nnamespace Sheng.Winform.Controls\n{\n    \n    public class ShengSimpleCheckBox:Control\n    {\n        private Graphics graphics;\n\n        private bool check = false;\n        public bool Check\n        {\n            get\n            {\n                return this.check;\n            }\n            set\n            {\n                this.check = value;\n            }\n        }\n\n        public ShengSimpleCheckBox()\n        {\n\n            this.SetStyle(ControlStyles.UserPaint, true);\n            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);\n            this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);\n            this.SetStyle(ControlStyles.ResizeRedraw, true);\n            this.SetStyle(ControlStyles.Selectable, true);\n        }\n\n        protected override void OnPaint(PaintEventArgs e)\n        {\n            base.OnPaint(e);\n            graphics = e.Graphics;\n\n            //绘制填充色\n            if (this.Check)\n            {\n                graphics.Clear(Color.SkyBlue);\n            }\n            else\n            {\n                graphics.Clear(Color.White);\n            }\n\n            //绘制边框\n            graphics.DrawRectangle(Pens.Black, 0, 0, this.Width - 1, this.Height - 1);\n\n            //绘制聚焦框\n            if (this.ShowFocusCues && this.Focused)\n            {\n                ControlPaint.DrawFocusRectangle(graphics,new Rectangle(2,2,this.Width-4,this.Height-4));\n            }\n        }\n\n        protected override void OnClick(EventArgs e)\n        {\n            base.OnClick(e);\n\n            this.Select();\n\n            this.Check = !this.Check;\n\n            this.Invalidate();\n        }\n\n        protected override void OnEnter(EventArgs e)\n        {\n            base.OnEnter(e);\n            this.Invalidate();\n        }\n\n        protected override void OnLeave(EventArgs e)\n        {\n            base.OnLeave(e);\n            this.Invalidate();\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengTabControl.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Reflection;\nusing System.Drawing;\nusing System.ComponentModel;\n\nnamespace Sheng.Winform.Controls\n{\n    \n    public class ShengTabControl : TabControl, IShengValidate\n    {\n        #region \n\n        public ShengTabControl()\n        {\n            \n        }\n\n        #endregion\n\n        #region ISEValidate Ա\n\n        private string title;\n        /// <summary>\n        /// \n        /// </summary>\n        [Description(\"\")]\n        [Category(\"Sheng.Winform.Controls\")]\n        public string Title\n        {\n            get\n            {\n                return this.title;\n            }\n            set\n            {\n                this.title = value;\n            }\n        }\n\n        private bool highLight = false;\n        /// <summary>\n        /// ֤ʧʱǷҪʾı䱳ɫ\n        /// </summary>\n        [Description(\"֤ʧʱǷҪʾı䱳ɫ\")]\n        [Category(\"Sheng.Winform.Controls\")]\n        public bool HighLight\n        {\n            get\n            {\n                return this.highLight;\n            }\n            set\n            {\n                this.highLight = value;\n            }\n        }\n\n        /// <summary>\n        /// ֤ؼ\n        /// </summary>\n        /// <param name=\"validateMsg\"></param>\n        /// <returns></returns>\n        public bool SEValidate(out string validateMsg)\n        {\n            bool validateResult = true;\n            string tabValidateMsg;\n            validateMsg = String.Empty;\n\n            foreach (TabPage tabPage in this.TabPages)\n            {\n                if (ShengValidateHelper.ValidateContainerControl(tabPage, out tabValidateMsg) == false)\n                {\n                    validateMsg += tabValidateMsg;\n                    validateResult = false;\n                }\n            }\n\n            return validateResult;\n        }\n\n        public CustomValidateMethod CustomValidate\n        {\n            get;\n            set;\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengTextBox.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Text.RegularExpressions;\nusing System.ComponentModel;\nusing System.Drawing;\nusing Sheng.Winform.Controls.Win32;\n\nnamespace Sheng.Winform.Controls\n{\n    \n    public class ShengTextBox : TextBox, IShengValidate\n    {\n        #region \n\n        public ShengTextBox()\n        {\n       }\n\n        #endregion\n\n        #region \n\n        private bool allowEmpty = true;\n        /// <summary>\n        /// Ƿ\n        /// </summary>\n        [Description(\"Ƿ\")]\n        [Category(\"Sheng.Winform.Controls\")]\n        public bool AllowEmpty\n        {\n            get\n            {\n                return this.allowEmpty;\n            }\n            set\n            {\n                this.allowEmpty = value;\n            }\n        }\n\n\n\n        private string waterText = String.Empty;\n        /// <summary>\n        /// ˮӡı\n        /// </summary>\n        [Description(\"ˮӡı\")]\n        [Category(\"Sheng.Winform.Controls\")]\n        public string WaterText\n        {\n            get { return this.waterText; }\n            set\n            {\n                this.waterText = value;\n                this.Invalidate();\n            }\n        }\n\n        private string regex = String.Empty;\n        /// <summary>\n        /// Ҫƥʽ\n        /// </summary>\n        [Description(\"Ҫƥʽ\")]\n        [Category(\"Sheng.Winform.Controls\")]\n        public string Regex\n        {\n            get\n            {\n                if (this.regex == null)\n                {\n                    this.regex = String.Empty;\n                }\n                return this.regex;\n            }\n            set\n            {\n                this.regex = value;\n            }\n        }\n\n        private string regexMsg;\n        /// <summary>\n        /// ֤ͨʱʾϢ\n        /// </summary>\n        [Description(\"֤ͨʱʾϢ\")]\n        [Category(\"Sheng.Winform.Controls\")]\n        public string RegexMsg\n        {\n            get\n            {\n                return this.regexMsg;\n            }\n            set\n            {\n                this.regexMsg = value;\n            }\n        }\n\n\n\n        private ShengTextBox valueCompareTo;\n        /// <summary>\n        /// ָSETextBoxֵȽϣͬ\n        /// \n        /// </summary>\n        [Description(\"ָSETextBoxֵȽϣͬ\")]\n        [Category(\"Sheng.Winform.Controls\")]\n        public ShengTextBox ValueCompareTo\n        {\n            get\n            {\n                return this.valueCompareTo;\n            }\n            set\n            {\n                this.valueCompareTo = value;\n            }\n        }\n\n        private bool limitMaxValue = false;\n        /// <summary>\n        /// ֵֻ,Ƿֵ\n        /// </summary>\n        [Description(\"ֵֻ,Ƿֵ\")]\n        [Category(\"Sheng.Winform.Controls\")]\n        public bool LimitMaxValue\n        {\n            get { return this.limitMaxValue; }\n            set { this.limitMaxValue = value; }\n        }\n\n        private long maxValue = Int32.MaxValue;\n        /// <summary>\n        /// ֵֻ,ֵ\n        /// </summary>\n        [Description(\"ֵֻ,ֵ\")]\n        [Category(\"Sheng.Winform.Controls\")]\n        public long MaxValue\n        {\n            get { return this.maxValue; }\n            set { this.maxValue = value; }\n        }\n\n        #endregion\n\n        #region ˽з\n\n        protected override void WndProc(ref   Message m)\n        {\n            base.WndProc(ref   m);\n\n            if (m.Msg == User32.WM_PAINT || m.Msg == User32.WM_ERASEBKGND || m.Msg == User32.WM_NCPAINT)\n            {\n                if (!this.Focused && this.Text == String.Empty && this.WaterText != String.Empty)\n                {\n                    Graphics g = Graphics.FromHwnd(this.Handle);\n                    g.DrawString(this.WaterText, this.Font, Brushes.Gray, this.ClientRectangle);\n                }\n            }\n        }\n\n        #endregion\n\n        #region \n\n\n        #endregion\n\n        #region ISEValidate Ա\n\n        private string title;\n        /// <summary>\n        /// \n        /// </summary>\n        [Description(\"\")]\n        [Category(\"Sheng.Winform.Controls\")]\n        public string Title\n        {\n            get\n            {\n                return this.title;\n            }\n            set\n            {\n                this.title = value;\n            }\n        }\n\n        private bool highLight = true;\n        /// <summary>\n        /// ֤ʧʱǷҪʾı䱳ɫ\n        /// </summary>\n        [Description(\"֤ʧʱǷҪʾı䱳ɫ\")]\n        [Category(\"Sheng.Winform.Controls\")]\n        public bool HighLight\n        {\n            get\n            {\n                return this.highLight;\n            }\n            set\n            {\n                this.highLight = value;\n            }\n        }\n\n        /// <summary>\n        /// ֤ؼ\n        /// </summary>\n        /// <returns></returns>\n        public bool SEValidate(out string msg)\n        {\n            msg = String.Empty;\n\n            #region ǷΪ\n\n            if (!this.AllowEmpty && this.Text == \"\")\n            {\n                msg += String.Format(\"[ {0} ] {1}\", this.Title, \"Ϊ\");\n                return false;\n            }\n\n            #endregion\n\n            #region \n\n            if (this.Text != \"\" && this.Regex != String.Empty)\n            {\n                System.Text.RegularExpressions.Regex r = new Regex(this.Regex, RegexOptions.Singleline);\n                Match m = r.Match(this.Text);\n                if (m.Success == false)\n                {\n                    msg += String.Format(\"[ {0} ] {1}\", this.Title, this.RegexMsg);\n                    return false;\n                }\n            }\n\n            #endregion\n\n            #region ֵΧ\n\n            if (LimitMaxValue && this.Text != String.Empty)\n            {\n                Regex regex = new Regex(@\"^\\d+$\");\n                Match match = regex.Match(this.Text);\n                if (match.Success)\n                {\n                    long value = Int64.Parse(this.Text);\n                    if (value > this.MaxValue)\n                    {\n                        msg += String.Format(\"[ {0} ] {1}\", this.Title, \"ܴ \" + this.MaxValue.ToString());\n                        return false;\n                    }\n                }\n            }\n\n            #endregion\n\n            #region CompareTo\n\n            if (this.ValueCompareTo != null)\n            {\n                if (this.Text != this.ValueCompareTo.Text)\n                {\n                    msg += String.Format(\"[ {0} ]  [ {1} ] {2}\", this.Title, this.ValueCompareTo.Title, \"ݱͬ\");\n                    this.ValueCompareTo.BackColor = Color.Pink;\n                    return false;\n                }\n            }\n\n            #endregion\n\n            #region CustomValidate\n\n            if (CustomValidate != null)\n            {\n                string customValidateMsg;\n                if (CustomValidate(this, out customValidateMsg) == false)\n                {\n                    msg += String.Format(\"[ {0} ] {1}\", this.Title, customValidateMsg);\n                    return false;\n                }\n            }\n\n            #endregion\n\n            msg = String.Empty;\n            return true;\n        }\n\n        public CustomValidateMethod CustomValidate\n        {\n            get;\n            set;\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengThumbnailImageListView.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Drawing;\nusing System.Windows.Forms;\nusing System.IO;\nusing System.Drawing.Drawing2D;\nusing Sheng.Winform.Controls.Drawing;\n\nnamespace Sheng.Winform.Controls\n{\n    \n    public class ShengThumbnailImageListView : ListView\n    {\n        /// <summary>\n        /// 用于加载图像的后台线程\n        /// </summary>\n        private BackgroundWorker imageLoadBackgroundWork = new BackgroundWorker();\n        \n        private int thumbNailSize = 95;\n        /// <summary>\n        /// 缩略图大小\n        /// </summary>\n        public int ThumbNailSize\n        {\n            get { return thumbNailSize; }\n            set { thumbNailSize = value; }\n        }\n\n        private Color thumbBorderColor = Color.White;\n        /// <summary>\n        /// 缩略图边框颜色\n        /// </summary>\n        public Color ThumbBorderColor\n        {\n            get { return thumbBorderColor; }\n            set { thumbBorderColor = value; }\n        }\n\n        /// <summary>\n        /// 是否正处在载入状态\n        /// </summary>\n        public bool IsLoading\n        {\n            get { return imageLoadBackgroundWork.IsBusy; }\n        }\n\n        private string folder;\n        /// <summary>\n        /// 要查看的文件夹\n        /// </summary>\n        public string Folder\n        {\n            get { return folder; }\n            set\n            {\n                if (value == null || value == String.Empty)\n                {\n                    return;\n                }\n\n                if (!Directory.Exists(value))\n                    throw new DirectoryNotFoundException();\n                folder = value;\n                ReLoadItems();\n            }\n        }\n\n        private string _filter = \"*.jpg|*.png|*.gif|*.bmp\";\n        /// <summary>\n        /// 文件类型过滤器\n        /// </summary>\n        public string Filter\n        {\n            get\n            {\n                return this._filter;\n            }\n            set\n            {\n                this._filter = value;\n            }\n        }\n\n        /// <summary>\n        /// 构造 \n        /// </summary>\n        public ShengThumbnailImageListView()\n        {\n\n            ImageList il = new ImageList();\n            il.ImageSize = new Size(thumbNailSize, thumbNailSize);\n            il.ColorDepth = ColorDepth.Depth32Bit;\n            // il.TransparentColor = Color.White;\n            LargeImageList = il;\n            imageLoadBackgroundWork.WorkerSupportsCancellation = true;\n            imageLoadBackgroundWork.DoWork += new DoWorkEventHandler(bwLoadImages_DoWork);\n            imageLoadBackgroundWork.RunWorkerCompleted += new RunWorkerCompletedEventHandler(myWorker_RunWorkerCompleted);\n\n        }\n\n        private delegate void SetThumbnailDelegate(Image image);\n        /// <summary>\n        /// 向listview中添加一幅缩略图\n        /// </summary>\n        /// <param name=\"image\"></param>\n        private void SetThumbnail(Image image)\n        {\n            if (Disposing) return;\n\n            if (this.InvokeRequired)\n            {\n                SetThumbnailDelegate d = new SetThumbnailDelegate(SetThumbnail);\n                this.Invoke(d, new object[] { image });\n            }\n            else\n            {\n                LargeImageList.Images.Add(image); //Images[i].repl  \n                int index = LargeImageList.Images.Count - 1;\n                Items[index - 1].ImageIndex = index;\n            }\n        }\n\n        /// <summary>\n        /// 获取文件的缩略图\n        /// </summary>\n        /// <param name=\"fileName\"></param>\n        /// <returns></returns>\n        public Image GetThumbNail(string fileName)\n        {\n            Bitmap bmp;\n\n            try\n            {\n                bmp = (Bitmap)DrawingTool.GetImage(fileName);\n            }\n            catch\n            {\n                bmp = new Bitmap(ThumbNailSize, ThumbNailSize); //If we cant load the image, create a blank one with ThumbSize\n            }\n\n            bmp = (Bitmap)DrawingTool.GetScaleImage(bmp, ThumbNailSize, ThumbNailSize);\n\n            if (bmp.Width < ThumbNailSize || bmp.Height < ThumbNailSize)\n            {\n                Bitmap bitmap2 = new Bitmap(ThumbNailSize, ThumbNailSize);\n\n                Graphics g = Graphics.FromImage(bitmap2);\n                Point point = new Point();\n                point.X = (ThumbNailSize - bmp.Width) / 2;\n                point.Y = (ThumbNailSize - bmp.Height) / 2;\n                g.DrawImage(bmp, point);\n                g.Dispose();\n                bmp.Dispose();\n\n                return bitmap2;\n            }\n\n            return bmp;\n        }\n\n        /// <summary>\n        /// 向图像集合中添加默认(空白)图像\n        /// </summary>\n        private void AddDefaultThumb()\n        {\n            Bitmap bmp = new Bitmap(LargeImageList.ImageSize.Width, LargeImageList.ImageSize.Height, \n                System.Drawing.Imaging.PixelFormat.Format32bppRgb);\n            Graphics grp = Graphics.FromImage(bmp);\n            grp.Clear(Color.White);\n            //Brush brs = new SolidBrush(Color.White);\n            //Rectangle rect = new Rectangle(0, 0, bmp.Width - 1, bmp.Height - 1);\n            //grp.FillRectangle(brs, rect);\n            //Pen pn = new Pen(this.ThumbBorderColor, 1);\n\n            //grp.DrawRectangle(pn, 0, 0, bmp.Width - 1, bmp.Height - 1);\n            LargeImageList.Images.Add(bmp);\n        }\n      \n        /// <summary>\n        /// 加载图片\n        /// </summary>\n        /// <param name=\"fileList\"></param>\n        public void LoadItems(string[] fileList)\n        {\n            if ((imageLoadBackgroundWork != null) && (imageLoadBackgroundWork.IsBusy))\n                imageLoadBackgroundWork.CancelAsync();\n\n            BeginUpdate();\n            Items.Clear();\n            LargeImageList.Images.Clear();\n            AddDefaultThumb();\n\n            foreach (string fileName in fileList)\n            {\n                ListViewItem liTemp = Items.Add(System.IO.Path.GetFileName(fileName));\n                liTemp.ImageIndex = 0;\n                liTemp.Tag = fileName;\n            }\n\n            EndUpdate();\n            if (imageLoadBackgroundWork != null)\n            {\n                if (!imageLoadBackgroundWork.CancellationPending)\n                {\n                    if (OnLoadStart != null)\n                        OnLoadStart(this, new EventArgs());\n\n                    imageLoadBackgroundWork.RunWorkerAsync(fileList);\n                }\n            }\n        }\n\n        /// <summary>\n        /// 加载图片\n        /// </summary>\n        private void ReLoadItems()\n        {\n            List<string> fileList = new List<string>();\n            string[] arExtensions = Filter.Split('|');\n\n            foreach (string filter in arExtensions)\n            {\n                string[] strFiles = Directory.GetFiles(folder, filter);\n                fileList.AddRange(strFiles);\n            }\n\n            fileList.Sort();\n            LoadItems(fileList.ToArray());\n\n        }\n\n        #region 用于加载图片的后台线程事件\n\n        private void bwLoadImages_DoWork(object sender, DoWorkEventArgs e)\n        {\n            if (imageLoadBackgroundWork.CancellationPending) return;\n\n            string[] fileList = (string[])e.Argument;\n\n            foreach (string fileName in fileList)\n                SetThumbnail(GetThumbNail(fileName));\n        }\n\n        void myWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)\n        {\n            if (OnLoadComplete != null)\n                OnLoadComplete(this, new EventArgs());\n        }\n\n        #endregion\n\n        #region 公开事件\n\n        /// <summary>\n        /// 图片加载完成\n        /// </summary>\n        public event EventHandler OnLoadComplete;\n\n        /// <summary>\n        /// 图片开始加载\n        /// </summary>\n        public event EventHandler OnLoadStart;\n\n        #endregion\n\n        #region 公开方法\n\n        /// <summary>\n        /// 添加一幅缩略图,如果已存在则替换\n        /// </summary>\n        /// <param name=\"imageFile\"></param>\n        public void Add(string imageFile)\n        {\n            //判断图像是否已存在\n            for (int i = 0; i < this.Items.Count; i++)\n            {\n                if (this.Items[i].Tag.ToString().Equals(imageFile))\n                {\n                    //+1是因为第1副图是一个空白的默认图,与列表中项目对应的图应从下标1开始\n                    this.LargeImageList.Images[i + 1] = GetThumbNail(imageFile);\n                    this.Invalidate(this.Items[i].GetBounds(ItemBoundsPortion.Entire));\n                    return;\n                }\n            }\n\n            //不存在,则添加新的 \n            ListViewItem liTemp = Items.Add(System.IO.Path.GetFileName(imageFile));\n            liTemp.ImageIndex = 0;\n            liTemp.Tag = imageFile;\n\n            SetThumbnail(GetThumbNail(imageFile));\n        }\n\n        #endregion\n\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengToolStrip.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Drawing;\nusing System.Runtime.Serialization;\nusing System.Windows.Forms;\nusing Sheng.Winform.Controls.Drawing;\n\nnamespace Sheng.Winform.Controls\n{\n    /// <summary>\n    /// SEToolStrip 上的图像尺寸\n    /// </summary>\n    public enum ShengToolStripImageSize\n    {\n        /// <summary>\n        /// An image of 16x16 pixels.\n        /// </summary>\n        [LocalizedDescription(\"SEToolStripImageSize_Small\")]\n        Small,\n        /// <summary>\n        /// An image of 24x24 pixels.\n        /// </summary>\n        [LocalizedDescription(\"SEToolStripImageSize_Medium\")]\n        Medium,\n        /// <summary>\n        /// An image of 32x32 pixels.\n        /// </summary>\n        [LocalizedDescription(\"SEToolStripImageSize_Large\")]\n        Large,\n        /// <summary>\n        /// An image of 48x48 pixels.\n        /// </summary>\n        [LocalizedDescription(\"SEToolStripImageSize_ExtraLarge\")]\n        ExtraLarge,\n    }\n\n    /// <summary>\n    /// Implementations of this interface must indicate whether or not the\n    /// requested image size is supported. A default image override could\n    /// be enforced should the provider report with no support.\n    /// </summary>\n    public interface IShengToolStripImageProvider\n    {\n        #region Methods\n\n        /// <summary>\n        /// Queries the image provider for support of a specific size.\n        /// </summary>\n        /// <param name=\"size\">Indicated image size.</param>\n        /// <returns>Returns true when the requested size is supported.</returns>\n        bool IsImageSupported(ShengToolStripImageSize size);\n\n        /// <summary>\n        /// Fetches an image of the requested size.\n        /// </summary>\n        /// <param name=\"size\">Size of image to obtain.</param>\n        /// <returns>If supported, returns requested image. A value of null\n        /// indicates that the requested size is not supported.</returns>\n        Image GetImage(ShengToolStripImageSize size);\n\n        #endregion\n    }\n\n    /// <summary>\n    /// Implementations of this interface can provide access to multiple\n    /// different images of multiple different sizes. A default image override\n    /// could be enforced should the provider report with no support.\n    /// </summary>\n    public interface IShengToolStripMultipleImageProvider\n    {\n        #region Methods\n\n        /// <summary>\n        /// Queries the image provider for support of a specific size.\n        /// </summary>\n        /// <param name=\"key\">Key used to identify an image.</param>\n        /// <param name=\"size\">Indicated image size</param>\n        /// <returns>Returns true when the requested size is supported.</returns>\n        bool IsImageSupported(object key, ShengToolStripImageSize size);\n\n        /// <summary>\n        /// Fetches an image of the requested size.\n        /// </summary>\n        /// <param name=\"key\">Key used to identify an image.</param>\n        /// <param name=\"size\">Size of image to obtain.</param>\n        /// <returns>If supported, returns requested image. A value of null\n        /// indicates that the requested size is not supported.</returns>\n        Image GetImage(object key, ShengToolStripImageSize size);\n\n        #endregion\n\n        #region Properties\n\n        /// <summary>\n        /// Gets count of registered image providers.\n        /// </summary>\n        int ImageProviderCount { get; }\n\n        #endregion\n    }\n\n    /// <summary>\n    /// Provides a collection which pairs image providers with a key object.\n    /// The collection can be used to provide access to different images of\n    /// different sizes.\n    /// </summary>\n    public class ShengToolStripImageProviderCollection : Dictionary<object, IShengToolStripImageProvider>, IShengToolStripMultipleImageProvider\n    {\n        #region Construction and destruction\n\n        public ShengToolStripImageProviderCollection()\n            : base()\n        {\n        }\n\n        public ShengToolStripImageProviderCollection(int capacity)\n            : base(capacity)\n        {\n        }\n\n        public ShengToolStripImageProviderCollection(ShengToolStripImageProviderCollection collection)\n            : base(collection)\n        {\n        }\n\n        public ShengToolStripImageProviderCollection(SerializationInfo info, StreamingContext context)\n            : base(info, context)\n        {\n        }\n\n        #endregion\n\n        #region IMultipleImageProvider Members\n\n        /// <summary>\n        /// Queries the image provider for support of a specific size.\n        /// </summary>\n        /// <param name=\"key\">Key used to identify an image.</param>\n        /// <param name=\"size\">Indicated image size</param>\n        /// <returns>Returns true when the requested size is supported.</returns>\n        public bool IsImageSupported(object key, ShengToolStripImageSize size)\n        {\n            if (!this.ContainsKey(key))\n                return false;\n            return this[key].IsImageSupported(size);\n        }\n\n        /// <summary>\n        /// Fetches an image of the requested size.\n        /// </summary>\n        /// <param name=\"key\">Key used to identify an image.</param>\n        /// <param name=\"size\">Size of image to obtain.</param>\n        /// <returns>If supported, returns requested image. A value of null\n        /// indicates that the requested size is not supported.</returns>\n        public Image GetImage(object key, ShengToolStripImageSize size)\n        {\n            if (!this.ContainsKey(key))\n                throw new NullReferenceException();\n            return this[key].GetImage(size);\n        }\n\n        /// <summary>\n        /// Gets count of registered image providers.\n        /// </summary>\n        int IShengToolStripMultipleImageProvider.ImageProviderCount\n        {\n            get { return Count; }\n        }\n\n        #endregion\n    }\n\n    /// <summary>\n    /// Allows an icon to be used to provide images of different sizes.\n    /// </summary>\n    public class ShengToolStripIconImageProvider : IShengToolStripImageProvider\n    {\n        #region Construction and destruction\n\n        public ShengToolStripIconImageProvider(Icon icon)\n        {\n            this.m_sourceIcon = icon;\n        }\n\n        public ShengToolStripIconImageProvider(System.IO.Stream stream)\n        {\n            this.m_sourceIcon = new Icon(stream);\n        }\n\n        public ShengToolStripIconImageProvider(string fileName)\n        {\n            this.m_sourceIcon = new Icon(fileName);\n        }\n\n        public ShengToolStripIconImageProvider(Type type, string resource)\n        {\n            this.m_sourceIcon = new Icon(type, resource);\n        }\n\n        #endregion\n\n        #region Global Utility Methods\n\n        /// <summary>\n        /// A utility method which transforms an enumerated image value into\n        /// a two-dimensional size.\n        /// </summary>\n        /// <param name=\"size\">Requested image size.</param>\n        /// <returns>Returns a two-dimensional size.</returns>\n        public static Size GetIconSize(ShengToolStripImageSize size)\n        {\n            switch (size)\n            {\n                case ShengToolStripImageSize.Small:\n                    return new Size(16, 16);\n                case ShengToolStripImageSize.Medium:\n                    return new Size(24, 24);\n                case ShengToolStripImageSize.Large:\n                    return new Size(32, 32);\n                case ShengToolStripImageSize.ExtraLarge:\n                    return new Size(48, 48);\n                default:\n                    throw new NotSupportedException(\"Invalid image size requested.\");\n            }\n        }\n\n        #endregion\n\n        #region Events\n\n        /// <summary>\n        /// Raised when the icon property is changed.\n        /// </summary>\n        public ShengToolStripOldNewEventHandler<Icon> IconChanged;\n\n        /// <summary>\n        /// Invoked the 'IconChanged' event.\n        /// </summary>\n        /// <param name=\"e\">Provides access to old and new icons.</param>\n        public virtual void OnIconChanged(ShengToolStripOldNewEventArgs<Icon> e)\n        {\n            if (this.IconChanged != null)\n                this.IconChanged(this, e);\n        }\n\n        #endregion\n\n        #region IImageProvider Members\n\n        /// <summary>\n        /// Queries the image provider for support of a specific size.\n        /// </summary>\n        /// <param name=\"size\">Indicated image size.</param>\n        /// <returns>Returns true when the requested size is supported.</returns>\n        public bool IsImageSupported(ShengToolStripImageSize size)\n        {\n            return true;\n        }\n\n        /// <summary>\n        /// Fetches an image of the requested size.\n        /// </summary>\n        /// <param name=\"size\">Size of image to obtain.</param>\n        /// <returns>If supported, returns requested image. A value of null\n        /// indicates that the requested size is not supported.</returns>\n        public Image GetImage(ShengToolStripImageSize size)\n        {\n            Icon desiredSize = new Icon(SourceIcon, ShengToolStripIconImageProvider.GetIconSize(size));\n            return desiredSize.ToBitmap();\n        }\n\n        #endregion\n\n        #region Properties\n\n        /// <summary>\n        /// Gets or sets the source icon.\n        /// </summary>\n        public Icon SourceIcon\n        {\n            get { return this.m_sourceIcon; }\n            set\n            {\n                if (value != this.m_sourceIcon)\n                {\n                    Icon oldIcon = this.m_sourceIcon;\n                    this.m_sourceIcon = value;\n                    OnIconChanged(new ShengToolStripOldNewEventArgs<Icon>(oldIcon, value));\n                }\n            }\n        }\n\n        #endregion\n\n        #region Attributes\n\n        private Icon m_sourceIcon;\n\n        #endregion\n    }\n\n    /// <summary>\n    /// Provides event handlers with the current and proposed image sizes.\n    /// Event handlers can decide whether or not to cancel this procedure.\n    /// </summary>\n    public class ShengToolStripImageSizeChangingEventArgs : CancelEventArgs\n    {\n        #region Construction and destruction\n\n        public ShengToolStripImageSizeChangingEventArgs(ShengToolStripImageSize oldValue, ShengToolStripImageSize newValue)\n            : base(false)\n        {\n            this.m_currentValue = oldValue;\n            this.m_newValue = newValue;\n        }\n\n        #endregion\n\n        #region Properties\n\n        /// <summary>\n        /// Gets the current image size.\n        /// </summary>\n        public ShengToolStripImageSize CurrentValue\n        {\n            get { return this.m_currentValue; }\n        }\n\n        /// <summary>\n        /// Gets the proposed image size.\n        /// </summary>\n        public ShengToolStripImageSize NewValue\n        {\n            get { return this.m_newValue; }\n        }\n\n        #endregion\n\n        #region Attributes\n\n        private ShengToolStripImageSize m_currentValue;\n        private ShengToolStripImageSize m_newValue;\n\n        #endregion\n    }\n\n    public delegate void ShengToolStripImageSizeChangingEventHandler(object sender, ShengToolStripImageSizeChangingEventArgs e);\n\n    /// <summary>\n    /// This toolstrip implements the multiple image provider interface and thus\n    /// provides support for automatic image changes based upon the selected\n    /// image size.\n    /// </summary>\n    \n    public class ShengToolStrip : ToolStrip, IShengToolStripMultipleImageProvider, IShengToolStripImageProvider\n    {\n        #region Construction and destruction\n\n        public ShengToolStrip()\n        {\n\n            this.m_imageProvider = new ShengToolStripImageProviderCollection();\n            this.m_defaultProvider = this;\n        }\n\n        #endregion\n\n        #region Events\n\n        /// <summary>\n        /// Raised when image size is about to be changed.\n        /// </summary>\n        public event ShengToolStripImageSizeChangingEventHandler ImageSizeChanging;\n        /// <summary>\n        /// Raised when image size is changed.\n        /// </summary>\n        public event ShengToolStripOldNewEventHandler<ShengToolStripImageSize> ImageSizeChanged;\n        /// <summary>\n        /// Raised when the property 'UseUnknownImageSizeIcon' is changed.\n        /// </summary>\n        public event EventHandler UseUnknownImageSizeIconChanged;\n\n        /// <summary>\n        /// Invokes the 'ImageSizeChanging' event handler.\n        /// </summary>\n        /// <param name=\"e\">Event arguments.</param>\n        /// <returns>Returns true when proposed change is accepted.</returns>\n        protected virtual bool OnImageSizeChanging(ShengToolStripImageSizeChangingEventArgs e)\n        {\n            if (e.Cancel)\n                return false;\n\n            ShengToolStripImageSizeChangingEventHandler handler = this.ImageSizeChanging;\n            if (handler != null)\n            {\n                handler(this, e);\n                return !e.Cancel;\n            }\n\n            return true;\n        }\n\n        /// <summary>\n        /// Invokes the 'ImageSizeChanged' event handler.\n        /// </summary>\n        /// <param name=\"e\">Event arguments.</param>\n        protected virtual void OnImageSizeChanged(ShengToolStripOldNewEventArgs<ShengToolStripImageSize> e)\n        {\n            ShengToolStripOldNewEventHandler<ShengToolStripImageSize> handler = this.ImageSizeChanged;\n            if (handler != null)\n                this.ImageSizeChanged(this, e);\n        }\n\n        /// <summary>\n        /// Invokes the 'UseUnknownImageSizeIconChanged' event handler.\n        /// </summary>\n        /// <param name=\"e\"></param>\n        protected virtual void OnUseUnknownImageSizeIconChanged(EventArgs e)\n        {\n            // Refresh toolstrip images from providers?\n            if (!IsUpdatingImages)\n                RefreshItemImages();\n\n            // Raise the associated event handler.\n            EventHandler handler = this.UseUnknownImageSizeIconChanged;\n            if (handler != null)\n                this.UseUnknownImageSizeIconChanged(this, e);\n        }\n\n        #endregion\n\n        #region IMultipleImageProvider Members\n\n        /// <summary>\n        /// Queries the image provider for support of a specific size.\n        /// </summary>\n        /// <param name=\"key\">Key used to identify an image.</param>\n        /// <param name=\"size\">Indicated image size</param>\n        /// <returns>Returns true when the requested size is supported.</returns>\n        public virtual bool IsImageSupported(object key, ShengToolStripImageSize size)\n        {\n            return ImageProvider.IsImageSupported(key, size);\n        }\n\n        /// <summary>\n        /// Fetches an image of the requested size.\n        /// </summary>\n        /// <param name=\"key\">Key used to identify an image.</param>\n        /// <param name=\"size\">Size of image to obtain.</param>\n        /// <returns>If supported, returns requested image. A value of null\n        /// indicates that the requested size is not supported.</returns>\n        public virtual Image GetImage(object key, ShengToolStripImageSize size)\n        {\n            return ImageProvider.GetImage(key, size);\n        }\n\n        /// <summary>\n        /// Gets count of registered image providers.\n        /// </summary>\n        public virtual int ImageProviderCount\n        {\n            get { return ImageProvider.Count; }\n        }\n\n        #endregion\n\n        #region IImageProvider Members\n\n        /// <summary>\n        /// Queries the image provider for support of a specific size.\n        /// </summary>\n        /// <param name=\"size\">Indicated image size.</param>\n        /// <returns>Returns true when the requested size is supported.</returns>\n        public virtual bool IsImageSupported(ShengToolStripImageSize size)\n        {\n            if (DefaultImageProvider == null)\n                return false;\n            if (DefaultImageProvider == this)\n                return true;\n\n            return DefaultImageProvider.IsImageSupported(size);\n        }\n\n        /// <summary>\n        /// Fetches an image of the requested size.\n        /// </summary>\n        /// <param name=\"size\">Size of image to obtain.</param>\n        /// <returns>If supported, returns requested image. A value of null\n        /// indicates that the requested size is not supported.</returns>\n        public virtual Image GetImage(ShengToolStripImageSize size)\n        {\n            if (DefaultImageProvider == null)\n                throw new NullReferenceException();\n\n            if (DefaultImageProvider == this)\n            {\n                Size iconSize = ShengToolStripIconImageProvider.GetIconSize(size);\n                Bitmap icon = new Bitmap(16, 16);\n                Icon iconResult = new Icon(DrawingTool.ImageToIcon(icon), iconSize);\n                return iconResult.ToBitmap();\n            }\n\n            return DefaultImageProvider.GetImage(size);\n        }\n\n        #endregion\n\n        #region Methods\n\n        /// <summary>\n        /// Call to begin a batch image provider update more efficiently.\n        /// Each 'BeginImageProviderUpdate' call <b>MUST</b> be paired with\n        /// an 'EndImageProviderUpdate' call.\n        /// </summary>\n        public virtual void BeginUpdateImages()\n        {\n            IsUpdatingImages = true;\n        }\n\n        /// <summary>\n        /// Call to end a batch image provider update. Please note that any\n        /// image refreshements only occur when all nested updates are ended.\n        /// </summary>\n        /// <param name=\"refresh\">Indicates if image sizes are to be refreshed.</param>\n        public virtual void EndUpdateImages(bool refresh)\n        {\n            if (!IsUpdatingImages)\n                throw new NotSupportedException();\n\n            IsUpdatingImages = false;\n\n            // Only apply updates when image providers have been changed.\n            if (HasImagesChanged)\n            {\n                HasImagesChanged = false;\n\n                // If no longer updating image providers (i.e. no nested calls), then\n                // refresh the image sizes.\n                if (!IsUpdatingImages && refresh)\n                    RefreshItemImages();\n            }\n        }\n\n        /// <summary>\n        /// Call to end a batch image provider update. Please note that\n        /// image refreshements only occur when all nested updates are ended.\n        /// </summary>\n        public void EndUpdateImages()\n        {\n            EndUpdateImages(true);\n        }\n\n        /// <summary>\n        /// Assigns an image provider for the specified item.\n        /// </summary>\n        /// <param name=\"item\">Associated toolstrip item.</param>\n        /// <param name=\"provider\">Image provider.</param>\n        /// <returns>Returns true when successful.</returns>\n        public bool AssignImage(ToolStripItem item, IShengToolStripImageProvider provider)\n        {\n            if (item == null || provider == null)\n                throw new ArgumentException(\"One or more arguments were null references.\");\n            if (ContainsImage(item))\n                return false;\n\n            ImageProvider.Add(item, provider);\n            HasImagesChanged = true;\n\n            if (!IsUpdatingImages)\n                RefreshItemImages();\n\n            return true;\n        }\n\n        /// <summary>\n        /// Assigns an image provider for the specified item.\n        /// </summary>\n        /// <param name=\"item\">Associated toolstrip item.</param>\n        /// <param name=\"item\">Associated multi-icon.</param>\n        /// <returns>Returns true when successful.</returns>\n        public bool AssignImage(ToolStripItem item, Icon icon)\n        {\n            return AssignImage(item, new ShengToolStripIconImageProvider(icon));\n        }\n\n        /// <summary>\n        /// Unregisters an image provider.\n        /// </summary>\n        /// <param name=\"item\">Associated toolstrip item.</param>\n        /// <returns>Returns true when successful.</returns>\n        public bool RemoveImage(ToolStripItem item)\n        {\n            if (ImageProvider.Remove(item))\n            {\n                HasImagesChanged = true;\n\n                if (!IsUpdatingImages)\n                    RefreshItemImages();\n                return true;\n            }\n            return false;\n        }\n\n        /// <summary>\n        /// Remove image providers which are not referenced with a <c>ToolStripItem</c>.\n        /// </summary>\n        /// <returns>Returns count of items removed.</returns>\n        public int RemoveUnusedImages()\n        {\n            List<ToolStripItem> removeList = new List<ToolStripItem>();\n            int count = 0;\n\n            // Compile a list of all items which are to be removed.\n            foreach (ToolStripItem key in ImageProvider.Keys)\n                if (!Items.Contains(key as ToolStripItem))\n                    removeList.Add(key);\n            count = removeList.Count;\n\n            // Remove each item from provider collection.\n            foreach (ToolStripItem item in removeList)\n                RemoveImage(item);\n\n            // Make sure that the removal list is disposed of.\n            removeList = null;\n            return count;\n        }\n\n        /// <summary>\n        /// Searches for the a provider which is associated with a toolstrip item.\n        /// </summary>\n        /// <param name=\"item\">Toolstrip item.</param>\n        /// <returns>Returns true when an associated provider is found.</returns>\n        public bool ContainsImage(ToolStripItem item)\n        {\n            return ImageProvider.ContainsKey(item);\n        }\n\n        /// <summary>\n        /// Forces all images sizes to be refreshed from the respective providers.\n        /// </summary>\n        protected void RefreshItemImages()\n        {\n            Size imageSize = ShengToolStripIconImageProvider.GetIconSize(ImageSize);\n            ImageScalingSize = imageSize;\n\n            bool changesMade = false;\n            IShengToolStripImageProvider imageProvider = null;\n\n            foreach (ToolStripItem item in Items)\n            {\n                if (item.Size != imageSize)\n                {\n                    imageProvider = null;\n\n                    // If an image provider was registered with the toolstrip then...\n                    if (ContainsImage(item))\n                    {\n                        if (IsImageSupported(item, ImageSize))\n                            item.Image = GetImage(item, ImageSize);\n                        else if (UseUnknownImageSizeIcon && IsImageSupported(ImageSize))\n                            item.Image = GetImage(ImageSize);\n\n                        changesMade = true;\n                    }\n                    else if (item is IShengToolStripImageProvider)\n                    {\n                        imageProvider = item as IShengToolStripImageProvider;\n                    }\n                    else if (item.Tag is IShengToolStripImageProvider)\n                    {\n                        imageProvider = item.Tag as IShengToolStripImageProvider;\n                    }\n\n                    // If an alternative image provider was found, attempt to use that.\n                    if (!changesMade && imageProvider != null)\n                    {\n                        if (imageProvider.IsImageSupported(ImageSize))\n                        {\n                            item.Image = imageProvider.GetImage(ImageSize);\n                            changesMade = true;\n                        }\n                    }\n\n                    // Were changes made?\n                    if (changesMade)\n                    {\n                        // Automatically adjust the image scaling mode.\n                        if (item.Image != null && item.Image.Size == imageSize)\n                            item.ImageScaling = ToolStripItemImageScaling.None;\n                        else\n                            item.ImageScaling = ToolStripItemImageScaling.SizeToFit;\n                    }\n                }\n            }\n        }\n\n        #endregion\n\n        #region Properties\n\n        /// <summary>\n        /// Gets or sets the default image provider.\n        /// </summary>\n        public IShengToolStripImageProvider DefaultImageProvider\n        {\n            get { return this.m_defaultProvider; }\n            set { this.m_defaultProvider = value; }\n        }\n\n        /// <summary>\n        /// Gets the active multiple image provider.\n        /// </summary>\n        protected ShengToolStripImageProviderCollection ImageProvider\n        {\n            get { return this.m_imageProvider; }\n        }\n\n        /// <summary>\n        /// Gets or sets the active toolstrip item images sizes.\n        /// </summary>\n        public ShengToolStripImageSize ImageSize\n        {\n            get { return this.m_imageSize; }\n            set\n            {\n                if (value != this.m_imageSize)\n                {\n                    ShengToolStripImageSizeChangingEventArgs e = new ShengToolStripImageSizeChangingEventArgs(this.m_imageSize, value);\n                    if (OnImageSizeChanging(e))\n                    {\n                        // Adjust image scaling mode.\n                        ImageScalingSize = ShengToolStripIconImageProvider.GetIconSize(value);\n\n                        // Adjust image size as specified.\n                        this.m_imageSize = value;\n                        RefreshItemImages();\n                        OnImageSizeChanged(new ShengToolStripOldNewEventArgs<ShengToolStripImageSize>(e.CurrentValue, value));\n                    }\n                }\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets whether a default icon is used to represent unsupported\n        /// image sizes.\n        /// </summary>\n        public bool UseUnknownImageSizeIcon\n        {\n            get { return this.m_useUnknownIcon; }\n            set\n            {\n                if (value != this.m_useUnknownIcon)\n                {\n                    this.m_useUnknownIcon = value;\n                    OnUseUnknownImageSizeIconChanged(EventArgs.Empty);\n                }\n            }\n        }\n\n        /// <summary>\n        /// Gets a value indicating if image providers are being updated.\n        /// </summary>\n        public bool IsUpdatingImages\n        {\n            get { return this.m_updatingProviders > 0; }\n            private set { this.m_updatingProviders += value ? +1 : -1; }\n        }\n\n        /// <summary>\n        /// Gets or sets a value indicating if one or more image providers have been changed.\n        /// </summary>\n        protected bool HasImagesChanged\n        {\n            get { return this.m_changesMade; }\n            set { this.m_changesMade = value; }\n        }\n\n        #endregion\n\n        #region Attributes\n\n        private ShengToolStripImageProviderCollection m_imageProvider;\n        private IShengToolStripImageProvider m_defaultProvider;\n        private ShengToolStripImageSize m_imageSize = ShengToolStripImageSize.Small;\n        private bool m_useUnknownIcon = false;\n        private int m_updatingProviders = 0;\n        private bool m_changesMade = false;\n\n        #endregion\n    }\n\n\n    public class ShengToolStripOldNewEventArgs<T> : EventArgs\n    {\n        public ShengToolStripOldNewEventArgs(T oldValue, T newValue)\n        {\n            OldValue = oldValue;\n            NewValue = newValue;\n        }\n\n        public T OldValue\n        {\n            get { return this.m_oldValue; }\n            protected set { this.m_oldValue = value; }\n        }\n        public T NewValue\n        {\n            get { return this.m_newValue; }\n            protected set { this.m_newValue = value; }\n        }\n\n        T m_oldValue = default(T);\n        T m_newValue = default(T);\n    }\n\n    public delegate void ShengToolStripOldNewEventHandler<T>(object sender, ShengToolStripOldNewEventArgs<T> e);\n\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengToolStripMenuItem.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\nusing System.Windows.Forms;\nusing Sheng.Winform.Controls.Drawing;\nusing System.Drawing;\nusing System.Drawing.Drawing2D;\nusing System.Drawing.Text;\nusing System.ComponentModel;\n\nnamespace Sheng.Winform.Controls\n{\n    \n    public class ShengToolStripMenuItem : ToolStripMenuItem\n    {\n\n        StringFormat stringFormat = new StringFormat();\n\n        public ShengToolStripMenuItem()\n            : this(String.Empty)\n        {\n        }\n\n        public ShengToolStripMenuItem(string strName)\n            : base(strName)\n        {\n\n            stringFormat.HotkeyPrefix = HotkeyPrefix.Show;\n            //stringFormat.Trimming = StringTrimming.None;\n            //stringFormat.LineAlignment = StringAlignment.Near;\n\n        }\n\n        protected override void OnPaint(PaintEventArgs e)\n        {\n            Color colorMenuHighLight = ControlPaint.LightLight(SystemColors.MenuHighlight);\n\n            #region \n\n            //ʾͼλX\n            int imageLocationX = 4;\n\n            //ʾͼλY\n            int imageLocationY = 2;\n\n            //ʾıλX\n            int textLocationX = 6;\n\n            //ʾıλY\n            //int textLocationY = 4;\n            int textLocationY = (int)Math.Round((float)(this.ContentRectangle.Height - (int)Math.Round(this.Font.SizeInPoints)) / 2);\n\n            //Ӳ˵ʾıλX\n            int textLocationX_DropDown = 33;\n\n            //Ӳ˵ʾͼλX\n            int imageLocationX_DropDown = 5;\n\n            //Ӳ˵ʾͼλY\n            int imageLocationY_DropDown = 3;\n\n            //ı\n            SolidBrush textBrush = new SolidBrush(this.ForeColor);\n\n            //ʾͼRectangle\n            Rectangle imageRect = new Rectangle(imageLocationX, imageLocationY, 16, 16);\n\n            //Ӳ˵ʾͼRectangle\n            Rectangle imageRect_DropDown = new Rectangle(imageLocationX_DropDown, imageLocationY_DropDown, 16, 16);\n\n            //˵\n            SolidBrush backBrush_Normal = new SolidBrush(SystemColors.ControlLightLight);\n\n            //˵ ѡ״̬\n            //LinearGradientBrush backBrush_Selected = new LinearGradientBrush(new Point(0, 0), new Point(0, this.Height),\n            //            Color.FromArgb(255, 246, 204), Color.FromArgb(255, 194, 115));\n            LinearGradientBrush backBrush_Selected = new LinearGradientBrush(new Point(0, 0), new Point(0, this.Height),\n                      Color.White, colorMenuHighLight);\n\n\n            //˵ ״̬\n            //LinearGradientBrush backBrush_Pressed = new LinearGradientBrush(new Point(0, 0), new Point(0, this.Height),\n            //            Color.White, Color.LightSkyBlue);\n            LinearGradientBrush backBrush_Pressed = new LinearGradientBrush(new Point(0, 0), new Point(0, this.Height),\n                        Color.White, colorMenuHighLight);\n\n            //Ӳ˵\n            LinearGradientBrush leftBrush_DropDown = new LinearGradientBrush(new Point(0, 0), new Point(25, 0),\n                        Color.White, Color.FromArgb(233, 230, 215));\n\n            //Rectangle \n            Rectangle fillRect = new Rectangle(0, 0, this.Bounds.Width, this.Bounds.Height);\n\n            //Ӳ˵Rectangle\n            Rectangle fillRect_DropDown = new Rectangle(2, 0, this.Bounds.Width - 4, this.Bounds.Height);\n\n            //߿Rectangle \n            Rectangle drawRect = new Rectangle(0, 0, this.Bounds.Width - 1, this.Bounds.Height - 1);\n\n            //Ӳ˵߿Rectangle\n            Rectangle drawRect_DropDown = new Rectangle(3, 0, this.Bounds.Width - 6, this.Bounds.Height - 2);\n\n            //Ӳ˵ݵķָ\n            Pen leftLine = new Pen(Color.FromArgb(197, 194, 184));\n\n            //߿򻭱 \n            //Pen drawPen = new Pen(Color.FromArgb(255, 192, 111));\n            Pen drawPen = new Pen(SystemColors.GradientActiveCaption);\n\n            //ʱı߿򻭱 \n            //Pen drawPen_Pressed = new Pen(Color.SkyBlue);\n            Pen drawPen_Pressed = new Pen(SystemColors.GradientActiveCaption);\n\n            //߿򻭱\n            //Pen drawPen_DropDown = new Pen(Color.FromArgb(255, 192, 111));\n            Pen drawPen_DropDown = new Pen(SystemColors.GradientActiveCaption);\n\n            #endregion\n\n            #region ,ıɫĳɻɫ,ͼƬҵ\n\n            //,ıɫĳɻɫ\n            if (this.Enabled)\n            {\n                textBrush.Color = this.ForeColor;\n            }\n            else\n            {\n                textBrush.Color = Color.LightGray;\n            }\n\n            #endregion\n\n            #region ˵\n\n            //Ƕ˵\n            if (!this.IsOnDropDown)\n            {\n                //ǰ״̬\n                if (this.Pressed)\n                {\n                    e.Graphics.FillRectangle(backBrush_Pressed, fillRect);\n                    e.Graphics.DrawRectangle(drawPen_Pressed, drawRect);\n                }\n                //ѡ״̬\n                else if (this.Selected)\n                {\n                    e.Graphics.FillRectangle(backBrush_Selected, fillRect);\n                    e.Graphics.DrawRectangle(drawPen, drawRect);\n                }\n\n                //ͼı\n                if (this.Image != null)\n                {\n                    if (this.DisplayStyle == ToolStripItemDisplayStyle.ImageAndText)\n                    {\n                        if (this.Enabled)\n                            e.Graphics.DrawImage(this.Image, imageRect);\n                        else\n                            ControlPaint.DrawImageDisabled(e.Graphics, this.Image, imageRect.X, imageRect.Y, this.BackColor);\n\n                        e.Graphics.DrawString(this.Text, this.Font, textBrush, new Point(textLocationX + 14, textLocationY), stringFormat);\n                    }\n                    else if (this.DisplayStyle == ToolStripItemDisplayStyle.Image)\n                    {\n                        if (this.Enabled)\n                            e.Graphics.DrawImage(this.Image, imageRect);\n                        else\n                            ControlPaint.DrawImageDisabled(e.Graphics, this.Image, imageRect.X, imageRect.Y, this.BackColor);\n                    }\n                    else if (this.DisplayStyle == ToolStripItemDisplayStyle.Text)\n                    {\n                        e.Graphics.DrawString(this.Text, this.Font, textBrush, new Point(textLocationX, textLocationY), stringFormat);\n                    }\n                }\n                else\n                {\n                    e.Graphics.DrawString(this.Text, this.Font, textBrush, new Point(textLocationX, textLocationY), stringFormat);\n                }\n\n            }\n\n            #endregion\n\n            #region Ƕ˵\n\n            //Ƕ˵\n            else\n            {\n                #region ѡлǰ״̬\n\n                //ѡлǰ״̬\n                if (this.Selected || this.Pressed)\n                {\n                    //e.Graphics.FillRectangle(backBrush_Selected,fillRect_DropDown);\n\n                    e.Graphics.FillRectangle(backBrush_Normal, fillRect_DropDown);\n                    e.Graphics.FillRectangle(leftBrush_DropDown, 0, 0, 25, this.Height);\n                    e.Graphics.DrawLine(leftLine, 25, 0, 25, this.Height);\n\n                    //\n                    if (this.Enabled)\n                    {\n                        //GraphPlotting.FillRoundRect(e.Graphics, backBrush_Selected, drawRect_DropDown, 0, 2);\n                        //GraphPlotting.DrawRoundRect(e.Graphics, drawPen_DropDown, drawRect_DropDown, 2);                      \n\n                        e.Graphics.FillPath(backBrush_Selected, DrawingTool.RoundedRect(drawRect_DropDown, 3));\n                        e.Graphics.DrawPath(drawPen_DropDown, DrawingTool.RoundedRect(drawRect_DropDown, 3));\n                    }\n\n                    if (this.Image != null)\n                    {\n                        //Ӳ˵дһ\n                        //Ϊûͼ,ıλǲ\n                        if (this.DisplayStyle == ToolStripItemDisplayStyle.ImageAndText ||\n                            this.DisplayStyle == ToolStripItemDisplayStyle.Image\n                            )\n                        {\n                            if (this.Enabled)\n                                e.Graphics.DrawImage(this.Image, imageRect_DropDown);\n                            else\n                                ControlPaint.DrawImageDisabled(e.Graphics, this.Image, imageRect_DropDown.X, imageRect_DropDown.Y,this.BackColor);\n                        }\n                    }\n\n                    e.Graphics.DrawString(this.Text, this.Font, textBrush, new Point(textLocationX_DropDown, textLocationY), stringFormat);\n\n                }\n\n                #endregion\n\n                #region δѡҲδ\n\n                //δѡҲδ\n                else\n                {\n\n                    e.Graphics.FillRectangle(backBrush_Normal, fillRect_DropDown);\n                    e.Graphics.FillRectangle(leftBrush_DropDown, 0, 0, 25, this.Height);\n                    e.Graphics.DrawLine(leftLine, 25, 0, 25, this.Height);\n\n                    if (this.Image != null)\n                    {\n                        if (this.DisplayStyle == ToolStripItemDisplayStyle.ImageAndText ||\n                            this.DisplayStyle == ToolStripItemDisplayStyle.Image)\n                        {\n                            if (this.Enabled)\n                                e.Graphics.DrawImage(this.Image, imageRect_DropDown);\n                            else\n                                ControlPaint.DrawImageDisabled(e.Graphics, this.Image, imageRect_DropDown.X, imageRect_DropDown.Y, this.BackColor);\n                        }\n                    }\n\n                    e.Graphics.DrawString(this.Text, this.Font, textBrush, new Point(textLocationX_DropDown, textLocationY), stringFormat);\n\n                }\n\n                #endregion\n\n                #region Checked = true\n \n         //       ControlPaint.draw\n             //   MenuGlyph.\n\n                if (this.Checked)\n                {\n                    ControlPaint.DrawMenuGlyph\n                        (e.Graphics, imageLocationX_DropDown, imageLocationY_DropDown, 16, 16, \n                        MenuGlyph.Checkmark,Color.Black, SystemColors.GradientActiveCaption);\n                }\n\n                #endregion\n\n                #region Ӳ˵,Ҽͷ\n\n                if (this.DropDownItems.Count > 0)\n                {\n                    ControlPaint.DrawMenuGlyph\n                        (e.Graphics,this.Width - 20, imageLocationY_DropDown, 16, 16,\n                        MenuGlyph.Arrow, Color.Black, Color.Transparent);\n                }\n\n                #endregion\n            }\n\n            #endregion\n           \n\n            #region ͷԴ\n\n            //ͷԴ\n            textBrush.Dispose();\n            backBrush_Normal.Dispose();\n            backBrush_Selected.Dispose();\n            backBrush_Pressed.Dispose();\n            leftBrush_DropDown.Dispose();\n            leftLine.Dispose();\n            drawPen.Dispose();\n            drawPen_Pressed.Dispose();\n            drawPen_DropDown.Dispose();\n\n            #endregion\n        }\n\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengToolStripSeparator.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Drawing;\nusing System.Drawing.Drawing2D;\nusing System.ComponentModel;\n\nnamespace Sheng.Winform.Controls\n{\n    \n    public class ShengToolStripSeparator : ToolStripSeparator\n    {\n        private bool defaultPaint = false;\n        public bool DefaultPaint\n        {\n            get\n            {\n                return this.defaultPaint;\n            }\n            set\n            {\n                this.defaultPaint = value;\n            }\n        }\n\n        public ShengToolStripSeparator()\n        {\n        }\n\n        protected override void OnPaint(PaintEventArgs e)\n        {\n            if (this.defaultPaint)\n            {\n                base.OnPaint(e);\n                return;\n            }\n\n            //菜单背景填充\n            SolidBrush backBrush_Normal = new SolidBrush(SystemColors.ControlLightLight);\n\n            //填充Rectangle 顶层\n            Rectangle fillRect = new Rectangle(0, 0, this.Bounds.Width, this.Bounds.Height);\n\n            //子菜单左侧边条的填充\n            LinearGradientBrush leftBrush_DropDown = new LinearGradientBrush(new Point(0, 0), new Point(23, 0),\n                        Color.White, Color.FromArgb(233, 230, 215));\n\n            //子菜单左侧与内容的分隔条\n            Pen leftLine = new Pen(Color.FromArgb(197, 194, 184));\n\n            e.Graphics.FillRectangle(backBrush_Normal, fillRect);\n            e.Graphics.FillRectangle(leftBrush_DropDown, 0, 0, 23, this.Height);\n            e.Graphics.DrawLine(leftLine, 23, 0, 23, this.Height);\n\n            int lineY = (int)Math.Round((double)(this.ContentRectangle.Height / 2));;\n\n            e.Graphics.DrawLine(leftLine, 25, lineY, this.Width - 2, lineY);\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengTreeView.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Drawing;\nusing Sheng.Winform.Controls.Win32;\n\nnamespace Sheng.Winform.Controls\n{\n    /// <summary>\n    /// 1.支持Win7/Vista外观\n    /// 2.支持拖放操作\n    /// </summary>\n    public class ShengTreeView : TreeView\n    {\n        #region 私有成员\n\n        // Node being dragged\n        private TreeNode _dragNode = null;\n        protected TreeNode DragNode\n        {\n            get { return _dragNode; }\n            set { _dragNode = value; }\n        }\n\n        // Temporary drop node for selection\n        private TreeNode _tempDropNode = null;\n\n        // Timer for scrolling\n        private Timer _timer = new Timer();\n\n        private System.Windows.Forms.ImageList _imageListDrag;\n\n        #endregion\n\n        #region 公开属性\n\n        //private bool _allowDropNode = false;\n        ///// <summary>\n        ///// 是否允许拖放节点\n        ///// </summary>\n        //public bool AllowDropNode\n        //{\n        //    get { return _allowDropNode; }\n        //    set { _allowDropNode = value; }\n        //}\n\n        private Func<TreeNode, bool> _canDragFunc;\n        /// <summary>\n        /// 节点是否可以拖动\n        /// 如果不定义，默认节点都是可以拖动的\n        /// </summary>\n        public Func<TreeNode, bool> CanDragFunc\n        {\n            get { return _canDragFunc; }\n            set { _canDragFunc = value; }\n        }\n\n        public delegate bool CanDropFuncDelegate(TreeNode dragNode, TreeNode dropNode);\n        private CanDropFuncDelegate _canDropFunc;\n        /// <summary>\n        /// 节点是否可以放置在指定节点下\n        /// dragNode（当前拖动的节点） 是否能放在 dropNode （要放置的节点）下\n        /// 如果不定义，默认节点都是可以放置的\n        /// </summary>\n        public CanDropFuncDelegate CanDropFunc\n        {\n            get { return _canDropFunc; }\n            set { _canDropFunc = value; }\n        }\n\n        public delegate void DragDropActionDelegate(TreeNode dragNode, TreeNode dropNode);\n        private DragDropActionDelegate _dragDropAction;\n        /// <summary>\n        /// 允许在不重写 ProcessDragDrop 方法的情况下实现外部的节点移动逻辑\n        /// 若要引发 OnDragDropNodeAction 事件 ，必须调用  DragDropNodeAction（如果调用了 MoveNode 除外）\n        /// </summary>\n        public DragDropActionDelegate DragDropAction\n        {\n            get { return _dragDropAction; }\n            set { _dragDropAction = value; }\n        }\n\n        #endregion\n\n        #region 事件\n\n        public delegate void OnDragDropNodeActionHandler(DragDropNodeActionEventArgs e);\n        public event OnDragDropNodeActionHandler DragDropNodeAction;\n\n        /// <summary>\n        /// 引发 OnDragDropNodeAction 事件\n        /// </summary>\n        /// <param name=\"dragNode\"></param>\n        /// <param name=\"dropNode\"></param>\n        protected void OnDragDropNodeAction(TreeNode dragNode, TreeNode dropNode)\n        {\n            if (DragDropNodeAction != null)\n            {\n                DragDropNodeActionEventArgs args = new DragDropNodeActionEventArgs(dragNode, dropNode);\n                DragDropNodeAction(args);\n            }\n        }\n\n        #endregion\n\n        #region 构造\n\n        public ShengTreeView()\n        {\n            ExplorerTreeView.ApplyTreeViewThemeStyles(this);\n\n            this._imageListDrag = new ImageList();\n            this._imageListDrag.ColorDepth = System.Windows.Forms.ColorDepth.Depth32Bit;\n            this._imageListDrag.ImageSize = new System.Drawing.Size(16, 16);\n            this._imageListDrag.TransparentColor = System.Drawing.Color.Transparent;\n\n            _timer.Interval = 200;\n            _timer.Tick += new EventHandler(timer_Tick);\n        }\n\n        #endregion\n\n        #region 和拖放有关的图形绘制\n        \n        /// <summary>\n        /// Begin dragging image\n        /// 当用户开始拖动节点时，调用此方法\n        /// 在调用  this.DoDragDrop 之后，还需要调用 DrawEndDrag\n        /// </summary>\n        /// <returns></returns>\n        protected bool DrawOnItemDrag()\n        {\n            if (_dragNode == null)\n                return false;\n\n            // Reset image list used for drag image\n            this._imageListDrag.Images.Clear();\n            this._imageListDrag.ImageSize = new Size(this._dragNode.Bounds.Size.Width + this.Indent, this._dragNode.Bounds.Height);\n\n            // Create new bitmap\n            // This bitmap will contain the tree node image to be dragged\n            Bitmap bmp = new Bitmap(this._dragNode.Bounds.Width + this.Indent, this._dragNode.Bounds.Height);\n\n            // Get graphics from bitmap\n            Graphics gfx = Graphics.FromImage(bmp);\n\n            //gfx.Clear(SystemColors.GradientInactiveCaption);\n\n            // Draw node icon into the bitmap\n            //cxs\n            //gfx.DrawImage(this.imageListTreeView.Images[0], 0, 0);\n            if (this.ImageList != null && this._dragNode.ImageIndex < this.ImageList.Images.Count && this._dragNode.ImageIndex >= 0)\n            {\n                gfx.DrawImage(this.ImageList.Images[this._dragNode.ImageIndex], 0, 0);\n            }\n\n            // Draw node label into bitmap\n            gfx.DrawString(this._dragNode.Text,\n                this.Font,\n                new SolidBrush(this.ForeColor),\n                (float)this.Indent, 1.0f);\n\n            // Add bitmap to imagelist\n            this._imageListDrag.Images.Add(bmp);\n\n              // Get mouse position in client coordinates\n            Point p = this.PointToClient(Control.MousePosition);\n\n            // Compute delta between mouse position and node bounds\n            int dx = p.X + this.Indent - this._dragNode.Bounds.Left;\n            int dy = p.Y - this._dragNode.Bounds.Top;\n\n            // Begin dragging image\n            return DragHelper.ImageList_BeginDrag(this._imageListDrag.Handle, 0, dx, dy);\n        }\n\n        /// <summary>\n        /// End dragging image\n        /// 停止绘制\n        /// </summary>\n        protected void DrawEndDrag()\n        {\n            DragHelper.ImageList_EndDrag();\n        }\n\n        /// <summary>\n        /// Unlock updates\n        /// 在拖放操作完成时发生时，调用此方法\n        /// </summary>\n        protected void DrawOnDragDrop()\n        {\n            // Unlock updates\n            DragHelper.ImageList_DragLeave(this.Handle);\n        }\n\n        #endregion\n\n        #region 拖放逻辑判断\n\n        //主要用于继承者在不重写 （处理拖放）相关方法时，仅重写这些方法也同样可以控制拖放的一些控制逻辑\n\n        /// <summary>\n        /// 节点是否可以拖动\n        /// </summary>\n        /// <param name=\"treeNode\"></param>\n        /// <returns></returns>\n        protected virtual bool CanDrag(TreeNode treeNode)\n        {\n            if (_canDragFunc != null)\n                return _canDragFunc(treeNode);\n            else\n                return true;\n        }\n\n        /// <summary>\n        /// 节点是否可以放置在指定节点下\n        /// dragNode（当前拖动的节点） 是否能放在 dropNode （要放置的节点）下\n        /// </summary>\n        /// <param name=\"dragNode\"></param>\n        /// <param name=\"dropNode\"></param>\n        /// <returns></returns>\n        protected virtual bool CanDrop(TreeNode dragNode, TreeNode dropNode)\n        {\n            if (_canDropFunc != null)\n                return _canDropFunc(dragNode, dropNode);\n            else\n                return true;\n        }\n\n        /// <summary>\n        /// 放置节点\n        /// 把 dragNode（当前拖动的节点） 放在 dropNode （要放置的节点）下\n        /// 允许继承者重写以实现必须的业务逻辑\n        /// 如果重写此事件后需要引发 OnDragDropNodeAction 事件必须调用  DragDropNodeAction\n        /// </summary>\n        /// <param name=\"dragNode\"></param>\n        /// <param name=\"dropNode\"></param>\n        protected virtual void ProcessDragDrop(TreeNode dragNode, TreeNode dropNode)\n        {\n            if (_dragDropAction != null)\n            {\n                //这里不调用 DragDropNodeAction ，让外部委托自己调用\n                //因为实际放置的节点并不一定就是传进来的 dropNode，有可能是传进来的 dropNode 的父节点，而不是放在 dropNode 之下\n                _dragDropAction(dragNode, dropNode);\n            }\n            else\n            {\n                MoveNode(dragNode, dropNode);\n            }\n        }\n\n        #endregion\n\n        #region 处理拖放\n\n        /// <summary>\n        /// 当用户开始拖动节点时发生。\n        /// </summary>\n        /// <param name=\"e\"></param>\n        protected override void OnItemDrag(ItemDragEventArgs e)\n        {\n            //如果不允许拖放\n            if (this.AllowDrop == false)\n                return;\n\n            // Get drag node and select it\n            this._dragNode = (TreeNode)e.Item;\n            this.SelectedNode = this._dragNode;\n\n            if (CanDrag(this.SelectedNode))\n            {\n                // Begin dragging image\n                if (DrawOnItemDrag())\n                {\n                    // Begin dragging\n                    this.DoDragDrop(_imageListDrag.Images.Count > 0 ? _imageListDrag.Images[0] : null, DragDropEffects.Move);\n                    // End dragging image\n                    DrawEndDrag();\n                }\n            }\n\n            base.OnItemDrag(e);\n        }\n\n        /// <summary>\n        /// 在将对象拖到控件的边界上发生。\n        /// </summary>\n        /// <param name=\"drgevent\"></param>\n        protected override void OnDragOver(DragEventArgs e)\n        {\n            // Compute drag position and move image\n            Point formP = this.PointToClient(new Point(e.X, e.Y));\n            //DragHelper.ImageList_DragMove(formP.X - this.Left, formP.Y - this.Top);\n            DragHelper.ImageList_DragMove(formP.X, formP.Y);\n\n            // Get actual drop node\n            TreeNode dropNode = this.GetNodeAt(this.PointToClient(new Point(e.X, e.Y)));\n            if (dropNode == null)\n            {\n                e.Effect = DragDropEffects.None;\n                return;\n            }\n\n            e.Effect = DragDropEffects.Move;\n\n            // if mouse is on a new node select it\n            if (this._tempDropNode != dropNode)\n            {\n                DragHelper.ImageList_DragShowNolock(false);\n                this.SelectedNode = dropNode;\n                DragHelper.ImageList_DragShowNolock(true);\n                _tempDropNode = dropNode;\n            }\n\n            // Avoid that drop node is child of drag node \n            TreeNode tmpNode = dropNode;\n            while (tmpNode.Parent != null)\n            {\n                if (tmpNode.Parent == this._dragNode) e.Effect = DragDropEffects.None;\n                tmpNode = tmpNode.Parent;\n            }\n\n            base.OnDragOver(e);\n\n        }\n\n        /// <summary>\n        /// 拖放操作完成时发生。\n        /// </summary>\n        /// <param name=\"drgevent\"></param>\n        protected override void OnDragDrop(DragEventArgs e)\n        {\n            DrawOnDragDrop();\n\n            // Get drop node\n            TreeNode dropNode = this.GetNodeAt(this.PointToClient(new Point(e.X, e.Y)));\n\n            // If drop node isn't equal to drag node, add drag node as child of drop node\n            //通过CanDrop判断是否允许放置\n            if (this._dragNode != dropNode && this._dragNode.Parent != dropNode && CanDrop(_dragNode, dropNode))\n            {\n                ProcessDragDrop(this._dragNode, dropNode);\n\n                this.SelectedNode = _dragNode;\n\n                // Set drag node to null\n                this._dragNode = null;\n\n                // Disable scroll timer\n                this._timer.Enabled = false;\n            }\n\n            base.OnDragDrop(e);\n        }\n\n        /// <summary>\n        /// 在将对象拖入控件的边界时发生。\n        /// </summary>\n        /// <param name=\"drgevent\"></param>\n        protected override void OnDragEnter(DragEventArgs e)\n        {\n            DragHelper.ImageList_DragEnter(this.Handle, e.X - this.Left,\n                e.Y - this.Top);\n\n            // Enable timer for scrolling dragged item\n            this._timer.Enabled = true;\n\n            base.OnDragEnter(e);\n        }\n\n        /// <summary>\n        /// 在将对象拖出控件的边界时发生。\n        /// </summary>\n        /// <param name=\"e\"></param>\n        protected override void OnDragLeave(EventArgs e)\n        {\n            DragHelper.ImageList_DragLeave(this.Handle);\n\n            // Disable timer for scrolling dragged item\n            this._timer.Enabled = false;\n\n            base.OnDragLeave(e);\n        }\n\n        /// <summary>\n        /// 在执行拖动操作期间发生。\n        /// 系统请求该控件对该效果的返回\n        /// </summary>\n        /// <param name=\"gfbevent\"></param>\n        protected override void OnGiveFeedback(GiveFeedbackEventArgs e)\n        {\n            if (e.Effect == DragDropEffects.Move)\n            {\n                // Show pointer cursor while dragging\n                e.UseDefaultCursors = false;\n                this.Cursor = Cursors.Default;\n            }\n            else e.UseDefaultCursors = true;\n\n            base.OnGiveFeedback(e);\n        }\n\n        private void timer_Tick(object sender, EventArgs e)\n        {\n            // get node at mouse position\n            Point pt = PointToClient(Control.MousePosition);\n            TreeNode node = this.GetNodeAt(pt);\n\n            if (node == null) return;\n\n            // if mouse is near to the top, scroll up\n            if (pt.Y < 30)\n            {\n                // set actual node to the upper one\n                if (node.PrevVisibleNode != null)\n                {\n                    node = node.PrevVisibleNode;\n\n                    // hide drag image\n                    DragHelper.ImageList_DragShowNolock(false);\n                    // scroll and refresh\n                    node.EnsureVisible();\n                    this.Refresh();\n                    // show drag image\n                    DragHelper.ImageList_DragShowNolock(true);\n\n                }\n            }\n            // if mouse is near to the bottom, scroll down\n            else if (pt.Y > this.Size.Height - 30)\n            {\n                if (node.NextVisibleNode != null)\n                {\n                    node = node.NextVisibleNode;\n\n                    DragHelper.ImageList_DragShowNolock(false);\n                    node.EnsureVisible();\n                    this.Refresh();\n                    DragHelper.ImageList_DragShowNolock(true);\n                }\n            }\n        }\n\n        #endregion\n\n        #region 其它重写的事件\n\n        protected override void OnMouseClick(MouseEventArgs e)\n        {\n            //使鼠标右击也具有选择节点功能\n            TreeNode dropNode = this.GetNodeAt(new Point(e.X, e.Y));\n            if (dropNode != null)\n            {\n                this.SelectedNode = dropNode;\n            }\n\n            base.OnMouseClick(e);\n        }\n\n        #endregion\n\n        #region 公开方法和受保护的方法\n\n        /// <summary>\n        /// 交换同一父节点下，两个节点的位置\n        /// </summary>\n        /// <param name=\"node1\"></param>\n        /// <param name=\"node2\"></param>\n        protected void SwapNode(TreeNode node1, TreeNode node2)\n        {\n            if (node1 == null || node2 == null)\n                return;\n\n            if (node1.TreeView != this || node2.TreeView != this)\n                return;\n\n            if (node1.Parent != node2.Parent)\n                return;\n\n            TreeNode parentNode = node1.Parent;\n\n            int index1 = node1.Index;\n            int index2 = node2.Index;\n\n            parentNode.Nodes.Remove(node1);\n            parentNode.Nodes.Remove(node2);\n\n            if (index1 < index2)\n            {\n                parentNode.Nodes.Insert(index1, node2);\n                parentNode.Nodes.Insert(index2, node1);\n            }\n            else\n            {\n                parentNode.Nodes.Insert(index2, node1);\n                parentNode.Nodes.Insert(index1, node2);\n            }\n        }\n\n        /// <summary>\n        /// 把 dragNode（当前拖动的节点） 放在 dropNode （要放置的节点）的子节点中（最后面）\n        /// </summary>\n        /// <param name=\"dragNode\"></param>\n        /// <param name=\"dropNode\"></param>\n        public void MoveNode(TreeNode dragNode, TreeNode dropNode)\n        {\n            // Remove drag node from parent\n            if (dragNode.Parent == null)\n            {\n                this.Nodes.Remove(dragNode);\n            }\n            else\n            {\n                dragNode.Parent.Nodes.Remove(dragNode);\n            }\n\n            // Add drag node to drop node\n            dropNode.Nodes.Add(dragNode);\n            dropNode.ExpandAll();\n\n            //引发事件\n            OnDragDropNodeAction(dragNode, dropNode);\n        }\n\n        #endregion\n\n        #region DragDropNodeActionEventArgs\n\n        public class DragDropNodeActionEventArgs : EventArgs\n        {\n            private TreeNode _dragNode;\n            public TreeNode DragNode\n            {\n                get { return _dragNode; }\n            }\n\n            private TreeNode _dropNode;\n            public TreeNode DropNode\n            {\n                get { return _dropNode; }\n            }\n\n            public DragDropNodeActionEventArgs(TreeNode dragNode, TreeNode dropNode)\n            {\n                _dragNode = dragNode;\n                _dropNode = dropNode;\n            }\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengUserControl.Designer.cs",
    "content": "﻿namespace Sheng.Winform.Controls\n{\n    partial class ShengUserControl\n    {\n        /// <summary> \n        /// 必需的设计器变量。\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary> \n        /// 清理所有正在使用的资源。\n        /// </summary>\n        /// <param name=\"disposing\">如果应释放托管资源，为 true；否则为 false。</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region 组件设计器生成的代码\n\n        /// <summary> \n        /// 设计器支持所需的方法 - 不要\n        /// 使用代码编辑器修改此方法的内容。\n        /// </summary>\n        private void InitializeComponent()\n        {\n            components = new System.ComponentModel.Container();\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengUserControl.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Drawing;\nusing System.Data;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Reflection;\nusing Sheng.Winform.Controls.Localisation;\n\nnamespace Sheng.Winform.Controls\n{\n    \n    public partial class ShengUserControl : UserControl, IShengValidate\n    {\n        #region \n\n        public ShengUserControl()\n        {\n\n            InitializeComponent();\n        }\n\n        #endregion\n\n        #region \n\n        /// <summary>\n        /// ֤ؼ\n        /// ֤,дʾ,ڲFormе֤ĵط\n        /// ʹ򵼵\n        /// </summary>\n        /// <returns></returns>\n        public virtual bool DoValidate()\n        {\n            bool validateResult = true;\n            string validateMsg;\n\n            validateResult = this.SEValidate(out validateMsg);\n            if (validateResult == false)\n            {\n                MessageBox.Show(validateMsg, Language.Current.MessageBoxCaptiton_Message, MessageBoxButtons.OK, MessageBoxIcon.Information);\n            }\n\n            return validateResult;\n        }\n\n        #endregion\n\n        #region ISEValidate Ա\n\n        private string title;\n        /// <summary>\n        /// \n        /// </summary>\n        [Description(\"\")]\n        [Category(\"Sheng.Winform.Controls\")]\n        public string Title\n        {\n            get\n            {\n                return this.title;\n            }\n            set\n            {\n                this.title = value;\n            }\n        }\n\n        private bool highLight = false;\n        /// <summary>\n        /// ֤ʧʱǷҪʾı䱳ɫ\n        /// </summary>\n        [Description(\"֤ʧʱǷҪʾı䱳ɫ\")]\n        [Category(\"Sheng.Winform.Controls\")]\n        public bool HighLight\n        {\n            get\n            {\n                return this.highLight;\n            }\n            set\n            {\n                this.highLight = value;\n            }\n        }\n\n        /// <summary>\n        /// ֤ؼ\n        /// </summary>\n        /// <param name=\"validateMsg\"></param>\n        /// <returns></returns>\n        public virtual bool SEValidate(out string validateMsg)\n        {\n            return ShengValidateHelper.ValidateContainerControl(this, out validateMsg);\n        }\n\n        public CustomValidateMethod CustomValidate\n        {\n            get;\n            set;\n        }\n\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/ShengUserControl.resx",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n</root>"
  },
  {
    "path": "Sheng.Winform.Controls/ShengValidateHelper.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Drawing;\n\nnamespace Sheng.Winform.Controls\n{\n    /// <summary>\n    /// 提供验证的公用方法，属性\n    /// </summary>\n    public static class ShengValidateHelper\n    {\n        /// <summary>\n        /// 为容器类控件提供通用的数据验证方法\n        /// 此方此自动迭代传入的Control对象的Controls属性，并调用期数据验证方法（如果有）\n        /// </summary>\n        /// <param name=\"control\"></param>\n        /// <param name=\"validateMsg\"></param>\n        /// <returns></returns>\n        public static bool ValidateContainerControl(Control control, out string validateMsg)\n        {\n            bool validateResult = true;\n            string ctrlValidateMsg;\n            validateMsg = String.Empty;\n\n            foreach (Control ctrl in control.Controls)\n            {\n                if (ValidateControl(ctrl, out ctrlValidateMsg) == false)\n                {\n                    validateMsg += ctrlValidateMsg + Environment.NewLine;\n                    validateResult = false;\n                }\n            }\n\n            if (validateResult == false)\n            {\n                WipeSpilthSpace(ref validateMsg);\n            }\n\n            return validateResult;\n        }\n\n        /// <summary>\n        /// 验证控件\n        /// </summary>\n        /// <param name=\"ctrl\"></param>\n        /// <param name=\"validateMsg\"></param>\n        /// <returns></returns>\n        public static bool ValidateControl(Control ctrl, out string validateMsg)\n        {\n            validateMsg = String.Empty;\n\n            IShengValidate seValidate = ctrl as IShengValidate;\n            if (seValidate == null)\n                return true;\n\n            bool result = true;\n\n            string msg = String.Empty;\n\n            if (seValidate.SEValidate(out msg) == false)\n            {\n                validateMsg += msg;\n                //获取属性判断是否需要改变背景色\n                if (seValidate.HighLight)\n                {\n                    ctrl.BackColor = Color.Pink;\n                }\n                result = false;\n            }\n            else\n            {\n                if (seValidate.HighLight)\n                {\n                    ctrl.BackColor = SystemColors.Window;\n                }\n                result = true;\n            }\n\n            if (result == false)\n            {\n                WipeSpilthSpace(ref validateMsg);\n            }\n\n            return result;\n        }\n\n        /// <summary>\n        /// 去除验证结果中多余的换行\n        /// </summary>\n        /// <param name=\"validateMsg\"></param>\n        public static void WipeSpilthSpace(ref string validateMsg)\n        {\n            //去除验证结果中多余的换行\n            //TODO:为什么会产生多余的换行，有时间跟\n\n            while (true)\n            {\n                if (validateMsg.IndexOf(\"\\r\\n\\r\\n\") > 0)\n                {\n                    validateMsg = validateMsg.Replace(\"\\r\\n\\r\\n\", \"\\r\\n\");\n                }\n                else\n                {\n                    break;\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/WinAPI.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Runtime.InteropServices;\n\nnamespace Sheng.SIMBE.SEControl\n{\n    class WinAPI\n    {\n        [DllImport(\"user32.dll\")]\n        public extern static IntPtr GetWindow();\n\n        [DllImport(\"user32.dll\")]\n        public extern static bool SetLayeredWindowAttributes(IntPtr hwnd, uint crKey, byte bAlpha, uint dwFlags);\n        public static uint LWA_COLORKEY = 0x00000001;\n        public static uint LWA_ALPHA = 0x00000002;\n\n        #region 阴影效果变量\n\n        [DllImport(\"user32.dll\", CharSet = CharSet.Auto)]\n        public static extern int SetClassLong(IntPtr hwnd, int nIndex, int dwNewLong);\n        [DllImport(\"user32.dll\", CharSet = CharSet.Auto)]\n        public static extern int GetClassLong(IntPtr hwnd, int nIndex);\n        [DllImport(\"user32.dll\")]\n        public extern static uint SetWindowLong(IntPtr hwnd, int nIndex, uint dwNewLong);\n        [DllImport(\"user32.dll\")]\n        public extern static uint GetWindowLong(IntPtr hwnd, int nIndex);\n\n        #endregion\n\n        public enum WindowStyle : int\n        {\n            GWL_EXSTYLE = -20\n        }\n\n        public enum ExWindowStyle : uint\n        {\n            WS_EX_LAYERED = 0x00080000\n        }\n\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/Wizard/IWizardView.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nnamespace Sheng.Winform.Controls\n{\n    public interface IWizardView\n    {\n        /// <summary>\n        /// 设置标题栏的关闭按钮是否可用\n        /// </summary>\n        bool CloseButtonEnabled { set; }\n\n        /// <summary>\n        /// 上一步按钮是否可用\n        /// </summary>\n        bool BackButtonEnabled { get; set; }\n\n        /// <summary>\n        /// 下一步按钮是否可用\n        /// </summary>\n        bool NextButtonEnabled { get; set; }\n\n        /// <summary>\n        /// 完成按钮是否可用\n        /// </summary>\n        bool FinishButtonEnabled { get; set; }\n\n        /// <summary>\n        /// 显示下一步界面\n        /// </summary>\n        void NextPanel();\n\n        /// <summary>\n        /// 设置数据\n        /// 用于跨面板数据交互\n        /// </summary>\n        /// <param name=\"name\"></param>\n        /// <param name=\"data\"></param>\n        void SetData(string name, object data);\n\n        /// <summary>\n        /// 获取数据\n        /// </summary>\n        /// <param name=\"name\"></param>\n        /// <returns></returns>\n        object GetData(string name);\n\n        /// <summary>\n        /// 设置选项对象\n        /// </summary>\n        /// <typeparam name=\"T\"></typeparam>\n        /// <param name=\"option\"></param>\n        void SetOptionInstance<T>(T option) where T : class;\n\n        /// <summary>\n        /// 获取选项对象\n        /// </summary>\n        /// <typeparam name=\"T\"></typeparam>\n        /// <returns></returns>\n        T GetOptionInstance<T>() where T : class;\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/Wizard/WizardPanelBase.Designer.cs",
    "content": "﻿namespace Sheng.Winform.Controls\n{\n    partial class WizardPanelBase\n    {\n        /// <summary> \n        /// 必需的设计器变量。\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary> \n        /// 清理所有正在使用的资源。\n        /// </summary>\n        /// <param name=\"disposing\">如果应释放托管资源，为 true；否则为 false。</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region 组件设计器生成的代码\n\n        /// <summary> \n        /// 设计器支持所需的方法 - 不要\n        /// 使用代码编辑器修改此方法的内容。\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.SuspendLayout();\n            // \n            // UserControlWizardPanelBase\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.Name = \"UserControlWizardPanelBase\";\n            this.Size = new System.Drawing.Size(508, 250);\n            this.ResumeLayout(false);\n\n        }\n\n        #endregion\n\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/Wizard/WizardPanelBase.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Drawing;\nusing System.Data;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\n\nnamespace Sheng.Winform.Controls\n{\n    [ToolboxItem(false)]\n    public partial class WizardPanelBase : ShengUserControl\n    {\n        #region 私有成员\n\n        private IWizardView _wizardView;\n        protected internal IWizardView WizardView\n        {\n            get { return _wizardView; }\n            set { _wizardView = value; }\n        }\n\n        #endregion\n\n        #region 公开属性\n\n        private bool backSkip = false;\n        /// <summary>\n        /// 当点击上一步按钮是,是否应跳过此面板\n        /// 有些面板承担的是自动化工作,不需要人为干预,完成就会自动转入下一面板\n        /// 这类面板,在上一步时,应跳过\n        /// </summary>\n        public bool BackSkip\n        {\n            get\n            {\n                return this.backSkip;\n            }\n            protected set\n            {\n                this.backSkip = value;\n            }\n        }\n\n        #endregion\n\n        #region 构造和窗体事件\n\n        /// <summary>\n        /// 无参数构造\n        /// 仅用于兼容vs设计器\n        /// </summary>\n        public WizardPanelBase()\n        {\n            InitializeComponent();\n        }\n\n        #endregion\n\n        #region 公开方法\n\n        /// <summary>\n        /// 提交当前面板\n        /// 提交时导航按钮均不可用\n        /// </summary>\n        public virtual void Submit()\n        {\n            \n        }\n\n        /// <summary>\n        /// 之所以单独写而不是放在 Run 中是因为可能会在面板中反复调用\n        /// 如输入验证不通过就会再次 ProcessButton\n        /// </summary>\n        public virtual void ProcessButton()\n        {\n        }\n\n        /// <summary>\n        /// 开始执行当前步骤上的初始逻辑\n        /// 类似load事件,但不同的是,load事件只执行一次,此方法在每次界面呈现时都会执行\n        /// 在有需要的面板上override\n        /// </summary>\n        public virtual void Run()\n        {\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/Wizard/WizardPanelBase.resx",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n</root>"
  },
  {
    "path": "Sheng.Winform.Controls/Wizard/WizardView.Designer.cs",
    "content": "﻿namespace Sheng.Winform.Controls\n{\n    partial class WizardView\n    {\n        /// <summary>\n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Windows Form Designer generated code\n\n        /// <summary>\n        /// Required method for Designer support - do not modify\n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(WizardView));\n            this.btnNext = new System.Windows.Forms.Button();\n            this.btnBack = new System.Windows.Forms.Button();\n            this.btnFinish = new System.Windows.Forms.Button();\n            this.panelMain = new System.Windows.Forms.Panel();\n            this.pictureBox2 = new System.Windows.Forms.PictureBox();\n            this.lblTitle = new System.Windows.Forms.Label();\n            this.lblNotice = new System.Windows.Forms.Label();\n            this.seLine2 = new Sheng.Winform.Controls.ShengLine();\n            this.panel1 = new System.Windows.Forms.Panel();\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).BeginInit();\n            this.panel1.SuspendLayout();\n            this.SuspendLayout();\n            // \n            // btnNext\n            // \n            this.btnNext.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));\n            this.btnNext.Enabled = false;\n            this.btnNext.Location = new System.Drawing.Point(374, 353);\n            this.btnNext.Name = \"btnNext\";\n            this.btnNext.Size = new System.Drawing.Size(75, 23);\n            this.btnNext.TabIndex = 1;\n            this.btnNext.Text = \"下一步\";\n            this.btnNext.UseVisualStyleBackColor = true;\n            this.btnNext.EnabledChanged += new System.EventHandler(this.btnNext_EnabledChanged);\n            this.btnNext.Click += new System.EventHandler(this.btnNext_Click);\n            // \n            // btnBack\n            // \n            this.btnBack.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));\n            this.btnBack.Enabled = false;\n            this.btnBack.Location = new System.Drawing.Point(293, 353);\n            this.btnBack.Name = \"btnBack\";\n            this.btnBack.Size = new System.Drawing.Size(75, 23);\n            this.btnBack.TabIndex = 4;\n            this.btnBack.Text = \"上一步\";\n            this.btnBack.UseVisualStyleBackColor = true;\n            this.btnBack.Click += new System.EventHandler(this.btnBack_Click);\n            // \n            // btnFinish\n            // \n            this.btnFinish.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));\n            this.btnFinish.Enabled = false;\n            this.btnFinish.Location = new System.Drawing.Point(455, 353);\n            this.btnFinish.Name = \"btnFinish\";\n            this.btnFinish.Size = new System.Drawing.Size(75, 23);\n            this.btnFinish.TabIndex = 2;\n            this.btnFinish.Text = \"完成\";\n            this.btnFinish.UseVisualStyleBackColor = true;\n            this.btnFinish.Click += new System.EventHandler(this.btnFinish_Click);\n            // \n            // panelMain\n            // \n            this.panelMain.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)\n                        | System.Windows.Forms.AnchorStyles.Left)\n                        | System.Windows.Forms.AnchorStyles.Right)));\n            this.panelMain.Location = new System.Drawing.Point(17, 71);\n            this.panelMain.Margin = new System.Windows.Forms.Padding(8);\n            this.panelMain.Name = \"panelMain\";\n            this.panelMain.Size = new System.Drawing.Size(508, 250);\n            this.panelMain.TabIndex = 4;\n            // \n            // pictureBox2\n            // \n            this.pictureBox2.BackColor = System.Drawing.Color.White;\n            this.pictureBox2.Image = ((System.Drawing.Image)(resources.GetObject(\"pictureBox2.Image\")));\n            this.pictureBox2.Location = new System.Drawing.Point(12, 12);\n            this.pictureBox2.Name = \"pictureBox2\";\n            this.pictureBox2.Size = new System.Drawing.Size(40, 40);\n            this.pictureBox2.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage;\n            this.pictureBox2.TabIndex = 6;\n            this.pictureBox2.TabStop = false;\n            // \n            // lblTitle\n            // \n            this.lblTitle.AutoSize = true;\n            this.lblTitle.BackColor = System.Drawing.Color.White;\n            this.lblTitle.Font = new System.Drawing.Font(\"宋体\", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134)));\n            this.lblTitle.Location = new System.Drawing.Point(70, 25);\n            this.lblTitle.Name = \"lblTitle\";\n            this.lblTitle.Size = new System.Drawing.Size(62, 16);\n            this.lblTitle.TabIndex = 7;\n            this.lblTitle.Text = \"Wizard\";\n            // \n            // lblNotice\n            // \n            this.lblNotice.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));\n            this.lblNotice.AutoSize = true;\n            this.lblNotice.Enabled = false;\n            this.lblNotice.Location = new System.Drawing.Point(15, 358);\n            this.lblNotice.Name = \"lblNotice\";\n            this.lblNotice.Size = new System.Drawing.Size(41, 12);\n            this.lblNotice.TabIndex = 8;\n            this.lblNotice.Text = \"Wizard\";\n            // \n            // seLine2\n            // \n            this.seLine2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)\n                        | System.Windows.Forms.AnchorStyles.Right)));\n            this.seLine2.Location = new System.Drawing.Point(0, 345);\n            this.seLine2.Name = \"seLine2\";\n            this.seLine2.Size = new System.Drawing.Size(542, 2);\n            this.seLine2.TabIndex = 10;\n            this.seLine2.Text = \"seLine2\";\n            // \n            // panel1\n            // \n            this.panel1.BackColor = System.Drawing.Color.White;\n            this.panel1.Controls.Add(this.pictureBox2);\n            this.panel1.Controls.Add(this.lblTitle);\n            this.panel1.Dock = System.Windows.Forms.DockStyle.Top;\n            this.panel1.Location = new System.Drawing.Point(0, 0);\n            this.panel1.Name = \"panel1\";\n            this.panel1.Size = new System.Drawing.Size(542, 60);\n            this.panel1.TabIndex = 11;\n            // \n            // WizardView\n            // \n            this.AcceptButton = this.btnNext;\n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.ClientSize = new System.Drawing.Size(542, 388);\n            this.Controls.Add(this.panel1);\n            this.Controls.Add(this.seLine2);\n            this.Controls.Add(this.lblNotice);\n            this.Controls.Add(this.panelMain);\n            this.Controls.Add(this.btnFinish);\n            this.Controls.Add(this.btnBack);\n            this.Controls.Add(this.btnNext);\n            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;\n            this.MaximizeBox = false;\n            this.MinimizeBox = false;\n            this.Name = \"WizardView\";\n            this.ShowInTaskbar = false;\n            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;\n            this.Text = \"向导\";\n            this.Load += new System.EventHandler(this.WizardView_Load);\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).EndInit();\n            this.panel1.ResumeLayout(false);\n            this.panel1.PerformLayout();\n            this.ResumeLayout(false);\n            this.PerformLayout();\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.Button btnNext;\n        private System.Windows.Forms.Button btnBack;\n        private System.Windows.Forms.Button btnFinish;\n        private System.Windows.Forms.Label lblNotice;\n        private ShengLine seLine2;\n        protected System.Windows.Forms.PictureBox pictureBox2;\n        private System.Windows.Forms.Panel panelMain;\n        private System.Windows.Forms.Label lblTitle;\n        private System.Windows.Forms.Panel panel1;\n    }\n}"
  },
  {
    "path": "Sheng.Winform.Controls/Wizard/WizardView.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Data;\nusing System.Drawing;\nusing System.Linq;\nusing System.Runtime.InteropServices;\nusing System.Text;\nusing System.Windows.Forms;\nusing Sheng.Winform.Controls.Win32;\nusing System.Diagnostics;\n\nnamespace Sheng.Winform.Controls\n{\n    public sealed partial class WizardView : ShengForm, IWizardView\n    {\n        #region 私有成员\n\n        /// <summary>\n        /// 当前显示的面板的索引\n        /// </summary>\n        private int _currentPanel = 0;\n\n        private List<WizardPanelBase> _panelList = new List<WizardPanelBase>();\n\n        private Dictionary<string, object> _data = new Dictionary<string, object>();\n\n        private object _optionInstance;\n\n        #endregion\n\n        #region 公开属性\n\n        [Description(\"标题\")]\n        [Category(\"Sheng.Winform.Controls\")]\n        public string Title\n        {\n            get\n            {\n                return this.lblTitle.Text;\n            }\n            set\n            {\n                this.lblTitle.Text = value;\n            }\n        }\n\n        [Description(\"提示\")]\n        [Category(\"Sheng.Winform.Controls\")]\n        public string Nocite\n        {\n            get\n            {\n                return this.lblNotice.Text;\n            }\n            set\n            {\n                this.lblNotice.Text = value;\n            }\n        }\n\n        /// <summary>\n        /// 设置标题栏的关闭按钮是否可用\n        /// </summary>\n        public bool CloseButtonEnabled\n        {\n            set\n            {\n                if (value)\n                {\n                    User32.EnableMenuItem(User32.GetSystemMenu(this.Handle, false), User32.SC_CLOSE, User32.MF_ENABLE);\n                }\n                else\n                {\n                    User32.EnableMenuItem(User32.GetSystemMenu(this.Handle, false), User32.SC_CLOSE, User32.MF_DISABLE);\n                }\n            }\n        }\n\n        public bool BackButtonEnabled\n        {\n            get\n            {\n                return this.btnBack.Enabled;\n            }\n            set\n            {\n                this.btnBack.Enabled = value;\n            }\n        }\n\n        public bool NextButtonEnabled\n        {\n            get\n            {\n                return this.btnNext.Enabled;\n            }\n            set\n            {\n                this.btnNext.Enabled = value;\n            }\n        }\n\n        public bool FinishButtonEnabled\n        {\n            get\n            {\n                return this.btnFinish.Enabled;\n            }\n            set\n            {\n                this.btnFinish.Enabled = value;\n            }\n        }\n\n        #endregion\n\n        #region 构造及窗体事件\n\n        public WizardView()\n        {\n            InitializeComponent();\n        }\n\n        /// <summary>\n        /// 窗体载入\n        /// 注意,载入前就要把步骤面板设置好\n        /// </summary>\n        /// <param name=\"sender\"></param>\n        /// <param name=\"e\"></param>\n        private void WizardView_Load(object sender, EventArgs e)\n        {\n            if (this._panelList.Count > 0)\n            {\n                ShowPanel();\n            }\n        }\n\n        #endregion\n\n        #region 私有方法\n\n        /// <summary>\n        /// 显示当前步骤界面\n        /// </summary>\n        private void ShowPanel()\n        {\n            this.panelMain.Controls.Clear();\n            this._panelList[this._currentPanel].ProcessButton();\n            this._panelList[this._currentPanel].Run();\n            this.panelMain.Controls.Add(this._panelList[this._currentPanel]);\n        }\n\n        /// <summary>\n        /// 提交当前面板\n        /// </summary>\n        private void Submit()\n        {\n            BackButtonEnabled = false;\n            NextButtonEnabled = false;\n            FinishButtonEnabled = false;\n\n            this._panelList[this._currentPanel].Submit();\n            this.btnNext.Focus();\n        }\n\n        /// <summary>\n        /// 后退到上一面板\n        /// </summary>\n        private void Back()\n        {\n            this._currentPanel--;\n\n            //如果前一个面板需要被跳过\n            while (this._panelList[this._currentPanel].BackSkip)\n            {\n                this._currentPanel--;\n            }\n\n            ShowPanel();\n            this.btnBack.Focus();\n        }\n\n        #endregion\n\n        #region 公开方法\n\n        /// <summary>\n        /// 添加步骤界面\n        /// 必须按顺序加入\n        /// </summary>\n        /// <param name=\"panel\"></param>\n        public void AddStepPanel(WizardPanelBase panel)\n        {\n            Debug.Assert(panel != null, \" panel 为 null\");\n\n            panel.WizardView = this;\n            panel.Dock = DockStyle.Fill;\n            this._panelList.Add(panel);\n        }\n\n        /// <summary>\n        /// 显示下一步界面\n        /// </summary>\n        public void NextPanel()\n        {\n            this._currentPanel++;\n            ShowPanel();\n        }\n\n        public void SetData(string name, object data)\n        {\n            if (String.IsNullOrEmpty(name) || data == null)\n            {\n                Debug.Assert(false, \"name 或 data为空\");\n                throw new ArgumentException();\n            }\n\n            if (_data.Keys.Contains(name))\n            {\n                _data[name] = data;\n            }\n            else\n            {\n                _data.Add(name, data);\n            }\n        }\n\n        public object GetData(string name)\n        {\n            if (String.IsNullOrEmpty(name))\n            {\n                Debug.Assert(false, \"name 为空\");\n                throw new ArgumentException();\n            }\n\n            if (_data.Keys.Contains(name) == false)\n            {\n                Debug.Assert(false, \"没有 name 的数据\");\n                throw new ArgumentOutOfRangeException();\n            }\n\n            return _data[name];\n        }\n\n        public void SetOptionInstance<T>(T option) where T : class\n        {\n            if (option == null)\n            {\n                Debug.Assert(false, \"option 为 null\");\n                throw new ArgumentNullException();\n            }\n\n            _optionInstance = option;\n        }\n\n        public T GetOptionInstance<T>() where T : class\n        {\n            if (_optionInstance == null)\n            {\n                Debug.Assert(false, \"_optionInstance 为 null\");\n                throw new NullReferenceException();\n            }\n\n            if ((_optionInstance is T) == false)\n            {\n                Debug.Assert(false, \"_optionInstance 的类型不为 T\");\n                throw new InvalidOperationException();\n            }\n\n            return (T)_optionInstance;\n        }\n\n        #endregion\n\n        #region 事件处理\n\n        private void btnNext_Click(object sender, EventArgs e)\n        {\n            Submit();\n        }\n\n        private void btnBack_Click(object sender, EventArgs e)\n        {\n            Back();\n        }\n\n        private void btnFinish_Click(object sender, EventArgs e)\n        {\n            this.DialogResult = DialogResult.OK;\n            this.Close();\n        }\n\n        private void btnNext_EnabledChanged(object sender, EventArgs e)\n        {\n            if (this.btnNext.Enabled)\n            {\n                this.AcceptButton = this.btnNext;\n            }\n            else\n            {\n                this.AcceptButton = this.btnFinish;\n            }\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls/Wizard/WizardView.resx",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <assembly alias=\"System.Drawing\" name=\"System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\" />\n  <data name=\"pictureBox2.Image\" type=\"System.Drawing.Bitmap, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n    <value>\n        /9j/4AAQSkZJRgABAQEAAAAAAAD/2wBDAAkGBwgHBgkIBwgKCgkLDRYPDQwMDRsUFRAWIB0iIiAdHx8k\n        KDQsJCYxJx8fLT0tMTU3Ojo6Iys/RD84QzQ5Ojf/2wBDAQoKCg0MDRoPDxo3JR8lNzc3Nzc3Nzc3Nzc3\n        Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzf/wAARCAAoACgDASIAAhEBAxEB/8QA\n        HwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIh\n        MUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVW\n        V1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXG\n        x8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQF\n        BgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAV\n        YnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOE\n        hYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq\n        8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3GiordZ1RhcujtuJBRcDbngUI8puJEaILEoGyTdnce/HbFTzb\n        DsS1W1G/tdMspb2+mWG3iXLu38h6k9AByTTr27t7C1kuruQRwxjLMefoAOpJPAA5J4ryK8k1T4qa+1la\n        PJaaBZvi4nU/dPdVPRpCOp5Cg4GeS1CG2V/4i+JnjGK5025uNL8P6XOG8yNsFmH8PHDOR16hQe+fmK9a\n        0nTLLRtOg0/TbdILWBdqRr29z6k9Se9FADNZtru7s/LsbjyJd6nd7A1JJcx6bpn2jUZ1RIYwZZWPf+uT\n        0Hes7xIbq38u/W+jtLG2HmXLSNwADycd8DtnmublurH4l6WbewleS0lJ3SoSptcHGSP+eh9DwAfQknCC\n        vVk7NbLyfoW/hSuc9dXmq/FDXHsNMeSz0O1fFxdD+Ad1XsZSOp6KDjuS3qmjaVZaJpsGnaZbrBawLtRF\n        /mfUnqT3pNF0ix0PTINO0u3WC1hXCov6knuT3NXq3ICiiigClqEtrJBLbXcM0sUilXUQOQQfcCsuxGl6\n        VpR03R7N7OAKwRVt2wCepPcn8aKKTV1YA8PSS2VvIl5NNOzuWBKEkdupPPAH0raS7R+iyfitFFTTpxpw\n        UI7IqUnJ3ZKrBugP4iiiirJP/9k=\n</value>\n  </data>\n</root>"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/Form1.Designer.cs",
    "content": "﻿namespace Sheng.Winform.Controls.Demo\r\n{\r\n    partial class Form1\r\n    {\r\n        /// <summary>\r\n        /// 必需的设计器变量。\r\n        /// </summary>\r\n        private System.ComponentModel.IContainer components = null;\r\n\r\n        /// <summary>\r\n        /// 清理所有正在使用的资源。\r\n        /// </summary>\r\n        /// <param name=\"disposing\">如果应释放托管资源，为 true；否则为 false。</param>\r\n        protected override void Dispose(bool disposing)\r\n        {\r\n            if (disposing && (components != null))\r\n            {\r\n                components.Dispose();\r\n            }\r\n            base.Dispose(disposing);\r\n        }\r\n\r\n        #region Windows 窗体设计器生成的代码\r\n\r\n        /// <summary>\r\n        /// 设计器支持所需的方法 - 不要修改\r\n        /// 使用代码编辑器修改此方法的内容。\r\n        /// </summary>\r\n        private void InitializeComponent()\r\n        {\r\n            this.SuspendLayout();\r\n            // \r\n            // Form1\r\n            // \r\n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);\r\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\r\n            this.ClientSize = new System.Drawing.Size(1020, 700);\r\n            this.Name = \"Form1\";\r\n            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;\r\n            this.Text = \"Sheng.Winforms.Controls ，作者：sheng.c （QQ：279060597 @南京）\";\r\n            this.ResumeLayout(false);\r\n\r\n        }\r\n\r\n        #endregion\r\n    }\r\n}\r\n\r\n"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/Form1.cs",
    "content": "﻿using Sheng.Winform.Controls.Kernal;\r\nusing Sheng.Winform.Controls.Win32;\r\nusing System;\r\nusing System.Collections.Generic;\r\nusing System.ComponentModel;\r\nusing System.Data;\r\nusing System.Drawing;\r\nusing System.Linq;\r\nusing System.Text;\r\nusing System.Windows.Forms;\r\n\r\nnamespace Sheng.Winform.Controls.Demo\r\n{\r\n    public partial class Form1 : Form\r\n    {\r\n        private ShengAreoMainMenuStrip _menuStrip = new ShengAreoMainMenuStrip()\r\n        {\r\n            Dock = DockStyle.Top\r\n        };\r\n\r\n        private ToolStrip _toolStripPanel = new ToolStrip()\r\n        {\r\n            Dock = DockStyle.Top\r\n        };\r\n\r\n        private BrowserPane _browserPane = new BrowserPane();\r\n\r\n        private WebBrowser _webBrowser = new WebBrowser();\r\n\r\n        public Form1()\r\n        {\r\n            InitializeComponent();\r\n            InitMenuItems();\r\n\r\n            EnvironmentHelper.MainForm = this;\r\n\r\n            //处理 Areo 半透明效果\r\n            this.Paint += new PaintEventHandler(ShellView_Paint);\r\n\r\n            //初始化窗体\r\n            InitialiseForm();\r\n        }\r\n\r\n        private void InitMenuItems()\r\n        {\r\n            ToolStripMenuItem fileMenuItem = new ToolStripMenuItem()\r\n            {\r\n                Text = \"File\"\r\n            };\r\n            fileMenuItem.DropDownItems.Add(new ToolStripMenuItem() { Text = \"Open\" });\r\n            fileMenuItem.DropDownItems.Add(new ToolStripMenuItem() { Text = \"New\" });\r\n            fileMenuItem.DropDownItems.Add(new ToolStripMenuItem() { Text = \"Exit\" });\r\n\r\n            ToolStripMenuItem editMenuItem = new ToolStripMenuItem()\r\n            {\r\n                Text = \"控件库\"\r\n            };\r\n            ToolStripMenuItem shengDataGridView = new ToolStripMenuItem()\r\n            {\r\n                Text = \"ShengDataGridView\"\r\n            };\r\n            shengDataGridView.Click += (sender, e) => { FormShengDataGridView view = new FormShengDataGridView();view.Show(); };\r\n            editMenuItem.DropDownItems.Add(shengDataGridView);\r\n\r\n            shengDataGridView = new ToolStripMenuItem()\r\n            {\r\n                Text = \"ShengListView\"\r\n            };\r\n            shengDataGridView.Click += (sender, e) => { FormShengListView view = new FormShengListView(); view.Show(); };\r\n            editMenuItem.DropDownItems.Add(shengDataGridView);\r\n\r\n            shengDataGridView = new ToolStripMenuItem()\r\n            {\r\n                Text = \"ShengComboSelector\"\r\n            };\r\n            shengDataGridView.Click += (sender, e) => { FormShengComboSelector view = new FormShengComboSelector(); view.Show(); };\r\n            editMenuItem.DropDownItems.Add(shengDataGridView);\r\n\r\n            shengDataGridView = new ToolStripMenuItem()\r\n            {\r\n                Text = \"ShengComboSelector2\"\r\n            };\r\n            shengDataGridView.Click += (sender, e) => { FormShengComboSelector2 view = new FormShengComboSelector2(); view.Show(); };\r\n            editMenuItem.DropDownItems.Add(shengDataGridView);\r\n\r\n            shengDataGridView = new ToolStripMenuItem()\r\n            {\r\n                Text = \"ShengAdressBar\"\r\n            };\r\n            shengDataGridView.Click += (sender, e) => { FormShengAdressBar view = new FormShengAdressBar(); view.Show(); };\r\n            editMenuItem.DropDownItems.Add(shengDataGridView);\r\n\r\n            shengDataGridView = new ToolStripMenuItem()\r\n            {\r\n                Text = \"ShengImageListView\"\r\n            };\r\n            shengDataGridView.Click += (sender, e) => { FormShengImageListView view = new FormShengImageListView(); view.Show(); };\r\n            editMenuItem.DropDownItems.Add(shengDataGridView);\r\n\r\n            shengDataGridView = new ToolStripMenuItem()\r\n            {\r\n                Text = \"ShengTreeView\"\r\n            };\r\n            shengDataGridView.Click += (sender, e) => { FormShengTreeView view = new FormShengTreeView(); view.Show(); };\r\n            editMenuItem.DropDownItems.Add(shengDataGridView);\r\n\r\n            shengDataGridView = new ToolStripMenuItem()\r\n            {\r\n                Text = \"ShengThumbnailImageListView\"\r\n            };\r\n            shengDataGridView.Click += (sender, e) => { FormShengThumbnailImageListView view = new FormShengThumbnailImageListView(); view.Show(); };\r\n            editMenuItem.DropDownItems.Add(shengDataGridView);\r\n\r\n            shengDataGridView = new ToolStripMenuItem()\r\n            {\r\n                Text = \"Misc\"\r\n            };\r\n            shengDataGridView.Click += (sender, e) => { FormMisc view = new FormMisc(); view.Show(); };\r\n            editMenuItem.DropDownItems.Add(shengDataGridView);\r\n\r\n\r\n            _menuStrip.Items.Add(fileMenuItem);\r\n            _menuStrip.Items.Add(editMenuItem);\r\n\r\n            _toolStripPanel.Items.Add(new ToolStripButton()\r\n            {\r\n                Image = Resource1.Browser_Home\r\n            });\r\n            _toolStripPanel.Items.Add(new ToolStripButton()\r\n            {\r\n                Text = \"Open\"\r\n            });\r\n        }\r\n\r\n        private void ShellView_Paint(object sender, PaintEventArgs e)\r\n        {\r\n            #region 处理 Areo 效果\r\n\r\n            //处理 Dwm 半透明效果\r\n            if (EnvironmentHelper.SupportAreo && EnvironmentHelper.DwmIsCompositionEnabled)\r\n            {\r\n                switch (_RenderMode)\r\n                {\r\n                    case RenderMode.EntireWindow:\r\n                        e.Graphics.FillRectangle(Brushes.Black, this.ClientRectangle);\r\n                        break;\r\n\r\n                    case RenderMode.TopWindow:\r\n                        e.Graphics.FillRectangle(Brushes.Black, Rectangle.FromLTRB(0, 0, this.ClientRectangle.Width, _glassMargins.cyTopHeight));\r\n                        break;\r\n\r\n                    case RenderMode.Region:\r\n                        if (_blurRegion != null) e.Graphics.FillRegion(Brushes.Black, _blurRegion);\r\n                        break;\r\n                }\r\n            }\r\n\r\n            #endregion\r\n        }\r\n\r\n        protected override void WndProc(ref Message msg)\r\n        {\r\n            base.WndProc(ref msg); \r\n\r\n            const int WM_DWMCOMPOSITIONCHANGED = 0x031E;\r\n            const int WM_NCHITTEST = 0x84;\r\n            const int HTCLIENT = 0x01;\r\n\r\n            switch (msg.Msg)\r\n            {\r\n                #region 处理 Areo 效果\r\n\r\n                case WM_NCHITTEST:\r\n                    if (HTCLIENT == msg.Result.ToInt32())\r\n                    {\r\n                        Point p = new Point();\r\n                        p.X = (msg.LParam.ToInt32() & 0xFFFF);\r\n                        p.Y = (msg.LParam.ToInt32() >> 16); \r\n\r\n                        p = PointToClient(p);\r\n\r\n                        if (PointIsOnGlass(p))\r\n                            msg.Result = new IntPtr(2);\r\n                    }\r\n                    break;\r\n\r\n                case WM_DWMCOMPOSITIONCHANGED:\r\n                    if (DwmApi.DwmIsCompositionEnabled() == false)\r\n                    {\r\n                        _RenderMode = RenderMode.None;\r\n                        _glassMargins = null;\r\n                        if (_blurRegion != null)\r\n                        {\r\n                            _blurRegion.Dispose();\r\n                            _blurRegion = null;\r\n                        }\r\n                    }\r\n                    else\r\n                    {\r\n                        InitAreo();\r\n                    }\r\n                    break;\r\n\r\n                    #endregion\r\n            }\r\n        }\r\n\r\n        private void InitialiseForm()\r\n        {\r\n            this.Controls.Add(_menuStrip);\r\n            _menuStrip.BringToFront();\r\n            this.Controls.Add(_toolStripPanel);\r\n            _menuStrip.SendToBack();\r\n\r\n            _webBrowser.Dock = DockStyle.Bottom;\r\n            _webBrowser.Height = 100;\r\n            this.Controls.Add(_webBrowser);\r\n            _webBrowser.BringToFront();\r\n            _webBrowser.Navigate(\"http://www.shengxunwei.com/banner.html\");\r\n            \r\n\r\n            //browserPane\r\n            _browserPane.View.GetSchemeFunc = (sender, e) =>\r\n            {\r\n                if (e.SchemeName.Equals(StartPageScheme.SCHEMENAME, StringComparison.CurrentCultureIgnoreCase))\r\n                    return StartPageScheme.Instance;\r\n                else\r\n                    return null;\r\n            };\r\n\r\n            //_browserPane.View.StatusTextChanged = (e) => { workbenchService.SetStatusMessage(e); };\r\n            //_browserPane.View.TitleChanged = (e) => { this.TabText = e; };\r\n            //_browserPane.View.NewWindow += (sender, e) => { workbenchService.Show(new BrowserView(e.BrowserPane, e.Url)); };\r\n\r\n            this.Controls.Add(_browserPane.View);\r\n            _browserPane.View.BringToFront();\r\n\r\n            _browserPane.Navigate(StartPageScheme.STARTPAGE_URI);\r\n\r\n            InitAreo();\r\n            this.Activate();\r\n        }\r\n\r\n        #region Areo效果\r\n\r\n        private DwmApi.MARGINS _glassMargins;\r\n        private enum RenderMode { None, EntireWindow, TopWindow, Region };\r\n        private RenderMode _RenderMode;\r\n        private Region _blurRegion;\r\n\r\n        private void InitAreo()\r\n        {\r\n            if (EnvironmentHelper.SupportAreo && EnvironmentHelper.DwmIsCompositionEnabled)\r\n            {\r\n                _glassMargins = new DwmApi.MARGINS(0, this._menuStrip.Height, 0, 0);\r\n                _RenderMode = RenderMode.TopWindow;\r\n\r\n                if (DwmApi.DwmIsCompositionEnabled())\r\n                    DwmApi.DwmExtendFrameIntoClientArea(this.Handle, _glassMargins);\r\n\r\n                this.Invalidate();\r\n                this._menuStrip.Invalidate();\r\n            }\r\n        }\r\n\r\n        private bool PointIsOnGlass(Point p)\r\n        {\r\n            return _glassMargins != null &&\r\n                (_glassMargins.cyTopHeight <= 0 ||\r\n                 _glassMargins.cyTopHeight > p.Y);\r\n        }\r\n\r\n        #endregion\r\n    }\r\n}\r\n"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/Form1.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<root>\r\n  <!-- \r\n    Microsoft ResX Schema \r\n    \r\n    Version 2.0\r\n    \r\n    The primary goals of this format is to allow a simple XML format \r\n    that is mostly human readable. The generation and parsing of the \r\n    various data types are done through the TypeConverter classes \r\n    associated with the data types.\r\n    \r\n    Example:\r\n    \r\n    ... ado.net/XML headers & schema ...\r\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\r\n    <resheader name=\"version\">2.0</resheader>\r\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\r\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\r\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\r\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\r\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\r\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\r\n    </data>\r\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\r\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\r\n        <comment>This is a comment</comment>\r\n    </data>\r\n                \r\n    There are any number of \"resheader\" rows that contain simple \r\n    name/value pairs.\r\n    \r\n    Each data row contains a name, and value. The row also contains a \r\n    type or mimetype. Type corresponds to a .NET class that support \r\n    text/value conversion through the TypeConverter architecture. \r\n    Classes that don't support this are serialized and stored with the \r\n    mimetype set.\r\n    \r\n    The mimetype is used for serialized objects, and tells the \r\n    ResXResourceReader how to depersist the object. This is currently not \r\n    extensible. For a given mimetype the value must be set accordingly:\r\n    \r\n    Note - application/x-microsoft.net.object.binary.base64 is the format \r\n    that the ResXResourceWriter will generate, however the reader can \r\n    read any of the formats listed below.\r\n    \r\n    mimetype: application/x-microsoft.net.object.binary.base64\r\n    value   : The object must be serialized with \r\n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\r\n            : and then encoded with base64 encoding.\r\n    \r\n    mimetype: application/x-microsoft.net.object.soap.base64\r\n    value   : The object must be serialized with \r\n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\r\n            : and then encoded with base64 encoding.\r\n\r\n    mimetype: application/x-microsoft.net.object.bytearray.base64\r\n    value   : The object must be serialized into a byte array \r\n            : using a System.ComponentModel.TypeConverter\r\n            : and then encoded with base64 encoding.\r\n    -->\r\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\r\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\r\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\r\n      <xsd:complexType>\r\n        <xsd:choice maxOccurs=\"unbounded\">\r\n          <xsd:element name=\"metadata\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\r\n              <xsd:attribute ref=\"xml:space\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"assembly\">\r\n            <xsd:complexType>\r\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"data\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\r\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\r\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\r\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\r\n              <xsd:attribute ref=\"xml:space\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"resheader\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n        </xsd:choice>\r\n      </xsd:complexType>\r\n    </xsd:element>\r\n  </xsd:schema>\r\n  <resheader name=\"resmimetype\">\r\n    <value>text/microsoft-resx</value>\r\n  </resheader>\r\n  <resheader name=\"version\">\r\n    <value>2.0</value>\r\n  </resheader>\r\n  <resheader name=\"reader\">\r\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r\n  </resheader>\r\n  <resheader name=\"writer\">\r\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r\n  </resheader>\r\n</root>"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/FormMisc.Designer.cs",
    "content": "﻿namespace Sheng.Winform.Controls.Demo\r\n{\r\n    partial class FormMisc\r\n    {\r\n        /// <summary>\r\n        /// Required designer variable.\r\n        /// </summary>\r\n        private System.ComponentModel.IContainer components = null;\r\n\r\n        /// <summary>\r\n        /// Clean up any resources being used.\r\n        /// </summary>\r\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\r\n        protected override void Dispose(bool disposing)\r\n        {\r\n            if (disposing && (components != null))\r\n            {\r\n                components.Dispose();\r\n            }\r\n            base.Dispose(disposing);\r\n        }\r\n\r\n        #region Windows Form Designer generated code\r\n\r\n        /// <summary>\r\n        /// Required method for Designer support - do not modify\r\n        /// the contents of this method with the code editor.\r\n        /// </summary>\r\n        private void InitializeComponent()\r\n        {\r\n            this.label1 = new System.Windows.Forms.Label();\r\n            this.label2 = new System.Windows.Forms.Label();\r\n            this.shengSimpleCheckBox2 = new Sheng.Winform.Controls.ShengSimpleCheckBox();\r\n            this.shengSimpleCheckBox1 = new Sheng.Winform.Controls.ShengSimpleCheckBox();\r\n            this.shengLoadingCircle2 = new Sheng.Winform.Controls.ShengLoadingCircle();\r\n            this.shengLoadingCircle1 = new Sheng.Winform.Controls.ShengLoadingCircle();\r\n            this.shengLine1 = new Sheng.Winform.Controls.ShengLine();\r\n            this.shengFlatButton2 = new Sheng.Winform.Controls.ShengFlatButton();\r\n            this.shengFlatButton1 = new Sheng.Winform.Controls.ShengFlatButton();\r\n            this.shengAdvLabel1 = new Sheng.Winform.Controls.ShengAdvLabel();\r\n            this.SuspendLayout();\r\n            // \r\n            // label1\r\n            // \r\n            this.label1.AutoSize = true;\r\n            this.label1.Location = new System.Drawing.Point(12, 139);\r\n            this.label1.Name = \"label1\";\r\n            this.label1.Size = new System.Drawing.Size(119, 12);\r\n            this.label1.TabIndex = 3;\r\n            this.label1.Text = \"AllowSelect = false\";\r\n            // \r\n            // label2\r\n            // \r\n            this.label2.AutoSize = true;\r\n            this.label2.Location = new System.Drawing.Point(198, 139);\r\n            this.label2.Name = \"label2\";\r\n            this.label2.Size = new System.Drawing.Size(113, 12);\r\n            this.label2.TabIndex = 4;\r\n            this.label2.Text = \"AllowSelect = true\";\r\n            // \r\n            // shengSimpleCheckBox2\r\n            // \r\n            this.shengSimpleCheckBox2.Check = true;\r\n            this.shengSimpleCheckBox2.Location = new System.Drawing.Point(69, 288);\r\n            this.shengSimpleCheckBox2.Name = \"shengSimpleCheckBox2\";\r\n            this.shengSimpleCheckBox2.Size = new System.Drawing.Size(23, 22);\r\n            this.shengSimpleCheckBox2.TabIndex = 9;\r\n            this.shengSimpleCheckBox2.Text = \"shengSimpleCheckBox2\";\r\n            // \r\n            // shengSimpleCheckBox1\r\n            // \r\n            this.shengSimpleCheckBox1.Check = false;\r\n            this.shengSimpleCheckBox1.Location = new System.Drawing.Point(33, 288);\r\n            this.shengSimpleCheckBox1.Name = \"shengSimpleCheckBox1\";\r\n            this.shengSimpleCheckBox1.Size = new System.Drawing.Size(23, 22);\r\n            this.shengSimpleCheckBox1.TabIndex = 8;\r\n            this.shengSimpleCheckBox1.Text = \"shengSimpleCheckBox1\";\r\n            // \r\n            // shengLoadingCircle2\r\n            // \r\n            this.shengLoadingCircle2.Active = true;\r\n            this.shengLoadingCircle2.Color = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(192)))), ((int)(((byte)(255)))));\r\n            this.shengLoadingCircle2.InnerCircleRadius = 8;\r\n            this.shengLoadingCircle2.Location = new System.Drawing.Point(119, 201);\r\n            this.shengLoadingCircle2.Name = \"shengLoadingCircle2\";\r\n            this.shengLoadingCircle2.NumberSpoke = 24;\r\n            this.shengLoadingCircle2.OuterCircleRadius = 9;\r\n            this.shengLoadingCircle2.RotationSpeed = 50;\r\n            this.shengLoadingCircle2.Size = new System.Drawing.Size(75, 55);\r\n            this.shengLoadingCircle2.SpokeThickness = 4;\r\n            this.shengLoadingCircle2.StylePreset = Sheng.Winform.Controls.ShengLoadingCircle.StylePresets.IE7;\r\n            this.shengLoadingCircle2.TabIndex = 7;\r\n            this.shengLoadingCircle2.Text = \"shengLoadingCircle2\";\r\n            // \r\n            // shengLoadingCircle1\r\n            // \r\n            this.shengLoadingCircle1.Active = true;\r\n            this.shengLoadingCircle1.Color = System.Drawing.Color.DarkGray;\r\n            this.shengLoadingCircle1.InnerCircleRadius = 5;\r\n            this.shengLoadingCircle1.Location = new System.Drawing.Point(17, 201);\r\n            this.shengLoadingCircle1.Name = \"shengLoadingCircle1\";\r\n            this.shengLoadingCircle1.NumberSpoke = 12;\r\n            this.shengLoadingCircle1.OuterCircleRadius = 11;\r\n            this.shengLoadingCircle1.RotationSpeed = 100;\r\n            this.shengLoadingCircle1.Size = new System.Drawing.Size(75, 55);\r\n            this.shengLoadingCircle1.SpokeThickness = 2;\r\n            this.shengLoadingCircle1.StylePreset = Sheng.Winform.Controls.ShengLoadingCircle.StylePresets.MacOSX;\r\n            this.shengLoadingCircle1.TabIndex = 6;\r\n            this.shengLoadingCircle1.Text = \"shengLoadingCircle1\";\r\n            // \r\n            // shengLine1\r\n            // \r\n            this.shengLine1.Location = new System.Drawing.Point(17, 181);\r\n            this.shengLine1.Name = \"shengLine1\";\r\n            this.shengLine1.Size = new System.Drawing.Size(365, 14);\r\n            this.shengLine1.TabIndex = 5;\r\n            this.shengLine1.Text = \"shengLine1\";\r\n            // \r\n            // shengFlatButton2\r\n            // \r\n            this.shengFlatButton2.AllowSelect = true;\r\n            this.shengFlatButton2.Image = global::Sheng.Winform.Controls.Demo.Resource1.Browser_Home;\r\n            this.shengFlatButton2.Location = new System.Drawing.Point(200, 87);\r\n            this.shengFlatButton2.Name = \"shengFlatButton2\";\r\n            this.shengFlatButton2.Selected = false;\r\n            this.shengFlatButton2.ShowText = \"ShengFlatButton\";\r\n            this.shengFlatButton2.Size = new System.Drawing.Size(182, 40);\r\n            this.shengFlatButton2.TabIndex = 2;\r\n            // \r\n            // shengFlatButton1\r\n            // \r\n            this.shengFlatButton1.AllowSelect = false;\r\n            this.shengFlatButton1.Image = global::Sheng.Winform.Controls.Demo.Resource1.Browser_Home;\r\n            this.shengFlatButton1.Location = new System.Drawing.Point(12, 87);\r\n            this.shengFlatButton1.Name = \"shengFlatButton1\";\r\n            this.shengFlatButton1.Selected = false;\r\n            this.shengFlatButton1.ShowText = \"ShengFlatButton\";\r\n            this.shengFlatButton1.Size = new System.Drawing.Size(182, 40);\r\n            this.shengFlatButton1.TabIndex = 1;\r\n            // \r\n            // shengAdvLabel1\r\n            // \r\n            this.shengAdvLabel1.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(255)))), ((int)(((byte)(192)))));\r\n            this.shengAdvLabel1.FillColorEnd = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(192)))), ((int)(((byte)(192)))));\r\n            this.shengAdvLabel1.FillColorStart = System.Drawing.Color.FromArgb(((int)(((byte)(128)))), ((int)(((byte)(128)))), ((int)(((byte)(255)))));\r\n            this.shengAdvLabel1.FillMode = System.Drawing.Drawing2D.LinearGradientMode.Vertical;\r\n            this.shengAdvLabel1.FillStyle = Sheng.Winform.Controls.FillStyle.LinearGradient;\r\n            this.shengAdvLabel1.ForeColor = System.Drawing.Color.White;\r\n            this.shengAdvLabel1.Location = new System.Drawing.Point(12, 23);\r\n            this.shengAdvLabel1.Name = \"shengAdvLabel1\";\r\n            this.shengAdvLabel1.ShowBorder = true;\r\n            this.shengAdvLabel1.SingleLine = false;\r\n            this.shengAdvLabel1.Size = new System.Drawing.Size(354, 38);\r\n            this.shengAdvLabel1.TabIndex = 0;\r\n            this.shengAdvLabel1.Text = \" ShengAdvLabel ：可定制外观的 Label\";\r\n            this.shengAdvLabel1.TextHorizontalCenter = false;\r\n            this.shengAdvLabel1.TextVerticalCenter = true;\r\n            // \r\n            // FormMisc\r\n            // \r\n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);\r\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\r\n            this.ClientSize = new System.Drawing.Size(764, 488);\r\n            this.Controls.Add(this.shengSimpleCheckBox2);\r\n            this.Controls.Add(this.shengSimpleCheckBox1);\r\n            this.Controls.Add(this.shengLoadingCircle2);\r\n            this.Controls.Add(this.shengLoadingCircle1);\r\n            this.Controls.Add(this.shengLine1);\r\n            this.Controls.Add(this.label2);\r\n            this.Controls.Add(this.label1);\r\n            this.Controls.Add(this.shengFlatButton2);\r\n            this.Controls.Add(this.shengFlatButton1);\r\n            this.Controls.Add(this.shengAdvLabel1);\r\n            this.Name = \"FormMisc\";\r\n            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;\r\n            this.Text = \"FormMisc\";\r\n            this.Load += new System.EventHandler(this.FormMisc_Load);\r\n            this.ResumeLayout(false);\r\n            this.PerformLayout();\r\n\r\n        }\r\n\r\n        #endregion\r\n\r\n        private ShengAdvLabel shengAdvLabel1;\r\n        private ShengFlatButton shengFlatButton1;\r\n        private ShengFlatButton shengFlatButton2;\r\n        private System.Windows.Forms.Label label1;\r\n        private System.Windows.Forms.Label label2;\r\n        private ShengLine shengLine1;\r\n        private ShengLoadingCircle shengLoadingCircle1;\r\n        private ShengLoadingCircle shengLoadingCircle2;\r\n        private ShengSimpleCheckBox shengSimpleCheckBox1;\r\n        private ShengSimpleCheckBox shengSimpleCheckBox2;\r\n    }\r\n}"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/FormMisc.cs",
    "content": "﻿using System;\r\nusing System.Collections.Generic;\r\nusing System.ComponentModel;\r\nusing System.Data;\r\nusing System.Drawing;\r\nusing System.Linq;\r\nusing System.Text;\r\nusing System.Windows.Forms;\r\n\r\nnamespace Sheng.Winform.Controls.Demo\r\n{\r\n    public partial class FormMisc : Form\r\n    {\r\n        public FormMisc()\r\n        {\r\n            InitializeComponent();\r\n        }\r\n\r\n        private void FormMisc_Load(object sender, EventArgs e)\r\n        {\r\n\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/FormMisc.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<root>\r\n  <!-- \r\n    Microsoft ResX Schema \r\n    \r\n    Version 2.0\r\n    \r\n    The primary goals of this format is to allow a simple XML format \r\n    that is mostly human readable. The generation and parsing of the \r\n    various data types are done through the TypeConverter classes \r\n    associated with the data types.\r\n    \r\n    Example:\r\n    \r\n    ... ado.net/XML headers & schema ...\r\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\r\n    <resheader name=\"version\">2.0</resheader>\r\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\r\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\r\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\r\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\r\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\r\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\r\n    </data>\r\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\r\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\r\n        <comment>This is a comment</comment>\r\n    </data>\r\n                \r\n    There are any number of \"resheader\" rows that contain simple \r\n    name/value pairs.\r\n    \r\n    Each data row contains a name, and value. The row also contains a \r\n    type or mimetype. Type corresponds to a .NET class that support \r\n    text/value conversion through the TypeConverter architecture. \r\n    Classes that don't support this are serialized and stored with the \r\n    mimetype set.\r\n    \r\n    The mimetype is used for serialized objects, and tells the \r\n    ResXResourceReader how to depersist the object. This is currently not \r\n    extensible. For a given mimetype the value must be set accordingly:\r\n    \r\n    Note - application/x-microsoft.net.object.binary.base64 is the format \r\n    that the ResXResourceWriter will generate, however the reader can \r\n    read any of the formats listed below.\r\n    \r\n    mimetype: application/x-microsoft.net.object.binary.base64\r\n    value   : The object must be serialized with \r\n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\r\n            : and then encoded with base64 encoding.\r\n    \r\n    mimetype: application/x-microsoft.net.object.soap.base64\r\n    value   : The object must be serialized with \r\n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\r\n            : and then encoded with base64 encoding.\r\n\r\n    mimetype: application/x-microsoft.net.object.bytearray.base64\r\n    value   : The object must be serialized into a byte array \r\n            : using a System.ComponentModel.TypeConverter\r\n            : and then encoded with base64 encoding.\r\n    -->\r\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\r\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\r\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\r\n      <xsd:complexType>\r\n        <xsd:choice maxOccurs=\"unbounded\">\r\n          <xsd:element name=\"metadata\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\r\n              <xsd:attribute ref=\"xml:space\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"assembly\">\r\n            <xsd:complexType>\r\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"data\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\r\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\r\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\r\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\r\n              <xsd:attribute ref=\"xml:space\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"resheader\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n        </xsd:choice>\r\n      </xsd:complexType>\r\n    </xsd:element>\r\n  </xsd:schema>\r\n  <resheader name=\"resmimetype\">\r\n    <value>text/microsoft-resx</value>\r\n  </resheader>\r\n  <resheader name=\"version\">\r\n    <value>2.0</value>\r\n  </resheader>\r\n  <resheader name=\"reader\">\r\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r\n  </resheader>\r\n  <resheader name=\"writer\">\r\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r\n  </resheader>\r\n</root>"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/FormShengAdressBar.Designer.cs",
    "content": "﻿namespace Sheng.Winform.Controls.Demo\r\n{\r\n    partial class FormShengAdressBar\r\n    {\r\n        /// <summary>\r\n        /// Required designer variable.\r\n        /// </summary>\r\n        private System.ComponentModel.IContainer components = null;\r\n\r\n        /// <summary>\r\n        /// Clean up any resources being used.\r\n        /// </summary>\r\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\r\n        protected override void Dispose(bool disposing)\r\n        {\r\n            if (disposing && (components != null))\r\n            {\r\n                components.Dispose();\r\n            }\r\n            base.Dispose(disposing);\r\n        }\r\n\r\n        #region Windows Form Designer generated code\r\n\r\n        /// <summary>\r\n        /// Required method for Designer support - do not modify\r\n        /// the contents of this method with the code editor.\r\n        /// </summary>\r\n        private void InitializeComponent()\r\n        {\r\n            System.Windows.Forms.ToolStripSystemRenderer toolStripSystemRenderer1 = new System.Windows.Forms.ToolStripSystemRenderer();\r\n            this.shengAddressBar1 = new Sheng.Winform.Controls.SEAdressBar.ShengAddressBar();\r\n            this.shengLine1 = new Sheng.Winform.Controls.ShengLine();\r\n            this.pictureBox1 = new System.Windows.Forms.PictureBox();\r\n            this.label1 = new System.Windows.Forms.Label();\r\n            this.label2 = new System.Windows.Forms.Label();\r\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();\r\n            this.SuspendLayout();\r\n            // \r\n            // shengAddressBar1\r\n            // \r\n            this.shengAddressBar1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \r\n            | System.Windows.Forms.AnchorStyles.Right)));\r\n            this.shengAddressBar1.CurrentNode = null;\r\n            this.shengAddressBar1.DropDownRenderer = null;\r\n            this.shengAddressBar1.Location = new System.Drawing.Point(26, 38);\r\n            this.shengAddressBar1.Name = \"shengAddressBar1\";\r\n            this.shengAddressBar1.Renderer = toolStripSystemRenderer1;\r\n            this.shengAddressBar1.Size = new System.Drawing.Size(711, 28);\r\n            this.shengAddressBar1.TabIndex = 0;\r\n            // \r\n            // shengLine1\r\n            // \r\n            this.shengLine1.Location = new System.Drawing.Point(26, 82);\r\n            this.shengLine1.Name = \"shengLine1\";\r\n            this.shengLine1.Size = new System.Drawing.Size(75, 23);\r\n            this.shengLine1.TabIndex = 1;\r\n            this.shengLine1.Text = \"shengLine1\";\r\n            // \r\n            // pictureBox1\r\n            // \r\n            this.pictureBox1.Image = global::Sheng.Winform.Controls.Demo.Resource1._9;\r\n            this.pictureBox1.Location = new System.Drawing.Point(26, 111);\r\n            this.pictureBox1.Name = \"pictureBox1\";\r\n            this.pictureBox1.Size = new System.Drawing.Size(311, 192);\r\n            this.pictureBox1.TabIndex = 2;\r\n            this.pictureBox1.TabStop = false;\r\n            // \r\n            // label1\r\n            // \r\n            this.label1.AutoSize = true;\r\n            this.label1.Location = new System.Drawing.Point(367, 111);\r\n            this.label1.Name = \"label1\";\r\n            this.label1.Size = new System.Drawing.Size(353, 12);\r\n            this.label1.TabIndex = 3;\r\n            this.label1.Text = \"ShengAdressBar 是一个模仿 Windows 资源管理器地址栏的控件。\";\r\n            // \r\n            // label2\r\n            // \r\n            this.label2.Location = new System.Drawing.Point(367, 144);\r\n            this.label2.Name = \"label2\";\r\n            this.label2.Size = new System.Drawing.Size(385, 51);\r\n            this.label2.TabIndex = 4;\r\n            this.label2.Text = \"除了默认实现的 ShengFileSystemNode ，用来提供和资源管理器地址栏一样的功能之外，你也可以继承 IShengAddressNode 接口，实现自\" +\r\n    \"己的基于任何数据的路径选择器。并不局限于磁盘路径的选择。\";\r\n            // \r\n            // FormShengAdressBar\r\n            // \r\n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);\r\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\r\n            this.ClientSize = new System.Drawing.Size(764, 427);\r\n            this.Controls.Add(this.label2);\r\n            this.Controls.Add(this.label1);\r\n            this.Controls.Add(this.pictureBox1);\r\n            this.Controls.Add(this.shengLine1);\r\n            this.Controls.Add(this.shengAddressBar1);\r\n            this.Name = \"FormShengAdressBar\";\r\n            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;\r\n            this.Text = \"FormShengAdressBar\";\r\n            this.Load += new System.EventHandler(this.FormShengAdressBar_Load);\r\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();\r\n            this.ResumeLayout(false);\r\n            this.PerformLayout();\r\n\r\n        }\r\n\r\n        #endregion\r\n\r\n        private SEAdressBar.ShengAddressBar shengAddressBar1;\r\n        private ShengLine shengLine1;\r\n        private System.Windows.Forms.PictureBox pictureBox1;\r\n        private System.Windows.Forms.Label label1;\r\n        private System.Windows.Forms.Label label2;\r\n    }\r\n}"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/FormShengAdressBar.cs",
    "content": "﻿using System;\r\nusing System.Collections.Generic;\r\nusing System.ComponentModel;\r\nusing System.Data;\r\nusing System.Drawing;\r\nusing System.Linq;\r\nusing System.Text;\r\nusing System.Windows.Forms;\r\n\r\nnamespace Sheng.Winform.Controls.Demo\r\n{\r\n    public partial class FormShengAdressBar : Form\r\n    {\r\n        public FormShengAdressBar()\r\n        {\r\n            InitializeComponent();\r\n        }\r\n\r\n        private void FormShengAdressBar_Load(object sender, EventArgs e)\r\n        {\r\n            shengAddressBar1.InitializeRoot(new ShengFileSystemNode());\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/FormShengAdressBar.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<root>\r\n  <!-- \r\n    Microsoft ResX Schema \r\n    \r\n    Version 2.0\r\n    \r\n    The primary goals of this format is to allow a simple XML format \r\n    that is mostly human readable. The generation and parsing of the \r\n    various data types are done through the TypeConverter classes \r\n    associated with the data types.\r\n    \r\n    Example:\r\n    \r\n    ... ado.net/XML headers & schema ...\r\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\r\n    <resheader name=\"version\">2.0</resheader>\r\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\r\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\r\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\r\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\r\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\r\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\r\n    </data>\r\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\r\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\r\n        <comment>This is a comment</comment>\r\n    </data>\r\n                \r\n    There are any number of \"resheader\" rows that contain simple \r\n    name/value pairs.\r\n    \r\n    Each data row contains a name, and value. The row also contains a \r\n    type or mimetype. Type corresponds to a .NET class that support \r\n    text/value conversion through the TypeConverter architecture. \r\n    Classes that don't support this are serialized and stored with the \r\n    mimetype set.\r\n    \r\n    The mimetype is used for serialized objects, and tells the \r\n    ResXResourceReader how to depersist the object. This is currently not \r\n    extensible. For a given mimetype the value must be set accordingly:\r\n    \r\n    Note - application/x-microsoft.net.object.binary.base64 is the format \r\n    that the ResXResourceWriter will generate, however the reader can \r\n    read any of the formats listed below.\r\n    \r\n    mimetype: application/x-microsoft.net.object.binary.base64\r\n    value   : The object must be serialized with \r\n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\r\n            : and then encoded with base64 encoding.\r\n    \r\n    mimetype: application/x-microsoft.net.object.soap.base64\r\n    value   : The object must be serialized with \r\n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\r\n            : and then encoded with base64 encoding.\r\n\r\n    mimetype: application/x-microsoft.net.object.bytearray.base64\r\n    value   : The object must be serialized into a byte array \r\n            : using a System.ComponentModel.TypeConverter\r\n            : and then encoded with base64 encoding.\r\n    -->\r\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\r\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\r\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\r\n      <xsd:complexType>\r\n        <xsd:choice maxOccurs=\"unbounded\">\r\n          <xsd:element name=\"metadata\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\r\n              <xsd:attribute ref=\"xml:space\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"assembly\">\r\n            <xsd:complexType>\r\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"data\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\r\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\r\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\r\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\r\n              <xsd:attribute ref=\"xml:space\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"resheader\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n        </xsd:choice>\r\n      </xsd:complexType>\r\n    </xsd:element>\r\n  </xsd:schema>\r\n  <resheader name=\"resmimetype\">\r\n    <value>text/microsoft-resx</value>\r\n  </resheader>\r\n  <resheader name=\"version\">\r\n    <value>2.0</value>\r\n  </resheader>\r\n  <resheader name=\"reader\">\r\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r\n  </resheader>\r\n  <resheader name=\"writer\">\r\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r\n  </resheader>\r\n</root>"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/FormShengComboSelector.Designer.cs",
    "content": "﻿namespace Sheng.Winform.Controls.Demo\r\n{\r\n    partial class FormShengComboSelector\r\n    {\r\n        /// <summary>\r\n        /// Required designer variable.\r\n        /// </summary>\r\n        private System.ComponentModel.IContainer components = null;\r\n\r\n        /// <summary>\r\n        /// Clean up any resources being used.\r\n        /// </summary>\r\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\r\n        protected override void Dispose(bool disposing)\r\n        {\r\n            if (disposing && (components != null))\r\n            {\r\n                components.Dispose();\r\n            }\r\n            base.Dispose(disposing);\r\n        }\r\n\r\n        #region Windows Form Designer generated code\r\n\r\n        /// <summary>\r\n        /// Required method for Designer support - do not modify\r\n        /// the contents of this method with the code editor.\r\n        /// </summary>\r\n        private void InitializeComponent()\r\n        {\r\n            this.shengComboSelector1 = new Sheng.Winform.Controls.ShengComboSelector();\r\n            this.label3 = new System.Windows.Forms.Label();\r\n            this.label2 = new System.Windows.Forms.Label();\r\n            this.label1 = new System.Windows.Forms.Label();\r\n            this.pictureBox2 = new System.Windows.Forms.PictureBox();\r\n            this.pictureBox1 = new System.Windows.Forms.PictureBox();\r\n            this.shengComboSelector2 = new Sheng.Winform.Controls.ShengComboSelector();\r\n            this.label4 = new System.Windows.Forms.Label();\r\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).BeginInit();\r\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();\r\n            this.SuspendLayout();\r\n            // \r\n            // shengComboSelector1\r\n            // \r\n            this.shengComboSelector1.AllowEmpty = true;\r\n            this.shengComboSelector1.BackColor = System.Drawing.SystemColors.Window;\r\n            this.shengComboSelector1.BorderColor = System.Drawing.SystemColors.ControlDark;\r\n            this.shengComboSelector1.CustomValidate = null;\r\n            this.shengComboSelector1.DataSource = null;\r\n            this.shengComboSelector1.DataSourceType = null;\r\n            this.shengComboSelector1.DescriptionColor = System.Drawing.Color.DarkGray;\r\n            this.shengComboSelector1.DescriptionMember = null;\r\n            this.shengComboSelector1.DisplayMember = null;\r\n            this.shengComboSelector1.FocusBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(232)))), ((int)(((byte)(246)))));\r\n            this.shengComboSelector1.FocusBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(152)))), ((int)(((byte)(180)))), ((int)(((byte)(226)))));\r\n            this.shengComboSelector1.FocusDescriptionColor = System.Drawing.Color.DarkGray;\r\n            this.shengComboSelector1.FocusTextColor = System.Drawing.Color.Black;\r\n            this.shengComboSelector1.HighLight = true;\r\n            this.shengComboSelector1.ItemBackgroundColor = System.Drawing.Color.White;\r\n            this.shengComboSelector1.ItemBorderColor = System.Drawing.Color.White;\r\n            this.shengComboSelector1.ItemDescriptionColor = System.Drawing.Color.DarkGray;\r\n            this.shengComboSelector1.ItemFocusBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(152)))), ((int)(((byte)(180)))), ((int)(((byte)(226)))));\r\n            this.shengComboSelector1.ItemFocusColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(232)))), ((int)(((byte)(246)))));\r\n            this.shengComboSelector1.ItemFocusDescriptionColor = System.Drawing.Color.DarkGray;\r\n            this.shengComboSelector1.ItemFocusTextColor = System.Drawing.Color.Black;\r\n            this.shengComboSelector1.ItemSelectedBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(49)))), ((int)(((byte)(106)))), ((int)(((byte)(197)))));\r\n            this.shengComboSelector1.ItemSelectedColor = System.Drawing.Color.FromArgb(((int)(((byte)(193)))), ((int)(((byte)(210)))), ((int)(((byte)(238)))));\r\n            this.shengComboSelector1.ItemSelectedDescriptionColor = System.Drawing.Color.DarkGray;\r\n            this.shengComboSelector1.ItemSelectedTextColor = System.Drawing.Color.Black;\r\n            this.shengComboSelector1.ItemTextColor = System.Drawing.Color.Black;\r\n            this.shengComboSelector1.Location = new System.Drawing.Point(307, 38);\r\n            this.shengComboSelector1.MaxItem = 8;\r\n            this.shengComboSelector1.Name = \"shengComboSelector1\";\r\n            this.shengComboSelector1.SelectedBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(49)))), ((int)(((byte)(106)))), ((int)(((byte)(197)))));\r\n            this.shengComboSelector1.SelectedColor = System.Drawing.Color.FromArgb(((int)(((byte)(193)))), ((int)(((byte)(210)))), ((int)(((byte)(238)))));\r\n            this.shengComboSelector1.SelectedDescriptionColor = System.Drawing.Color.DarkGray;\r\n            this.shengComboSelector1.SelectedTextColor = System.Drawing.Color.Black;\r\n            this.shengComboSelector1.SelectedValue = null;\r\n            this.shengComboSelector1.ShowDescription = true;\r\n            this.shengComboSelector1.Size = new System.Drawing.Size(321, 42);\r\n            this.shengComboSelector1.TabIndex = 0;\r\n            this.shengComboSelector1.TextColor = System.Drawing.Color.Black;\r\n            this.shengComboSelector1.Title = null;\r\n            this.shengComboSelector1.ValueMember = null;\r\n            // \r\n            // label3\r\n            // \r\n            this.label3.Location = new System.Drawing.Point(29, 200);\r\n            this.label3.Name = \"label3\";\r\n            this.label3.Size = new System.Drawing.Size(582, 30);\r\n            this.label3.TabIndex = 8;\r\n            this.label3.Text = \"在绘制过程中所需的配色方案，都已独立定义，你也可以直接修改配色方案来定制外观。\";\r\n            // \r\n            // label2\r\n            // \r\n            this.label2.Location = new System.Drawing.Point(29, 168);\r\n            this.label2.Name = \"label2\";\r\n            this.label2.Size = new System.Drawing.Size(647, 18);\r\n            this.label2.TabIndex = 7;\r\n            this.label2.Text = \"你可以修改源代码，绘制想要的任何外观。\";\r\n            // \r\n            // label1\r\n            // \r\n            this.label1.AutoSize = true;\r\n            this.label1.Location = new System.Drawing.Point(29, 136);\r\n            this.label1.Name = \"label1\";\r\n            this.label1.Size = new System.Drawing.Size(599, 12);\r\n            this.label1.TabIndex = 6;\r\n            this.label1.Text = \"ShengComboSelector 是一个下拉选择框控件，这是一个重头实现的控件，并非基原生下拉框控件的继承和扩展。\";\r\n            // \r\n            // pictureBox2\r\n            // \r\n            this.pictureBox2.Image = global::Sheng.Winform.Controls.Demo.Resource1._5;\r\n            this.pictureBox2.Location = new System.Drawing.Point(660, 38);\r\n            this.pictureBox2.Name = \"pictureBox2\";\r\n            this.pictureBox2.Size = new System.Drawing.Size(304, 648);\r\n            this.pictureBox2.TabIndex = 10;\r\n            this.pictureBox2.TabStop = false;\r\n            // \r\n            // pictureBox1\r\n            // \r\n            this.pictureBox1.Image = global::Sheng.Winform.Controls.Demo.Resource1._6;\r\n            this.pictureBox1.Location = new System.Drawing.Point(31, 254);\r\n            this.pictureBox1.Name = \"pictureBox1\";\r\n            this.pictureBox1.Size = new System.Drawing.Size(359, 136);\r\n            this.pictureBox1.TabIndex = 9;\r\n            this.pictureBox1.TabStop = false;\r\n            // \r\n            // shengComboSelector2\r\n            // \r\n            this.shengComboSelector2.AllowEmpty = true;\r\n            this.shengComboSelector2.BackColor = System.Drawing.SystemColors.Window;\r\n            this.shengComboSelector2.BorderColor = System.Drawing.SystemColors.ControlDark;\r\n            this.shengComboSelector2.CustomValidate = null;\r\n            this.shengComboSelector2.DataSource = null;\r\n            this.shengComboSelector2.DataSourceType = null;\r\n            this.shengComboSelector2.DescriptionColor = System.Drawing.Color.DarkGray;\r\n            this.shengComboSelector2.DescriptionMember = null;\r\n            this.shengComboSelector2.DisplayMember = null;\r\n            this.shengComboSelector2.FocusBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(232)))), ((int)(((byte)(246)))));\r\n            this.shengComboSelector2.FocusBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(152)))), ((int)(((byte)(180)))), ((int)(((byte)(226)))));\r\n            this.shengComboSelector2.FocusDescriptionColor = System.Drawing.Color.DarkGray;\r\n            this.shengComboSelector2.FocusTextColor = System.Drawing.Color.Black;\r\n            this.shengComboSelector2.HighLight = true;\r\n            this.shengComboSelector2.ItemBackgroundColor = System.Drawing.Color.White;\r\n            this.shengComboSelector2.ItemBorderColor = System.Drawing.Color.White;\r\n            this.shengComboSelector2.ItemDescriptionColor = System.Drawing.Color.DarkGray;\r\n            this.shengComboSelector2.ItemFocusBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(152)))), ((int)(((byte)(180)))), ((int)(((byte)(226)))));\r\n            this.shengComboSelector2.ItemFocusColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(232)))), ((int)(((byte)(246)))));\r\n            this.shengComboSelector2.ItemFocusDescriptionColor = System.Drawing.Color.DarkGray;\r\n            this.shengComboSelector2.ItemFocusTextColor = System.Drawing.Color.Black;\r\n            this.shengComboSelector2.ItemSelectedBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(49)))), ((int)(((byte)(106)))), ((int)(((byte)(197)))));\r\n            this.shengComboSelector2.ItemSelectedColor = System.Drawing.Color.FromArgb(((int)(((byte)(193)))), ((int)(((byte)(210)))), ((int)(((byte)(238)))));\r\n            this.shengComboSelector2.ItemSelectedDescriptionColor = System.Drawing.Color.DarkGray;\r\n            this.shengComboSelector2.ItemSelectedTextColor = System.Drawing.Color.Black;\r\n            this.shengComboSelector2.ItemTextColor = System.Drawing.Color.Black;\r\n            this.shengComboSelector2.Location = new System.Drawing.Point(31, 38);\r\n            this.shengComboSelector2.MaxItem = 8;\r\n            this.shengComboSelector2.Name = \"shengComboSelector2\";\r\n            this.shengComboSelector2.SelectedBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(49)))), ((int)(((byte)(106)))), ((int)(((byte)(197)))));\r\n            this.shengComboSelector2.SelectedColor = System.Drawing.Color.FromArgb(((int)(((byte)(193)))), ((int)(((byte)(210)))), ((int)(((byte)(238)))));\r\n            this.shengComboSelector2.SelectedDescriptionColor = System.Drawing.Color.DarkGray;\r\n            this.shengComboSelector2.SelectedTextColor = System.Drawing.Color.Black;\r\n            this.shengComboSelector2.SelectedValue = null;\r\n            this.shengComboSelector2.ShowDescription = true;\r\n            this.shengComboSelector2.Size = new System.Drawing.Size(253, 27);\r\n            this.shengComboSelector2.TabIndex = 11;\r\n            this.shengComboSelector2.TextColor = System.Drawing.Color.Black;\r\n            this.shengComboSelector2.Title = null;\r\n            this.shengComboSelector2.ValueMember = null;\r\n            // \r\n            // label4\r\n            // \r\n            this.label4.Location = new System.Drawing.Point(29, 425);\r\n            this.label4.Name = \"label4\";\r\n            this.label4.Size = new System.Drawing.Size(549, 61);\r\n            this.label4.TabIndex = 12;\r\n            this.label4.Text = \"一般情况下，推荐使用 ShengComboSelector2，因为 ShengComboSelector2 是直接基于 Control 实现的，具有更好的性能表现\" +\r\n    \"，你也可以修改 ShengComboSelector 的源代码使其直接从 Control 实现而不是 UserControl。\";\r\n            // \r\n            // FormShengComboSelector\r\n            // \r\n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);\r\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\r\n            this.ClientSize = new System.Drawing.Size(989, 704);\r\n            this.Controls.Add(this.label4);\r\n            this.Controls.Add(this.shengComboSelector2);\r\n            this.Controls.Add(this.pictureBox2);\r\n            this.Controls.Add(this.pictureBox1);\r\n            this.Controls.Add(this.label3);\r\n            this.Controls.Add(this.label2);\r\n            this.Controls.Add(this.label1);\r\n            this.Controls.Add(this.shengComboSelector1);\r\n            this.Name = \"FormShengComboSelector\";\r\n            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;\r\n            this.Text = \"FormShengComboSelector\";\r\n            this.Load += new System.EventHandler(this.FormShengComboSelector_Load);\r\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).EndInit();\r\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();\r\n            this.ResumeLayout(false);\r\n            this.PerformLayout();\r\n\r\n        }\r\n\r\n        #endregion\r\n\r\n        private ShengComboSelector shengComboSelector1;\r\n        private System.Windows.Forms.Label label3;\r\n        private System.Windows.Forms.Label label2;\r\n        private System.Windows.Forms.Label label1;\r\n        private System.Windows.Forms.PictureBox pictureBox1;\r\n        private System.Windows.Forms.PictureBox pictureBox2;\r\n        private ShengComboSelector shengComboSelector2;\r\n        private System.Windows.Forms.Label label4;\r\n    }\r\n}"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/FormShengComboSelector.cs",
    "content": "﻿using System;\r\nusing System.Collections.Generic;\r\nusing System.ComponentModel;\r\nusing System.Data;\r\nusing System.Drawing;\r\nusing System.Linq;\r\nusing System.Text;\r\nusing System.Windows.Forms;\r\n\r\nnamespace Sheng.Winform.Controls.Demo\r\n{\r\n    public partial class FormShengComboSelector : Form\r\n    {\r\n        public FormShengComboSelector()\r\n        {\r\n            InitializeComponent();\r\n        }\r\n\r\n        private void FormShengComboSelector_Load(object sender, EventArgs e)\r\n        {\r\n            shengComboSelector1.ItemDescriptionColor = Color.Blue;\r\n            shengComboSelector1.ItemFocusColor = Color.LightYellow;\r\n            shengComboSelector1.DisplayMember = \"Name\";\r\n            shengComboSelector1.DescriptionMember = \"Description\";\r\n            shengComboSelector1.DataSource = TestListViewItem.GetTestData();\r\n\r\n            shengComboSelector2.DisplayMember = \"Name\";\r\n            shengComboSelector2.ShowDescription = false;\r\n            shengComboSelector2.DataSource = TestListViewItem.GetTestData();\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/FormShengComboSelector.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<root>\r\n  <!-- \r\n    Microsoft ResX Schema \r\n    \r\n    Version 2.0\r\n    \r\n    The primary goals of this format is to allow a simple XML format \r\n    that is mostly human readable. The generation and parsing of the \r\n    various data types are done through the TypeConverter classes \r\n    associated with the data types.\r\n    \r\n    Example:\r\n    \r\n    ... ado.net/XML headers & schema ...\r\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\r\n    <resheader name=\"version\">2.0</resheader>\r\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\r\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\r\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\r\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\r\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\r\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\r\n    </data>\r\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\r\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\r\n        <comment>This is a comment</comment>\r\n    </data>\r\n                \r\n    There are any number of \"resheader\" rows that contain simple \r\n    name/value pairs.\r\n    \r\n    Each data row contains a name, and value. The row also contains a \r\n    type or mimetype. Type corresponds to a .NET class that support \r\n    text/value conversion through the TypeConverter architecture. \r\n    Classes that don't support this are serialized and stored with the \r\n    mimetype set.\r\n    \r\n    The mimetype is used for serialized objects, and tells the \r\n    ResXResourceReader how to depersist the object. This is currently not \r\n    extensible. For a given mimetype the value must be set accordingly:\r\n    \r\n    Note - application/x-microsoft.net.object.binary.base64 is the format \r\n    that the ResXResourceWriter will generate, however the reader can \r\n    read any of the formats listed below.\r\n    \r\n    mimetype: application/x-microsoft.net.object.binary.base64\r\n    value   : The object must be serialized with \r\n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\r\n            : and then encoded with base64 encoding.\r\n    \r\n    mimetype: application/x-microsoft.net.object.soap.base64\r\n    value   : The object must be serialized with \r\n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\r\n            : and then encoded with base64 encoding.\r\n\r\n    mimetype: application/x-microsoft.net.object.bytearray.base64\r\n    value   : The object must be serialized into a byte array \r\n            : using a System.ComponentModel.TypeConverter\r\n            : and then encoded with base64 encoding.\r\n    -->\r\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\r\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\r\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\r\n      <xsd:complexType>\r\n        <xsd:choice maxOccurs=\"unbounded\">\r\n          <xsd:element name=\"metadata\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\r\n              <xsd:attribute ref=\"xml:space\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"assembly\">\r\n            <xsd:complexType>\r\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"data\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\r\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\r\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\r\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\r\n              <xsd:attribute ref=\"xml:space\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"resheader\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n        </xsd:choice>\r\n      </xsd:complexType>\r\n    </xsd:element>\r\n  </xsd:schema>\r\n  <resheader name=\"resmimetype\">\r\n    <value>text/microsoft-resx</value>\r\n  </resheader>\r\n  <resheader name=\"version\">\r\n    <value>2.0</value>\r\n  </resheader>\r\n  <resheader name=\"reader\">\r\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r\n  </resheader>\r\n  <resheader name=\"writer\">\r\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r\n  </resheader>\r\n</root>"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/FormShengComboSelector2.Designer.cs",
    "content": "﻿namespace Sheng.Winform.Controls.Demo\r\n{\r\n    partial class FormShengComboSelector2\r\n    {\r\n        /// <summary>\r\n        /// Required designer variable.\r\n        /// </summary>\r\n        private System.ComponentModel.IContainer components = null;\r\n\r\n        /// <summary>\r\n        /// Clean up any resources being used.\r\n        /// </summary>\r\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\r\n        protected override void Dispose(bool disposing)\r\n        {\r\n            if (disposing && (components != null))\r\n            {\r\n                components.Dispose();\r\n            }\r\n            base.Dispose(disposing);\r\n        }\r\n\r\n        #region Windows Form Designer generated code\r\n\r\n        /// <summary>\r\n        /// Required method for Designer support - do not modify\r\n        /// the contents of this method with the code editor.\r\n        /// </summary>\r\n        private void InitializeComponent()\r\n        {\r\n            Sheng.Winform.Controls.ShengComboSelectorTheme shengComboSelectorTheme1 = new Sheng.Winform.Controls.ShengComboSelectorTheme();\r\n            Sheng.Winform.Controls.ShengComboSelectorTheme shengComboSelectorTheme2 = new Sheng.Winform.Controls.ShengComboSelectorTheme();\r\n            this.shengComboSelector21 = new Sheng.Winform.Controls.ShengComboSelector2();\r\n            this.label3 = new System.Windows.Forms.Label();\r\n            this.label2 = new System.Windows.Forms.Label();\r\n            this.label1 = new System.Windows.Forms.Label();\r\n            this.pictureBox2 = new System.Windows.Forms.PictureBox();\r\n            this.pictureBox1 = new System.Windows.Forms.PictureBox();\r\n            this.label4 = new System.Windows.Forms.Label();\r\n            this.shengComboSelector22 = new Sheng.Winform.Controls.ShengComboSelector2();\r\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).BeginInit();\r\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();\r\n            this.SuspendLayout();\r\n            // \r\n            // shengComboSelector21\r\n            // \r\n            this.shengComboSelector21.AllowEmpty = true;\r\n            this.shengComboSelector21.BackColor = System.Drawing.Color.White;\r\n            this.shengComboSelector21.CustomValidate = null;\r\n            this.shengComboSelector21.DescriptionMember = null;\r\n            this.shengComboSelector21.DisplayMember = null;\r\n            this.shengComboSelector21.HighLight = true;\r\n            this.shengComboSelector21.LayoutMode = Sheng.Winform.Controls.ShengListViewLayoutMode.Descriptive;\r\n            this.shengComboSelector21.Location = new System.Drawing.Point(44, 40);\r\n            this.shengComboSelector21.MaxItem = 5;\r\n            this.shengComboSelector21.Name = \"shengComboSelector21\";\r\n            this.shengComboSelector21.Padding = new System.Windows.Forms.Padding(5);\r\n            this.shengComboSelector21.ShowDescription = true;\r\n            this.shengComboSelector21.Size = new System.Drawing.Size(311, 42);\r\n            this.shengComboSelector21.TabIndex = 0;\r\n            this.shengComboSelector21.Text = \"shengComboSelector21\";\r\n            shengComboSelectorTheme1.ArrowColorEnd = System.Drawing.Color.LightGray;\r\n            shengComboSelectorTheme1.ArrowColorStart = System.Drawing.Color.Gray;\r\n            shengComboSelectorTheme1.BackColor = System.Drawing.Color.Gray;\r\n            shengComboSelectorTheme1.BackgroundColor = System.Drawing.Color.White;\r\n            shengComboSelectorTheme1.BorderColor = System.Drawing.Color.LightGray;\r\n            shengComboSelectorTheme1.DescriptionTextColor = System.Drawing.SystemColors.GrayText;\r\n            shengComboSelectorTheme1.HoveredBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(254)))), ((int)(((byte)(228)))), ((int)(((byte)(134)))));\r\n            shengComboSelectorTheme1.HoveredBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(242)))), ((int)(((byte)(202)))), ((int)(((byte)(88)))));\r\n            shengComboSelectorTheme1.HoveredDescriptionColor = System.Drawing.SystemColors.GrayText;\r\n            shengComboSelectorTheme1.HoveredTextColor = System.Drawing.SystemColors.WindowText;\r\n            shengComboSelectorTheme1.SelectedBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(216)))), ((int)(((byte)(107)))));\r\n            shengComboSelectorTheme1.SelectedBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(194)))), ((int)(((byte)(138)))), ((int)(((byte)(48)))));\r\n            shengComboSelectorTheme1.SelectedDescriptionTextColor = System.Drawing.SystemColors.GrayText;\r\n            shengComboSelectorTheme1.SelectedTextColor = System.Drawing.SystemColors.WindowText;\r\n            shengComboSelectorTheme1.TextColor = System.Drawing.SystemColors.WindowText;\r\n            this.shengComboSelector21.Theme = shengComboSelectorTheme1;\r\n            this.shengComboSelector21.Title = null;\r\n            // \r\n            // label3\r\n            // \r\n            this.label3.Location = new System.Drawing.Point(42, 234);\r\n            this.label3.Name = \"label3\";\r\n            this.label3.Size = new System.Drawing.Size(582, 30);\r\n            this.label3.TabIndex = 11;\r\n            this.label3.Text = \"在绘制过程中所需的配色方案，定义在 ShengComboSelectorTheme 中，你可以直接修改配色方案来或定制自己的主题配色方案。\";\r\n            // \r\n            // label2\r\n            // \r\n            this.label2.Location = new System.Drawing.Point(42, 186);\r\n            this.label2.Name = \"label2\";\r\n            this.label2.Size = new System.Drawing.Size(647, 37);\r\n            this.label2.TabIndex = 10;\r\n            this.label2.Text = \"ShengComboSelector2 比 ShengComboSelector 具有更好的性能，因为它是基于 Control 实现的，而 ShengComboS\" +\r\n    \"elector 是基于 UserControl 实现的。\";\r\n            // \r\n            // label1\r\n            // \r\n            this.label1.AutoSize = true;\r\n            this.label1.Location = new System.Drawing.Point(42, 122);\r\n            this.label1.Name = \"label1\";\r\n            this.label1.Size = new System.Drawing.Size(605, 12);\r\n            this.label1.TabIndex = 9;\r\n            this.label1.Text = \"ShengComboSelector2 是一个下拉选择框控件，这是一个重头实现的控件，并非基原生下拉框控件的继承和扩展。\";\r\n            // \r\n            // pictureBox2\r\n            // \r\n            this.pictureBox2.Image = global::Sheng.Winform.Controls.Demo.Resource1._8;\r\n            this.pictureBox2.Location = new System.Drawing.Point(671, 31);\r\n            this.pictureBox2.Name = \"pictureBox2\";\r\n            this.pictureBox2.Size = new System.Drawing.Size(340, 511);\r\n            this.pictureBox2.TabIndex = 13;\r\n            this.pictureBox2.TabStop = false;\r\n            // \r\n            // pictureBox1\r\n            // \r\n            this.pictureBox1.Image = global::Sheng.Winform.Controls.Demo.Resource1._7;\r\n            this.pictureBox1.Location = new System.Drawing.Point(44, 301);\r\n            this.pictureBox1.Name = \"pictureBox1\";\r\n            this.pictureBox1.Size = new System.Drawing.Size(359, 103);\r\n            this.pictureBox1.TabIndex = 12;\r\n            this.pictureBox1.TabStop = false;\r\n            // \r\n            // label4\r\n            // \r\n            this.label4.Location = new System.Drawing.Point(42, 152);\r\n            this.label4.Name = \"label4\";\r\n            this.label4.Size = new System.Drawing.Size(582, 18);\r\n            this.label4.TabIndex = 14;\r\n            this.label4.Text = \"你可以修改源代码，绘制想要的任何外观。\";\r\n            // \r\n            // shengComboSelector22\r\n            // \r\n            this.shengComboSelector22.AllowEmpty = true;\r\n            this.shengComboSelector22.BackColor = System.Drawing.Color.White;\r\n            this.shengComboSelector22.CustomValidate = null;\r\n            this.shengComboSelector22.DescriptionMember = null;\r\n            this.shengComboSelector22.DisplayMember = null;\r\n            this.shengComboSelector22.HighLight = true;\r\n            this.shengComboSelector22.LayoutMode = Sheng.Winform.Controls.ShengListViewLayoutMode.Descriptive;\r\n            this.shengComboSelector22.Location = new System.Drawing.Point(390, 40);\r\n            this.shengComboSelector22.MaxItem = 5;\r\n            this.shengComboSelector22.Name = \"shengComboSelector22\";\r\n            this.shengComboSelector22.Padding = new System.Windows.Forms.Padding(5);\r\n            this.shengComboSelector22.ShowDescription = true;\r\n            this.shengComboSelector22.Size = new System.Drawing.Size(257, 42);\r\n            this.shengComboSelector22.TabIndex = 15;\r\n            this.shengComboSelector22.Text = \"shengComboSelector22\";\r\n            shengComboSelectorTheme2.ArrowColorEnd = System.Drawing.Color.LightGray;\r\n            shengComboSelectorTheme2.ArrowColorStart = System.Drawing.Color.Gray;\r\n            shengComboSelectorTheme2.BackColor = System.Drawing.Color.Gray;\r\n            shengComboSelectorTheme2.BackgroundColor = System.Drawing.Color.White;\r\n            shengComboSelectorTheme2.BorderColor = System.Drawing.Color.LightGray;\r\n            shengComboSelectorTheme2.DescriptionTextColor = System.Drawing.SystemColors.GrayText;\r\n            shengComboSelectorTheme2.HoveredBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(254)))), ((int)(((byte)(228)))), ((int)(((byte)(134)))));\r\n            shengComboSelectorTheme2.HoveredBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(242)))), ((int)(((byte)(202)))), ((int)(((byte)(88)))));\r\n            shengComboSelectorTheme2.HoveredDescriptionColor = System.Drawing.SystemColors.GrayText;\r\n            shengComboSelectorTheme2.HoveredTextColor = System.Drawing.SystemColors.WindowText;\r\n            shengComboSelectorTheme2.SelectedBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(216)))), ((int)(((byte)(107)))));\r\n            shengComboSelectorTheme2.SelectedBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(194)))), ((int)(((byte)(138)))), ((int)(((byte)(48)))));\r\n            shengComboSelectorTheme2.SelectedDescriptionTextColor = System.Drawing.SystemColors.GrayText;\r\n            shengComboSelectorTheme2.SelectedTextColor = System.Drawing.SystemColors.WindowText;\r\n            shengComboSelectorTheme2.TextColor = System.Drawing.SystemColors.WindowText;\r\n            this.shengComboSelector22.Theme = shengComboSelectorTheme2;\r\n            this.shengComboSelector22.Title = null;\r\n            // \r\n            // FormShengComboSelector2\r\n            // \r\n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);\r\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\r\n            this.ClientSize = new System.Drawing.Size(1055, 578);\r\n            this.Controls.Add(this.shengComboSelector22);\r\n            this.Controls.Add(this.label4);\r\n            this.Controls.Add(this.pictureBox2);\r\n            this.Controls.Add(this.pictureBox1);\r\n            this.Controls.Add(this.label3);\r\n            this.Controls.Add(this.label2);\r\n            this.Controls.Add(this.label1);\r\n            this.Controls.Add(this.shengComboSelector21);\r\n            this.Name = \"FormShengComboSelector2\";\r\n            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;\r\n            this.Text = \"FormShengComboSelector2\";\r\n            this.Load += new System.EventHandler(this.FormShengComboSelector2_Load);\r\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).EndInit();\r\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();\r\n            this.ResumeLayout(false);\r\n            this.PerformLayout();\r\n\r\n        }\r\n\r\n        #endregion\r\n\r\n        private ShengComboSelector2 shengComboSelector21;\r\n        private System.Windows.Forms.Label label3;\r\n        private System.Windows.Forms.Label label2;\r\n        private System.Windows.Forms.Label label1;\r\n        private System.Windows.Forms.PictureBox pictureBox1;\r\n        private System.Windows.Forms.PictureBox pictureBox2;\r\n        private System.Windows.Forms.Label label4;\r\n        private ShengComboSelector2 shengComboSelector22;\r\n    }\r\n}"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/FormShengComboSelector2.cs",
    "content": "﻿using System;\r\nusing System.Collections.Generic;\r\nusing System.ComponentModel;\r\nusing System.Data;\r\nusing System.Drawing;\r\nusing System.Linq;\r\nusing System.Text;\r\nusing System.Windows.Forms;\r\n\r\nnamespace Sheng.Winform.Controls.Demo\r\n{\r\n    public partial class FormShengComboSelector2 : Form\r\n    {\r\n        public FormShengComboSelector2()\r\n        {\r\n            InitializeComponent();\r\n        }\r\n\r\n        private void FormShengComboSelector2_Load(object sender, EventArgs e)\r\n        {\r\n            shengComboSelector21.DisplayMember = \"Name\";\r\n            shengComboSelector21.DescriptionMember = \"Description\";\r\n            shengComboSelector21.DataBind(TestListViewItem.GetTestData());\r\n\r\n            shengComboSelector22.DisplayMember = \"Name\";\r\n            shengComboSelector22.ShowDescription = false;\r\n            shengComboSelector22.DataBind(TestListViewItem.GetTestData());\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/FormShengComboSelector2.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<root>\r\n  <!-- \r\n    Microsoft ResX Schema \r\n    \r\n    Version 2.0\r\n    \r\n    The primary goals of this format is to allow a simple XML format \r\n    that is mostly human readable. The generation and parsing of the \r\n    various data types are done through the TypeConverter classes \r\n    associated with the data types.\r\n    \r\n    Example:\r\n    \r\n    ... ado.net/XML headers & schema ...\r\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\r\n    <resheader name=\"version\">2.0</resheader>\r\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\r\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\r\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\r\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\r\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\r\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\r\n    </data>\r\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\r\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\r\n        <comment>This is a comment</comment>\r\n    </data>\r\n                \r\n    There are any number of \"resheader\" rows that contain simple \r\n    name/value pairs.\r\n    \r\n    Each data row contains a name, and value. The row also contains a \r\n    type or mimetype. Type corresponds to a .NET class that support \r\n    text/value conversion through the TypeConverter architecture. \r\n    Classes that don't support this are serialized and stored with the \r\n    mimetype set.\r\n    \r\n    The mimetype is used for serialized objects, and tells the \r\n    ResXResourceReader how to depersist the object. This is currently not \r\n    extensible. For a given mimetype the value must be set accordingly:\r\n    \r\n    Note - application/x-microsoft.net.object.binary.base64 is the format \r\n    that the ResXResourceWriter will generate, however the reader can \r\n    read any of the formats listed below.\r\n    \r\n    mimetype: application/x-microsoft.net.object.binary.base64\r\n    value   : The object must be serialized with \r\n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\r\n            : and then encoded with base64 encoding.\r\n    \r\n    mimetype: application/x-microsoft.net.object.soap.base64\r\n    value   : The object must be serialized with \r\n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\r\n            : and then encoded with base64 encoding.\r\n\r\n    mimetype: application/x-microsoft.net.object.bytearray.base64\r\n    value   : The object must be serialized into a byte array \r\n            : using a System.ComponentModel.TypeConverter\r\n            : and then encoded with base64 encoding.\r\n    -->\r\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\r\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\r\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\r\n      <xsd:complexType>\r\n        <xsd:choice maxOccurs=\"unbounded\">\r\n          <xsd:element name=\"metadata\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\r\n              <xsd:attribute ref=\"xml:space\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"assembly\">\r\n            <xsd:complexType>\r\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"data\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\r\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\r\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\r\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\r\n              <xsd:attribute ref=\"xml:space\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"resheader\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n        </xsd:choice>\r\n      </xsd:complexType>\r\n    </xsd:element>\r\n  </xsd:schema>\r\n  <resheader name=\"resmimetype\">\r\n    <value>text/microsoft-resx</value>\r\n  </resheader>\r\n  <resheader name=\"version\">\r\n    <value>2.0</value>\r\n  </resheader>\r\n  <resheader name=\"reader\">\r\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r\n  </resheader>\r\n  <resheader name=\"writer\">\r\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r\n  </resheader>\r\n</root>"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/FormShengDataGridView.Designer.cs",
    "content": "﻿namespace Sheng.Winform.Controls.Demo\r\n{\r\n    partial class FormShengDataGridView\r\n    {\r\n        /// <summary>\r\n        /// Required designer variable.\r\n        /// </summary>\r\n        private System.ComponentModel.IContainer components = null;\r\n\r\n        /// <summary>\r\n        /// Clean up any resources being used.\r\n        /// </summary>\r\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\r\n        protected override void Dispose(bool disposing)\r\n        {\r\n            if (disposing && (components != null))\r\n            {\r\n                components.Dispose();\r\n            }\r\n            base.Dispose(disposing);\r\n        }\r\n\r\n        #region Windows Form Designer generated code\r\n\r\n        /// <summary>\r\n        /// Required method for Designer support - do not modify\r\n        /// the contents of this method with the code editor.\r\n        /// </summary>\r\n        private void InitializeComponent()\r\n        {\r\n            this.shengDataGridView1 = new Sheng.Winform.Controls.ShengDataGridView();\r\n            this.label1 = new System.Windows.Forms.Label();\r\n            this.pictureBox2 = new System.Windows.Forms.PictureBox();\r\n            this.pictureBox1 = new System.Windows.Forms.PictureBox();\r\n            this.label3 = new System.Windows.Forms.Label();\r\n            this.label4 = new System.Windows.Forms.Label();\r\n            ((System.ComponentModel.ISupportInitialize)(this.shengDataGridView1)).BeginInit();\r\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).BeginInit();\r\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();\r\n            this.SuspendLayout();\r\n            // \r\n            // shengDataGridView1\r\n            // \r\n            this.shengDataGridView1.AllowUserToAddRows = false;\r\n            this.shengDataGridView1.AllowUserToDeleteRows = false;\r\n            this.shengDataGridView1.AllowUserToResizeRows = false;\r\n            this.shengDataGridView1.BackgroundColor = System.Drawing.Color.White;\r\n            this.shengDataGridView1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;\r\n            this.shengDataGridView1.CellBorderStyle = System.Windows.Forms.DataGridViewCellBorderStyle.None;\r\n            this.shengDataGridView1.ColumnHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.None;\r\n            this.shengDataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;\r\n            this.shengDataGridView1.Location = new System.Drawing.Point(32, 26);\r\n            this.shengDataGridView1.Name = \"shengDataGridView1\";\r\n            this.shengDataGridView1.ReadOnly = true;\r\n            this.shengDataGridView1.RowHeadersVisible = false;\r\n            this.shengDataGridView1.RowHeadersWidthSizeMode = System.Windows.Forms.DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders;\r\n            this.shengDataGridView1.RowTemplate.Height = 23;\r\n            this.shengDataGridView1.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;\r\n            this.shengDataGridView1.Size = new System.Drawing.Size(405, 389);\r\n            this.shengDataGridView1.TabIndex = 0;\r\n            this.shengDataGridView1.WaterText = \"\";\r\n            // \r\n            // label1\r\n            // \r\n            this.label1.AutoSize = true;\r\n            this.label1.Location = new System.Drawing.Point(496, 36);\r\n            this.label1.Name = \"label1\";\r\n            this.label1.Size = new System.Drawing.Size(563, 12);\r\n            this.label1.TabIndex = 1;\r\n            this.label1.Text = \"ShengDataGridView 重绘了整个 DataGridView 的外观。包括 Checkbox 列和 Image 列，使其更加美观。\";\r\n            // \r\n            // pictureBox2\r\n            // \r\n            this.pictureBox2.Image = global::Sheng.Winform.Controls.Demo.Resource1._4;\r\n            this.pictureBox2.Location = new System.Drawing.Point(848, 173);\r\n            this.pictureBox2.Name = \"pictureBox2\";\r\n            this.pictureBox2.Size = new System.Drawing.Size(346, 399);\r\n            this.pictureBox2.TabIndex = 4;\r\n            this.pictureBox2.TabStop = false;\r\n            // \r\n            // pictureBox1\r\n            // \r\n            this.pictureBox1.Image = global::Sheng.Winform.Controls.Demo.Resource1._1;\r\n            this.pictureBox1.Location = new System.Drawing.Point(483, 173);\r\n            this.pictureBox1.Name = \"pictureBox1\";\r\n            this.pictureBox1.Size = new System.Drawing.Size(359, 217);\r\n            this.pictureBox1.TabIndex = 2;\r\n            this.pictureBox1.TabStop = false;\r\n            // \r\n            // label3\r\n            // \r\n            this.label3.Location = new System.Drawing.Point(496, 97);\r\n            this.label3.Name = \"label3\";\r\n            this.label3.Size = new System.Drawing.Size(647, 21);\r\n            this.label3.TabIndex = 5;\r\n            this.label3.Text = \"也可以直接借助 ShengDataGridViewRendererTheme 在既有外观的基础上定制主题配色等。\";\r\n            // \r\n            // label4\r\n            // \r\n            this.label4.AutoSize = true;\r\n            this.label4.Location = new System.Drawing.Point(496, 66);\r\n            this.label4.Name = \"label4\";\r\n            this.label4.Size = new System.Drawing.Size(707, 12);\r\n            this.label4.TabIndex = 6;\r\n            this.label4.Text = \"ShengDataGridView 的绘图逻辑实现在渲染器 ShengDataGridViewRender 中，你可以修改或重新实现新的渲染器以定制控件的外观。\";\r\n            // \r\n            // FormShengDataGridView\r\n            // \r\n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);\r\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\r\n            this.ClientSize = new System.Drawing.Size(1231, 617);\r\n            this.Controls.Add(this.label4);\r\n            this.Controls.Add(this.label3);\r\n            this.Controls.Add(this.pictureBox2);\r\n            this.Controls.Add(this.pictureBox1);\r\n            this.Controls.Add(this.label1);\r\n            this.Controls.Add(this.shengDataGridView1);\r\n            this.Name = \"FormShengDataGridView\";\r\n            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;\r\n            this.Text = \"FormShengDataGridView\";\r\n            this.Load += new System.EventHandler(this.FormShengDataGridView_Load);\r\n            ((System.ComponentModel.ISupportInitialize)(this.shengDataGridView1)).EndInit();\r\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).EndInit();\r\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();\r\n            this.ResumeLayout(false);\r\n            this.PerformLayout();\r\n\r\n        }\r\n\r\n        #endregion\r\n\r\n        private ShengDataGridView shengDataGridView1;\r\n        private System.Windows.Forms.Label label1;\r\n        private System.Windows.Forms.PictureBox pictureBox1;\r\n        private System.Windows.Forms.PictureBox pictureBox2;\r\n        private System.Windows.Forms.Label label3;\r\n        private System.Windows.Forms.Label label4;\r\n    }\r\n}"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/FormShengDataGridView.cs",
    "content": "﻿using System;\r\nusing System.Collections.Generic;\r\nusing System.ComponentModel;\r\nusing System.Data;\r\nusing System.Drawing;\r\nusing System.Linq;\r\nusing System.Text;\r\nusing System.Windows.Forms;\r\n\r\nnamespace Sheng.Winform.Controls.Demo\r\n{\r\n    public partial class FormShengDataGridView : Form\r\n    {\r\n\r\n\r\n        public FormShengDataGridView()\r\n        {\r\n            InitializeComponent();\r\n        }\r\n\r\n        private void FormShengDataGridView_Load(object sender, EventArgs e)\r\n        {\r\n            DataTable dt = new DataTable();\r\n            dt.Columns.Add(\"Name\");\r\n            dt.Columns.Add(\"Age\");\r\n            dt.Columns.Add(\"Class\");\r\n\r\n            DataRow dr = dt.NewRow();\r\n            dr[\"Name\"] = \"张三\";\r\n            dr[\"Age\"] = \"18\";\r\n            dr[\"Class\"] = \"A\";\r\n            dt.Rows.Add(dr);\r\n\r\n            dr = dt.NewRow();\r\n            dr[\"Name\"] = \"李四\";\r\n            dr[\"Age\"] = \"21\";\r\n            dr[\"Class\"] = \"B\";\r\n            dt.Rows.Add(dr);\r\n\r\n            this.shengDataGridView1.DataSource = dt;\r\n\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/FormShengDataGridView.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<root>\r\n  <!-- \r\n    Microsoft ResX Schema \r\n    \r\n    Version 2.0\r\n    \r\n    The primary goals of this format is to allow a simple XML format \r\n    that is mostly human readable. The generation and parsing of the \r\n    various data types are done through the TypeConverter classes \r\n    associated with the data types.\r\n    \r\n    Example:\r\n    \r\n    ... ado.net/XML headers & schema ...\r\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\r\n    <resheader name=\"version\">2.0</resheader>\r\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\r\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\r\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\r\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\r\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\r\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\r\n    </data>\r\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\r\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\r\n        <comment>This is a comment</comment>\r\n    </data>\r\n                \r\n    There are any number of \"resheader\" rows that contain simple \r\n    name/value pairs.\r\n    \r\n    Each data row contains a name, and value. The row also contains a \r\n    type or mimetype. Type corresponds to a .NET class that support \r\n    text/value conversion through the TypeConverter architecture. \r\n    Classes that don't support this are serialized and stored with the \r\n    mimetype set.\r\n    \r\n    The mimetype is used for serialized objects, and tells the \r\n    ResXResourceReader how to depersist the object. This is currently not \r\n    extensible. For a given mimetype the value must be set accordingly:\r\n    \r\n    Note - application/x-microsoft.net.object.binary.base64 is the format \r\n    that the ResXResourceWriter will generate, however the reader can \r\n    read any of the formats listed below.\r\n    \r\n    mimetype: application/x-microsoft.net.object.binary.base64\r\n    value   : The object must be serialized with \r\n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\r\n            : and then encoded with base64 encoding.\r\n    \r\n    mimetype: application/x-microsoft.net.object.soap.base64\r\n    value   : The object must be serialized with \r\n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\r\n            : and then encoded with base64 encoding.\r\n\r\n    mimetype: application/x-microsoft.net.object.bytearray.base64\r\n    value   : The object must be serialized into a byte array \r\n            : using a System.ComponentModel.TypeConverter\r\n            : and then encoded with base64 encoding.\r\n    -->\r\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\r\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\r\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\r\n      <xsd:complexType>\r\n        <xsd:choice maxOccurs=\"unbounded\">\r\n          <xsd:element name=\"metadata\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\r\n              <xsd:attribute ref=\"xml:space\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"assembly\">\r\n            <xsd:complexType>\r\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"data\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\r\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\r\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\r\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\r\n              <xsd:attribute ref=\"xml:space\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"resheader\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n        </xsd:choice>\r\n      </xsd:complexType>\r\n    </xsd:element>\r\n  </xsd:schema>\r\n  <resheader name=\"resmimetype\">\r\n    <value>text/microsoft-resx</value>\r\n  </resheader>\r\n  <resheader name=\"version\">\r\n    <value>2.0</value>\r\n  </resheader>\r\n  <resheader name=\"reader\">\r\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r\n  </resheader>\r\n  <resheader name=\"writer\">\r\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r\n  </resheader>\r\n</root>"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/FormShengImageListView.Designer.cs",
    "content": "﻿namespace Sheng.Winform.Controls.Demo\r\n{\r\n    partial class FormShengImageListView\r\n    {\r\n        /// <summary>\r\n        /// Required designer variable.\r\n        /// </summary>\r\n        private System.ComponentModel.IContainer components = null;\r\n\r\n        /// <summary>\r\n        /// Clean up any resources being used.\r\n        /// </summary>\r\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\r\n        protected override void Dispose(bool disposing)\r\n        {\r\n            if (disposing && (components != null))\r\n            {\r\n                components.Dispose();\r\n            }\r\n            base.Dispose(disposing);\r\n        }\r\n\r\n        #region Windows Form Designer generated code\r\n\r\n        /// <summary>\r\n        /// Required method for Designer support - do not modify\r\n        /// the contents of this method with the code editor.\r\n        /// </summary>\r\n        private void InitializeComponent()\r\n        {\r\n            Sheng.Winform.Controls.ShengImageListViewTheme shengImageListViewTheme1 = new Sheng.Winform.Controls.ShengImageListViewTheme();\r\n            Sheng.Winform.Controls.ShengImageListViewTheme shengImageListViewTheme2 = new Sheng.Winform.Controls.ShengImageListViewTheme();\r\n            this.shengImageListView1 = new Sheng.Winform.Controls.ShengImageListView();\r\n            this.pictureBox2 = new System.Windows.Forms.PictureBox();\r\n            this.pictureBox1 = new System.Windows.Forms.PictureBox();\r\n            this.label1 = new System.Windows.Forms.Label();\r\n            this.label2 = new System.Windows.Forms.Label();\r\n            this.label3 = new System.Windows.Forms.Label();\r\n            this.label4 = new System.Windows.Forms.Label();\r\n            this.label5 = new System.Windows.Forms.Label();\r\n            this.label6 = new System.Windows.Forms.Label();\r\n            this.shengImageListView2 = new Sheng.Winform.Controls.ShengImageListView();\r\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).BeginInit();\r\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();\r\n            this.SuspendLayout();\r\n            // \r\n            // shengImageListView1\r\n            // \r\n            this.shengImageListView1.AllowMultiSelection = false;\r\n            this.shengImageListView1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \r\n            | System.Windows.Forms.AnchorStyles.Left) \r\n            | System.Windows.Forms.AnchorStyles.Right)));\r\n            this.shengImageListView1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;\r\n            this.shengImageListView1.Location = new System.Drawing.Point(12, 12);\r\n            this.shengImageListView1.Name = \"shengImageListView1\";\r\n            this.shengImageListView1.Padding = new System.Windows.Forms.Padding(10);\r\n            this.shengImageListView1.Size = new System.Drawing.Size(726, 356);\r\n            this.shengImageListView1.TabIndex = 0;\r\n            this.shengImageListView1.Text = \"shengImageListView1\";\r\n            shengImageListViewTheme1.BackColor = System.Drawing.SystemColors.Window;\r\n            shengImageListViewTheme1.HoverColorEnd = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(0)))), ((int)(((byte)(120)))), ((int)(((byte)(215)))));\r\n            shengImageListViewTheme1.HoverColorStart = System.Drawing.Color.FromArgb(((int)(((byte)(8)))), ((int)(((byte)(0)))), ((int)(((byte)(120)))), ((int)(((byte)(215)))));\r\n            shengImageListViewTheme1.ImageInnerBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(128)))), ((int)(((byte)(255)))), ((int)(((byte)(255)))), ((int)(((byte)(255)))));\r\n            shengImageListViewTheme1.ImageOuterBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(128)))), ((int)(((byte)(128)))), ((int)(((byte)(128)))), ((int)(((byte)(128)))));\r\n            shengImageListViewTheme1.ItemBackColor = System.Drawing.SystemColors.Window;\r\n            shengImageListViewTheme1.ItemBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(109)))), ((int)(((byte)(109)))), ((int)(((byte)(109)))));\r\n            shengImageListViewTheme1.ItemHeaderColor = System.Drawing.SystemColors.WindowText;\r\n            shengImageListViewTheme1.ItemHeaderFont = new System.Drawing.Font(\"宋体\", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));\r\n            shengImageListViewTheme1.SelectedColorEnd = System.Drawing.Color.FromArgb(((int)(((byte)(128)))), ((int)(((byte)(0)))), ((int)(((byte)(120)))), ((int)(((byte)(215)))));\r\n            shengImageListViewTheme1.SelectedColorStart = System.Drawing.Color.FromArgb(((int)(((byte)(16)))), ((int)(((byte)(0)))), ((int)(((byte)(120)))), ((int)(((byte)(215)))));\r\n            shengImageListViewTheme1.SelectionRectangleBorderColor = System.Drawing.SystemColors.Highlight;\r\n            shengImageListViewTheme1.SelectionRectangleColor = System.Drawing.Color.FromArgb(((int)(((byte)(128)))), ((int)(((byte)(0)))), ((int)(((byte)(120)))), ((int)(((byte)(215)))));\r\n            shengImageListViewTheme1.UnFocusedColorEnd = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(109)))), ((int)(((byte)(109)))), ((int)(((byte)(109)))));\r\n            shengImageListViewTheme1.UnFocusedColorStart = System.Drawing.Color.FromArgb(((int)(((byte)(16)))), ((int)(((byte)(109)))), ((int)(((byte)(109)))), ((int)(((byte)(109)))));\r\n            this.shengImageListView1.Theme = shengImageListViewTheme1;\r\n            // \r\n            // pictureBox2\r\n            // \r\n            this.pictureBox2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));\r\n            this.pictureBox2.Image = global::Sheng.Winform.Controls.Demo.Resource1._11;\r\n            this.pictureBox2.Location = new System.Drawing.Point(388, 388);\r\n            this.pictureBox2.Name = \"pictureBox2\";\r\n            this.pictureBox2.Size = new System.Drawing.Size(344, 336);\r\n            this.pictureBox2.TabIndex = 2;\r\n            this.pictureBox2.TabStop = false;\r\n            // \r\n            // pictureBox1\r\n            // \r\n            this.pictureBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));\r\n            this.pictureBox1.Image = global::Sheng.Winform.Controls.Demo.Resource1._10;\r\n            this.pictureBox1.Location = new System.Drawing.Point(12, 388);\r\n            this.pictureBox1.Name = \"pictureBox1\";\r\n            this.pictureBox1.Size = new System.Drawing.Size(344, 264);\r\n            this.pictureBox1.TabIndex = 1;\r\n            this.pictureBox1.TabStop = false;\r\n            // \r\n            // label1\r\n            // \r\n            this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));\r\n            this.label1.AutoSize = true;\r\n            this.label1.Location = new System.Drawing.Point(806, 29);\r\n            this.label1.Name = \"label1\";\r\n            this.label1.Size = new System.Drawing.Size(251, 12);\r\n            this.label1.TabIndex = 3;\r\n            this.label1.Text = \"ShengImageListView 是一个图像浏览器控件。\";\r\n            // \r\n            // label2\r\n            // \r\n            this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));\r\n            this.label2.AutoSize = true;\r\n            this.label2.Location = new System.Drawing.Point(806, 58);\r\n            this.label2.Name = \"label2\";\r\n            this.label2.Size = new System.Drawing.Size(515, 12);\r\n            this.label2.TabIndex = 4;\r\n            this.label2.Text = \"ShengImageListView 具有非常良好的实现结构，独立实现了布局管理器，渲染器，和配色方案。\";\r\n            // \r\n            // label3\r\n            // \r\n            this.label3.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));\r\n            this.label3.Location = new System.Drawing.Point(806, 88);\r\n            this.label3.Name = \"label3\";\r\n            this.label3.Size = new System.Drawing.Size(536, 39);\r\n            this.label3.TabIndex = 5;\r\n            this.label3.Text = \"ShengImageListViewRenderer，ShengImageListViewStandardRenderer：渲染器基类和默认实现的渲染器。\";\r\n            // \r\n            // label4\r\n            // \r\n            this.label4.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));\r\n            this.label4.Location = new System.Drawing.Point(806, 127);\r\n            this.label4.Name = \"label4\";\r\n            this.label4.Size = new System.Drawing.Size(536, 23);\r\n            this.label4.TabIndex = 6;\r\n            this.label4.Text = \"ShengImageListViewLayoutManager 默认实现的布局管理器。\";\r\n            // \r\n            // label5\r\n            // \r\n            this.label5.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));\r\n            this.label5.Location = new System.Drawing.Point(806, 163);\r\n            this.label5.Name = \"label5\";\r\n            this.label5.Size = new System.Drawing.Size(536, 23);\r\n            this.label5.TabIndex = 7;\r\n            this.label5.Text = \"ShengImageListViewTheme 主题功能，提供渲染器所需使用的配色方案。\";\r\n            // \r\n            // label6\r\n            // \r\n            this.label6.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));\r\n            this.label6.Location = new System.Drawing.Point(806, 200);\r\n            this.label6.Name = \"label6\";\r\n            this.label6.Size = new System.Drawing.Size(536, 39);\r\n            this.label6.TabIndex = 8;\r\n            this.label6.Text = \"你可以通过修改或实现新的布局管理器，渲染器，实现更加复杂的功能，甚至是完全不同用处的控件，例如：一个售票系统的选座控件。\";\r\n            // \r\n            // shengImageListView2\r\n            // \r\n            this.shengImageListView2.AllowMultiSelection = false;\r\n            this.shengImageListView2.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \r\n            | System.Windows.Forms.AnchorStyles.Left) \r\n            | System.Windows.Forms.AnchorStyles.Right)));\r\n            this.shengImageListView2.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;\r\n            this.shengImageListView2.Location = new System.Drawing.Point(778, 388);\r\n            this.shengImageListView2.Name = \"shengImageListView2\";\r\n            this.shengImageListView2.Padding = new System.Windows.Forms.Padding(10);\r\n            this.shengImageListView2.Size = new System.Drawing.Size(543, 307);\r\n            this.shengImageListView2.TabIndex = 9;\r\n            this.shengImageListView2.Text = \"shengImageListView2\";\r\n            shengImageListViewTheme2.BackColor = System.Drawing.SystemColors.Window;\r\n            shengImageListViewTheme2.HoverColorEnd = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(0)))), ((int)(((byte)(120)))), ((int)(((byte)(215)))));\r\n            shengImageListViewTheme2.HoverColorStart = System.Drawing.Color.FromArgb(((int)(((byte)(8)))), ((int)(((byte)(0)))), ((int)(((byte)(120)))), ((int)(((byte)(215)))));\r\n            shengImageListViewTheme2.ImageInnerBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(128)))), ((int)(((byte)(255)))), ((int)(((byte)(255)))), ((int)(((byte)(255)))));\r\n            shengImageListViewTheme2.ImageOuterBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(128)))), ((int)(((byte)(128)))), ((int)(((byte)(128)))), ((int)(((byte)(128)))));\r\n            shengImageListViewTheme2.ItemBackColor = System.Drawing.SystemColors.Window;\r\n            shengImageListViewTheme2.ItemBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(109)))), ((int)(((byte)(109)))), ((int)(((byte)(109)))));\r\n            shengImageListViewTheme2.ItemHeaderColor = System.Drawing.SystemColors.WindowText;\r\n            shengImageListViewTheme2.ItemHeaderFont = new System.Drawing.Font(\"宋体\", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));\r\n            shengImageListViewTheme2.SelectedColorEnd = System.Drawing.Color.FromArgb(((int)(((byte)(128)))), ((int)(((byte)(0)))), ((int)(((byte)(120)))), ((int)(((byte)(215)))));\r\n            shengImageListViewTheme2.SelectedColorStart = System.Drawing.Color.FromArgb(((int)(((byte)(16)))), ((int)(((byte)(0)))), ((int)(((byte)(120)))), ((int)(((byte)(215)))));\r\n            shengImageListViewTheme2.SelectionRectangleBorderColor = System.Drawing.SystemColors.Highlight;\r\n            shengImageListViewTheme2.SelectionRectangleColor = System.Drawing.Color.FromArgb(((int)(((byte)(128)))), ((int)(((byte)(0)))), ((int)(((byte)(120)))), ((int)(((byte)(215)))));\r\n            shengImageListViewTheme2.UnFocusedColorEnd = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(109)))), ((int)(((byte)(109)))), ((int)(((byte)(109)))));\r\n            shengImageListViewTheme2.UnFocusedColorStart = System.Drawing.Color.FromArgb(((int)(((byte)(16)))), ((int)(((byte)(109)))), ((int)(((byte)(109)))), ((int)(((byte)(109)))));\r\n            this.shengImageListView2.Theme = shengImageListViewTheme2;\r\n            // \r\n            // FormShengImageListView\r\n            // \r\n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);\r\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\r\n            this.ClientSize = new System.Drawing.Size(1354, 750);\r\n            this.Controls.Add(this.shengImageListView2);\r\n            this.Controls.Add(this.label6);\r\n            this.Controls.Add(this.label5);\r\n            this.Controls.Add(this.label4);\r\n            this.Controls.Add(this.label3);\r\n            this.Controls.Add(this.label2);\r\n            this.Controls.Add(this.label1);\r\n            this.Controls.Add(this.pictureBox2);\r\n            this.Controls.Add(this.pictureBox1);\r\n            this.Controls.Add(this.shengImageListView1);\r\n            this.Name = \"FormShengImageListView\";\r\n            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;\r\n            this.Text = \"FormShengImageListView\";\r\n            this.Load += new System.EventHandler(this.FormShengImageListView_Load);\r\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).EndInit();\r\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();\r\n            this.ResumeLayout(false);\r\n            this.PerformLayout();\r\n\r\n        }\r\n\r\n        #endregion\r\n\r\n        private ShengImageListView shengImageListView1;\r\n        private System.Windows.Forms.PictureBox pictureBox1;\r\n        private System.Windows.Forms.PictureBox pictureBox2;\r\n        private System.Windows.Forms.Label label1;\r\n        private System.Windows.Forms.Label label2;\r\n        private System.Windows.Forms.Label label3;\r\n        private System.Windows.Forms.Label label4;\r\n        private System.Windows.Forms.Label label5;\r\n        private System.Windows.Forms.Label label6;\r\n        private ShengImageListView shengImageListView2;\r\n    }\r\n}"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/FormShengImageListView.cs",
    "content": "﻿using System;\r\nusing System.Collections.Generic;\r\nusing System.ComponentModel;\r\nusing System.Data;\r\nusing System.Drawing;\r\nusing System.IO;\r\nusing System.Linq;\r\nusing System.Text;\r\nusing System.Windows.Forms;\r\n\r\nnamespace Sheng.Winform.Controls.Demo\r\n{\r\n    public partial class FormShengImageListView : Form\r\n    {\r\n        private string _imagesDir;\r\n\r\n        public FormShengImageListView()\r\n        {\r\n            InitializeComponent();\r\n        }\r\n\r\n        private void FormShengImageListView_Load(object sender, EventArgs e)\r\n        {\r\n            _imagesDir = Path.Combine(Application.StartupPath, \"Images\");\r\n\r\n            shengImageListView1.AllowMultiSelection = true;\r\n            shengImageListView1.Items.Add(new ShengImageListViewItem(\"1.jpg\", GetImageHandler));\r\n            shengImageListView1.Items.Add(new ShengImageListViewItem(\"2.jpg\", GetImageHandler));\r\n            shengImageListView1.Items.Add(new ShengImageListViewItem(\"3.jpg\", GetImageHandler));\r\n            shengImageListView1.Items.Add(new ShengImageListViewItem(\"4.jpg\", GetImageHandler));\r\n            shengImageListView1.Items.Add(new ShengImageListViewItem(\"5.jpg\", GetImageHandler));\r\n\r\n\r\n            shengImageListView2.AllowMultiSelection = true;\r\n            shengImageListView2.LayoutManager.Renderer = new ShengImageListViewRenderer(shengImageListView2.LayoutManager);\r\n            shengImageListView2.Items.Add(new ShengImageListViewItem(\"1.jpg\", GetImageHandler));\r\n            shengImageListView2.Items.Add(new ShengImageListViewItem(\"2.jpg\", GetImageHandler));\r\n            shengImageListView2.Items.Add(new ShengImageListViewItem(\"3.jpg\", GetImageHandler));\r\n            shengImageListView2.Items.Add(new ShengImageListViewItem(\"4.jpg\", GetImageHandler));\r\n            shengImageListView2.Items.Add(new ShengImageListViewItem(\"5.jpg\", GetImageHandler));\r\n\r\n        }\r\n\r\n        private Image GetImageHandler(object key)\r\n        {\r\n            Image image = Image.FromFile(Path.Combine(_imagesDir, key.ToString()));\r\n            return image;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/FormShengImageListView.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<root>\r\n  <!-- \r\n    Microsoft ResX Schema \r\n    \r\n    Version 2.0\r\n    \r\n    The primary goals of this format is to allow a simple XML format \r\n    that is mostly human readable. The generation and parsing of the \r\n    various data types are done through the TypeConverter classes \r\n    associated with the data types.\r\n    \r\n    Example:\r\n    \r\n    ... ado.net/XML headers & schema ...\r\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\r\n    <resheader name=\"version\">2.0</resheader>\r\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\r\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\r\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\r\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\r\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\r\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\r\n    </data>\r\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\r\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\r\n        <comment>This is a comment</comment>\r\n    </data>\r\n                \r\n    There are any number of \"resheader\" rows that contain simple \r\n    name/value pairs.\r\n    \r\n    Each data row contains a name, and value. The row also contains a \r\n    type or mimetype. Type corresponds to a .NET class that support \r\n    text/value conversion through the TypeConverter architecture. \r\n    Classes that don't support this are serialized and stored with the \r\n    mimetype set.\r\n    \r\n    The mimetype is used for serialized objects, and tells the \r\n    ResXResourceReader how to depersist the object. This is currently not \r\n    extensible. For a given mimetype the value must be set accordingly:\r\n    \r\n    Note - application/x-microsoft.net.object.binary.base64 is the format \r\n    that the ResXResourceWriter will generate, however the reader can \r\n    read any of the formats listed below.\r\n    \r\n    mimetype: application/x-microsoft.net.object.binary.base64\r\n    value   : The object must be serialized with \r\n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\r\n            : and then encoded with base64 encoding.\r\n    \r\n    mimetype: application/x-microsoft.net.object.soap.base64\r\n    value   : The object must be serialized with \r\n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\r\n            : and then encoded with base64 encoding.\r\n\r\n    mimetype: application/x-microsoft.net.object.bytearray.base64\r\n    value   : The object must be serialized into a byte array \r\n            : using a System.ComponentModel.TypeConverter\r\n            : and then encoded with base64 encoding.\r\n    -->\r\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\r\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\r\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\r\n      <xsd:complexType>\r\n        <xsd:choice maxOccurs=\"unbounded\">\r\n          <xsd:element name=\"metadata\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\r\n              <xsd:attribute ref=\"xml:space\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"assembly\">\r\n            <xsd:complexType>\r\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"data\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\r\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\r\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\r\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\r\n              <xsd:attribute ref=\"xml:space\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"resheader\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n        </xsd:choice>\r\n      </xsd:complexType>\r\n    </xsd:element>\r\n  </xsd:schema>\r\n  <resheader name=\"resmimetype\">\r\n    <value>text/microsoft-resx</value>\r\n  </resheader>\r\n  <resheader name=\"version\">\r\n    <value>2.0</value>\r\n  </resheader>\r\n  <resheader name=\"reader\">\r\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r\n  </resheader>\r\n  <resheader name=\"writer\">\r\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r\n  </resheader>\r\n</root>"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/FormShengListView.Designer.cs",
    "content": "﻿namespace Sheng.Winform.Controls.Demo\r\n{\r\n    partial class FormShengListView\r\n    {\r\n        /// <summary>\r\n        /// Required designer variable.\r\n        /// </summary>\r\n        private System.ComponentModel.IContainer components = null;\r\n\r\n        /// <summary>\r\n        /// Clean up any resources being used.\r\n        /// </summary>\r\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\r\n        protected override void Dispose(bool disposing)\r\n        {\r\n            if (disposing && (components != null))\r\n            {\r\n                components.Dispose();\r\n            }\r\n            base.Dispose(disposing);\r\n        }\r\n\r\n        #region Windows Form Designer generated code\r\n\r\n        /// <summary>\r\n        /// Required method for Designer support - do not modify\r\n        /// the contents of this method with the code editor.\r\n        /// </summary>\r\n        private void InitializeComponent()\r\n        {\r\n            Sheng.Winform.Controls.ShengListViewTheme shengListViewTheme1 = new Sheng.Winform.Controls.ShengListViewTheme();\r\n            Sheng.Winform.Controls.ShengListViewTheme shengListViewTheme2 = new Sheng.Winform.Controls.ShengListViewTheme();\r\n            this.shengListView2 = new Sheng.Winform.Controls.ShengListView();\r\n            this.shengListView1 = new Sheng.Winform.Controls.ShengListView();\r\n            this.label1 = new System.Windows.Forms.Label();\r\n            this.pictureBox2 = new System.Windows.Forms.PictureBox();\r\n            this.pictureBox1 = new System.Windows.Forms.PictureBox();\r\n            this.label2 = new System.Windows.Forms.Label();\r\n            this.label3 = new System.Windows.Forms.Label();\r\n            this.label4 = new System.Windows.Forms.Label();\r\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).BeginInit();\r\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();\r\n            this.SuspendLayout();\r\n            // \r\n            // shengListView2\r\n            // \r\n            this.shengListView2.AllowMultiSelection = false;\r\n            this.shengListView2.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;\r\n            this.shengListView2.DisplayMember = null;\r\n            this.shengListView2.LayoutMode = Sheng.Winform.Controls.ShengListViewLayoutMode.Standard;\r\n            this.shengListView2.Location = new System.Drawing.Point(22, 228);\r\n            this.shengListView2.Name = \"shengListView2\";\r\n            this.shengListView2.Padding = new System.Windows.Forms.Padding(10);\r\n            this.shengListView2.Size = new System.Drawing.Size(306, 146);\r\n            this.shengListView2.TabIndex = 1;\r\n            this.shengListView2.Text = \"shengListView2\";\r\n            shengListViewTheme1.BackColor = System.Drawing.SystemColors.Window;\r\n            shengListViewTheme1.HoverColorEnd = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(0)))), ((int)(((byte)(120)))), ((int)(((byte)(215)))));\r\n            shengListViewTheme1.HoverColorStart = System.Drawing.Color.FromArgb(((int)(((byte)(8)))), ((int)(((byte)(0)))), ((int)(((byte)(120)))), ((int)(((byte)(215)))));\r\n            shengListViewTheme1.ImageInnerBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(128)))), ((int)(((byte)(255)))), ((int)(((byte)(255)))), ((int)(((byte)(255)))));\r\n            shengListViewTheme1.ImageOuterBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(128)))), ((int)(((byte)(128)))), ((int)(((byte)(128)))), ((int)(((byte)(128)))));\r\n            shengListViewTheme1.ItemBackColor = System.Drawing.SystemColors.Window;\r\n            shengListViewTheme1.ItemBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(109)))), ((int)(((byte)(109)))), ((int)(((byte)(109)))));\r\n            shengListViewTheme1.ItemDescriptioniColor = System.Drawing.SystemColors.GrayText;\r\n            shengListViewTheme1.ItemHeaderColor = System.Drawing.SystemColors.WindowText;\r\n            shengListViewTheme1.ItemHeaderFont = new System.Drawing.Font(\"宋体\", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));\r\n            shengListViewTheme1.SelectedColorEnd = System.Drawing.Color.FromArgb(((int)(((byte)(128)))), ((int)(((byte)(0)))), ((int)(((byte)(120)))), ((int)(((byte)(215)))));\r\n            shengListViewTheme1.SelectedColorStart = System.Drawing.Color.FromArgb(((int)(((byte)(16)))), ((int)(((byte)(0)))), ((int)(((byte)(120)))), ((int)(((byte)(215)))));\r\n            shengListViewTheme1.SelectionRectangleBorderColor = System.Drawing.SystemColors.Highlight;\r\n            shengListViewTheme1.SelectionRectangleColor = System.Drawing.Color.FromArgb(((int)(((byte)(128)))), ((int)(((byte)(0)))), ((int)(((byte)(120)))), ((int)(((byte)(215)))));\r\n            shengListViewTheme1.UnFocusedColorEnd = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(109)))), ((int)(((byte)(109)))), ((int)(((byte)(109)))));\r\n            shengListViewTheme1.UnFocusedColorStart = System.Drawing.Color.FromArgb(((int)(((byte)(16)))), ((int)(((byte)(109)))), ((int)(((byte)(109)))), ((int)(((byte)(109)))));\r\n            this.shengListView2.Theme = shengListViewTheme1;\r\n            // \r\n            // shengListView1\r\n            // \r\n            this.shengListView1.AllowMultiSelection = false;\r\n            this.shengListView1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;\r\n            this.shengListView1.DisplayMember = null;\r\n            this.shengListView1.LayoutMode = Sheng.Winform.Controls.ShengListViewLayoutMode.Standard;\r\n            this.shengListView1.Location = new System.Drawing.Point(22, 33);\r\n            this.shengListView1.Name = \"shengListView1\";\r\n            this.shengListView1.Padding = new System.Windows.Forms.Padding(10);\r\n            this.shengListView1.Size = new System.Drawing.Size(306, 146);\r\n            this.shengListView1.TabIndex = 0;\r\n            this.shengListView1.Text = \"shengListView1\";\r\n            shengListViewTheme2.BackColor = System.Drawing.SystemColors.Window;\r\n            shengListViewTheme2.HoverColorEnd = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(0)))), ((int)(((byte)(120)))), ((int)(((byte)(215)))));\r\n            shengListViewTheme2.HoverColorStart = System.Drawing.Color.FromArgb(((int)(((byte)(8)))), ((int)(((byte)(0)))), ((int)(((byte)(120)))), ((int)(((byte)(215)))));\r\n            shengListViewTheme2.ImageInnerBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(128)))), ((int)(((byte)(255)))), ((int)(((byte)(255)))), ((int)(((byte)(255)))));\r\n            shengListViewTheme2.ImageOuterBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(128)))), ((int)(((byte)(128)))), ((int)(((byte)(128)))), ((int)(((byte)(128)))));\r\n            shengListViewTheme2.ItemBackColor = System.Drawing.SystemColors.Window;\r\n            shengListViewTheme2.ItemBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(109)))), ((int)(((byte)(109)))), ((int)(((byte)(109)))));\r\n            shengListViewTheme2.ItemDescriptioniColor = System.Drawing.SystemColors.GrayText;\r\n            shengListViewTheme2.ItemHeaderColor = System.Drawing.SystemColors.WindowText;\r\n            shengListViewTheme2.ItemHeaderFont = new System.Drawing.Font(\"宋体\", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));\r\n            shengListViewTheme2.SelectedColorEnd = System.Drawing.Color.FromArgb(((int)(((byte)(128)))), ((int)(((byte)(0)))), ((int)(((byte)(120)))), ((int)(((byte)(215)))));\r\n            shengListViewTheme2.SelectedColorStart = System.Drawing.Color.FromArgb(((int)(((byte)(16)))), ((int)(((byte)(0)))), ((int)(((byte)(120)))), ((int)(((byte)(215)))));\r\n            shengListViewTheme2.SelectionRectangleBorderColor = System.Drawing.SystemColors.Highlight;\r\n            shengListViewTheme2.SelectionRectangleColor = System.Drawing.Color.FromArgb(((int)(((byte)(128)))), ((int)(((byte)(0)))), ((int)(((byte)(120)))), ((int)(((byte)(215)))));\r\n            shengListViewTheme2.UnFocusedColorEnd = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(109)))), ((int)(((byte)(109)))), ((int)(((byte)(109)))));\r\n            shengListViewTheme2.UnFocusedColorStart = System.Drawing.Color.FromArgb(((int)(((byte)(16)))), ((int)(((byte)(109)))), ((int)(((byte)(109)))), ((int)(((byte)(109)))));\r\n            this.shengListView1.Theme = shengListViewTheme2;\r\n            // \r\n            // label1\r\n            // \r\n            this.label1.AutoSize = true;\r\n            this.label1.Location = new System.Drawing.Point(361, 33);\r\n            this.label1.Name = \"label1\";\r\n            this.label1.Size = new System.Drawing.Size(497, 12);\r\n            this.label1.TabIndex = 2;\r\n            this.label1.Text = \"ShengListView 是完全重头实现的一个 ListView 控件，而非原生 ListView 的继承和扩展。\";\r\n            // \r\n            // pictureBox2\r\n            // \r\n            this.pictureBox2.Image = global::Sheng.Winform.Controls.Demo.Resource1._3;\r\n            this.pictureBox2.Location = new System.Drawing.Point(732, 190);\r\n            this.pictureBox2.Name = \"pictureBox2\";\r\n            this.pictureBox2.Size = new System.Drawing.Size(349, 358);\r\n            this.pictureBox2.TabIndex = 4;\r\n            this.pictureBox2.TabStop = false;\r\n            // \r\n            // pictureBox1\r\n            // \r\n            this.pictureBox1.Image = global::Sheng.Winform.Controls.Demo.Resource1._2;\r\n            this.pictureBox1.Location = new System.Drawing.Point(359, 190);\r\n            this.pictureBox1.Name = \"pictureBox1\";\r\n            this.pictureBox1.Size = new System.Drawing.Size(367, 358);\r\n            this.pictureBox1.TabIndex = 3;\r\n            this.pictureBox1.TabStop = false;\r\n            // \r\n            // label2\r\n            // \r\n            this.label2.AutoSize = true;\r\n            this.label2.Location = new System.Drawing.Point(361, 68);\r\n            this.label2.Name = \"label2\";\r\n            this.label2.Size = new System.Drawing.Size(641, 12);\r\n            this.label2.TabIndex = 5;\r\n            this.label2.Text = \"将布局相关的逻辑，独立实现为不同的 Layout，ShengListViewLayoutManager 作为基类，提供了布局所需的基本功能。\";\r\n            // \r\n            // label3\r\n            // \r\n            this.label3.AutoSize = true;\r\n            this.label3.Location = new System.Drawing.Point(361, 100);\r\n            this.label3.Name = \"label3\";\r\n            this.label3.Size = new System.Drawing.Size(611, 12);\r\n            this.label3.TabIndex = 6;\r\n            this.label3.Text = \"将绘图相关的逻辑，独立实现为不同的 Render，ShengListViewRenderer 作为基类，提供了绘图所需的基本功能。\";\r\n            // \r\n            // label4\r\n            // \r\n            this.label4.AutoSize = true;\r\n            this.label4.Location = new System.Drawing.Point(361, 133);\r\n            this.label4.Name = \"label4\";\r\n            this.label4.Size = new System.Drawing.Size(611, 12);\r\n            this.label4.TabIndex = 7;\r\n            this.label4.Text = \"而绘图时所需要用的配色方案，在 ShengListViewTheme 中定义，你可以定制不同的主题。\";\r\n            // \r\n            // FormShengListView\r\n            // \r\n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);\r\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\r\n            this.ClientSize = new System.Drawing.Size(1093, 709);\r\n            this.Controls.Add(this.label4);\r\n            this.Controls.Add(this.label3);\r\n            this.Controls.Add(this.label2);\r\n            this.Controls.Add(this.pictureBox2);\r\n            this.Controls.Add(this.pictureBox1);\r\n            this.Controls.Add(this.label1);\r\n            this.Controls.Add(this.shengListView2);\r\n            this.Controls.Add(this.shengListView1);\r\n            this.Name = \"FormShengListView\";\r\n            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;\r\n            this.Text = \"FormShengListView\";\r\n            this.Load += new System.EventHandler(this.FormShengListView_Load);\r\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).EndInit();\r\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();\r\n            this.ResumeLayout(false);\r\n            this.PerformLayout();\r\n\r\n        }\r\n\r\n        #endregion\r\n\r\n        private ShengListView shengListView1;\r\n        private ShengListView shengListView2;\r\n        private System.Windows.Forms.Label label1;\r\n        private System.Windows.Forms.PictureBox pictureBox1;\r\n        private System.Windows.Forms.PictureBox pictureBox2;\r\n        private System.Windows.Forms.Label label2;\r\n        private System.Windows.Forms.Label label3;\r\n        private System.Windows.Forms.Label label4;\r\n    }\r\n}"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/FormShengListView.cs",
    "content": "﻿using System;\r\nusing System.Collections.Generic;\r\nusing System.ComponentModel;\r\nusing System.Data;\r\nusing System.Drawing;\r\nusing System.Linq;\r\nusing System.Text;\r\nusing System.Windows.Forms;\r\n\r\nnamespace Sheng.Winform.Controls.Demo\r\n{\r\n    public partial class FormShengListView : Form\r\n    {\r\n        public FormShengListView()\r\n        {\r\n            InitializeComponent();\r\n        }\r\n\r\n        private void FormShengListView_Load(object sender, EventArgs e)\r\n        {\r\n            \r\n\r\n            shengListView1.DisplayMember = \"Name\";\r\n            shengListView1.DataBind(TestListViewItem.GetTestData());\r\n\r\n            shengListView2.SetExtendMember(\"Description\", \"Description\");\r\n            shengListView2.LayoutMode = ShengListViewLayoutMode.Descriptive;\r\n            shengListView2.Theme.SelectedColorStart = Color.Yellow;\r\n            shengListView2.Theme.SelectedColorEnd = Color.LightYellow;\r\n            shengListView2.DisplayMember = \"Name\";\r\n            shengListView2.DataBind(TestListViewItem.GetTestData());\r\n        }\r\n\r\n      \r\n\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/FormShengListView.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<root>\r\n  <!-- \r\n    Microsoft ResX Schema \r\n    \r\n    Version 2.0\r\n    \r\n    The primary goals of this format is to allow a simple XML format \r\n    that is mostly human readable. The generation and parsing of the \r\n    various data types are done through the TypeConverter classes \r\n    associated with the data types.\r\n    \r\n    Example:\r\n    \r\n    ... ado.net/XML headers & schema ...\r\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\r\n    <resheader name=\"version\">2.0</resheader>\r\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\r\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\r\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\r\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\r\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\r\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\r\n    </data>\r\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\r\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\r\n        <comment>This is a comment</comment>\r\n    </data>\r\n                \r\n    There are any number of \"resheader\" rows that contain simple \r\n    name/value pairs.\r\n    \r\n    Each data row contains a name, and value. The row also contains a \r\n    type or mimetype. Type corresponds to a .NET class that support \r\n    text/value conversion through the TypeConverter architecture. \r\n    Classes that don't support this are serialized and stored with the \r\n    mimetype set.\r\n    \r\n    The mimetype is used for serialized objects, and tells the \r\n    ResXResourceReader how to depersist the object. This is currently not \r\n    extensible. For a given mimetype the value must be set accordingly:\r\n    \r\n    Note - application/x-microsoft.net.object.binary.base64 is the format \r\n    that the ResXResourceWriter will generate, however the reader can \r\n    read any of the formats listed below.\r\n    \r\n    mimetype: application/x-microsoft.net.object.binary.base64\r\n    value   : The object must be serialized with \r\n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\r\n            : and then encoded with base64 encoding.\r\n    \r\n    mimetype: application/x-microsoft.net.object.soap.base64\r\n    value   : The object must be serialized with \r\n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\r\n            : and then encoded with base64 encoding.\r\n\r\n    mimetype: application/x-microsoft.net.object.bytearray.base64\r\n    value   : The object must be serialized into a byte array \r\n            : using a System.ComponentModel.TypeConverter\r\n            : and then encoded with base64 encoding.\r\n    -->\r\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\r\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\r\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\r\n      <xsd:complexType>\r\n        <xsd:choice maxOccurs=\"unbounded\">\r\n          <xsd:element name=\"metadata\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\r\n              <xsd:attribute ref=\"xml:space\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"assembly\">\r\n            <xsd:complexType>\r\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"data\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\r\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\r\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\r\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\r\n              <xsd:attribute ref=\"xml:space\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"resheader\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n        </xsd:choice>\r\n      </xsd:complexType>\r\n    </xsd:element>\r\n  </xsd:schema>\r\n  <resheader name=\"resmimetype\">\r\n    <value>text/microsoft-resx</value>\r\n  </resheader>\r\n  <resheader name=\"version\">\r\n    <value>2.0</value>\r\n  </resheader>\r\n  <resheader name=\"reader\">\r\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r\n  </resheader>\r\n  <resheader name=\"writer\">\r\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r\n  </resheader>\r\n</root>"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/FormShengThumbnailImageListView.Designer.cs",
    "content": "﻿namespace Sheng.Winform.Controls.Demo\r\n{\r\n    partial class FormShengThumbnailImageListView\r\n    {\r\n        /// <summary>\r\n        /// Required designer variable.\r\n        /// </summary>\r\n        private System.ComponentModel.IContainer components = null;\r\n\r\n        /// <summary>\r\n        /// Clean up any resources being used.\r\n        /// </summary>\r\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\r\n        protected override void Dispose(bool disposing)\r\n        {\r\n            if (disposing && (components != null))\r\n            {\r\n                components.Dispose();\r\n            }\r\n            base.Dispose(disposing);\r\n        }\r\n\r\n        #region Windows Form Designer generated code\r\n\r\n        /// <summary>\r\n        /// Required method for Designer support - do not modify\r\n        /// the contents of this method with the code editor.\r\n        /// </summary>\r\n        private void InitializeComponent()\r\n        {\r\n            this.components = new System.ComponentModel.Container();\r\n            this.shengThumbnailImageListView1 = new Sheng.Winform.Controls.ShengThumbnailImageListView();\r\n            this.label1 = new System.Windows.Forms.Label();\r\n            this.pictureBox1 = new System.Windows.Forms.PictureBox();\r\n            this.label2 = new System.Windows.Forms.Label();\r\n            this.label3 = new System.Windows.Forms.Label();\r\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();\r\n            this.SuspendLayout();\r\n            // \r\n            // shengThumbnailImageListView1\r\n            // \r\n            this.shengThumbnailImageListView1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \r\n            | System.Windows.Forms.AnchorStyles.Left) \r\n            | System.Windows.Forms.AnchorStyles.Right)));\r\n            this.shengThumbnailImageListView1.Filter = \"*.jpg|*.png|*.gif|*.bmp\";\r\n            this.shengThumbnailImageListView1.Folder = null;\r\n            this.shengThumbnailImageListView1.Location = new System.Drawing.Point(27, 31);\r\n            this.shengThumbnailImageListView1.Name = \"shengThumbnailImageListView1\";\r\n            this.shengThumbnailImageListView1.Size = new System.Drawing.Size(492, 402);\r\n            this.shengThumbnailImageListView1.TabIndex = 0;\r\n            this.shengThumbnailImageListView1.ThumbBorderColor = System.Drawing.Color.White;\r\n            this.shengThumbnailImageListView1.ThumbNailSize = 95;\r\n            this.shengThumbnailImageListView1.UseCompatibleStateImageBehavior = false;\r\n            // \r\n            // label1\r\n            // \r\n            this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));\r\n            this.label1.AutoSize = true;\r\n            this.label1.Location = new System.Drawing.Point(25, 460);\r\n            this.label1.Name = \"label1\";\r\n            this.label1.Size = new System.Drawing.Size(275, 12);\r\n            this.label1.TabIndex = 1;\r\n            this.label1.Text = \"ShengThumbnailImageListView 是一个简单的缩略图浏览控件。\";\r\n            // \r\n            // pictureBox1\r\n            // \r\n            this.pictureBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));\r\n            this.pictureBox1.Image = global::Sheng.Winform.Controls.Demo.Resource1._13;\r\n            this.pictureBox1.Location = new System.Drawing.Point(568, 31);\r\n            this.pictureBox1.Name = \"pictureBox1\";\r\n            this.pictureBox1.Size = new System.Drawing.Size(339, 435);\r\n            this.pictureBox1.TabIndex = 2;\r\n            this.pictureBox1.TabStop = false;\r\n            // \r\n            // label2\r\n            // \r\n            this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));\r\n            this.label2.AutoSize = true;\r\n            this.label2.Location = new System.Drawing.Point(25, 492);\r\n            this.label2.Name = \"label2\";\r\n            this.label2.Size = new System.Drawing.Size(479, 12);\r\n            this.label2.TabIndex = 3;\r\n            this.label2.Text = \"ShengThumbnailImageListView 是基于 ListView 实现的，并使用了独立的后台线程加载图片。\";\r\n            // \r\n            // label3\r\n            // \r\n            this.label3.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));\r\n            this.label3.AutoSize = true;\r\n            this.label3.Location = new System.Drawing.Point(25, 522);\r\n            this.label3.Name = \"label3\";\r\n            this.label3.Size = new System.Drawing.Size(11, 12);\r\n            this.label3.TabIndex = 4;\r\n            this.label3.Text = \"如果需要更高级的功能，或更加深入的定制，你可以使用 ShengImageListView\";\r\n            // \r\n            // FormShengThumbnailImageListView\r\n            // \r\n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);\r\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\r\n            this.ClientSize = new System.Drawing.Size(944, 622);\r\n            this.Controls.Add(this.label3);\r\n            this.Controls.Add(this.label2);\r\n            this.Controls.Add(this.pictureBox1);\r\n            this.Controls.Add(this.label1);\r\n            this.Controls.Add(this.shengThumbnailImageListView1);\r\n            this.Name = \"FormShengThumbnailImageListView\";\r\n            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;\r\n            this.Text = \"FormShengThumbnailImageListView\";\r\n            this.Load += new System.EventHandler(this.FormShengThumbnailImageListView_Load);\r\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();\r\n            this.ResumeLayout(false);\r\n            this.PerformLayout();\r\n\r\n        }\r\n\r\n        #endregion\r\n\r\n        private ShengThumbnailImageListView shengThumbnailImageListView1;\r\n        private System.Windows.Forms.Label label1;\r\n        private System.Windows.Forms.PictureBox pictureBox1;\r\n        private System.Windows.Forms.Label label2;\r\n        private System.Windows.Forms.Label label3;\r\n    }\r\n}"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/FormShengThumbnailImageListView.cs",
    "content": "﻿using System;\r\nusing System.Collections.Generic;\r\nusing System.ComponentModel;\r\nusing System.Data;\r\nusing System.Drawing;\r\nusing System.IO;\r\nusing System.Linq;\r\nusing System.Text;\r\nusing System.Windows.Forms;\r\n\r\nnamespace Sheng.Winform.Controls.Demo\r\n{\r\n    public partial class FormShengThumbnailImageListView : Form\r\n    {\r\n        public FormShengThumbnailImageListView()\r\n        {\r\n            InitializeComponent();\r\n        }\r\n\r\n        private void FormShengThumbnailImageListView_Load(object sender, EventArgs e)\r\n        {\r\n            string _imagesDir;\r\n            _imagesDir = Path.Combine(Application.StartupPath, \"Images\");\r\n\r\n            string[] fileList = new string[5];\r\n            fileList[0] = Path.Combine(_imagesDir, \"1.jpg\");\r\n            fileList[1] = Path.Combine(_imagesDir, \"2.jpg\");\r\n            fileList[2] = Path.Combine(_imagesDir, \"3.jpg\");\r\n            fileList[3] = Path.Combine(_imagesDir, \"4.jpg\");\r\n            fileList[4] = Path.Combine(_imagesDir, \"5.jpg\");\r\n\r\n            shengThumbnailImageListView1.LoadItems(fileList);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/FormShengThumbnailImageListView.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<root>\r\n  <!-- \r\n    Microsoft ResX Schema \r\n    \r\n    Version 2.0\r\n    \r\n    The primary goals of this format is to allow a simple XML format \r\n    that is mostly human readable. The generation and parsing of the \r\n    various data types are done through the TypeConverter classes \r\n    associated with the data types.\r\n    \r\n    Example:\r\n    \r\n    ... ado.net/XML headers & schema ...\r\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\r\n    <resheader name=\"version\">2.0</resheader>\r\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\r\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\r\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\r\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\r\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\r\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\r\n    </data>\r\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\r\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\r\n        <comment>This is a comment</comment>\r\n    </data>\r\n                \r\n    There are any number of \"resheader\" rows that contain simple \r\n    name/value pairs.\r\n    \r\n    Each data row contains a name, and value. The row also contains a \r\n    type or mimetype. Type corresponds to a .NET class that support \r\n    text/value conversion through the TypeConverter architecture. \r\n    Classes that don't support this are serialized and stored with the \r\n    mimetype set.\r\n    \r\n    The mimetype is used for serialized objects, and tells the \r\n    ResXResourceReader how to depersist the object. This is currently not \r\n    extensible. For a given mimetype the value must be set accordingly:\r\n    \r\n    Note - application/x-microsoft.net.object.binary.base64 is the format \r\n    that the ResXResourceWriter will generate, however the reader can \r\n    read any of the formats listed below.\r\n    \r\n    mimetype: application/x-microsoft.net.object.binary.base64\r\n    value   : The object must be serialized with \r\n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\r\n            : and then encoded with base64 encoding.\r\n    \r\n    mimetype: application/x-microsoft.net.object.soap.base64\r\n    value   : The object must be serialized with \r\n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\r\n            : and then encoded with base64 encoding.\r\n\r\n    mimetype: application/x-microsoft.net.object.bytearray.base64\r\n    value   : The object must be serialized into a byte array \r\n            : using a System.ComponentModel.TypeConverter\r\n            : and then encoded with base64 encoding.\r\n    -->\r\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\r\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\r\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\r\n      <xsd:complexType>\r\n        <xsd:choice maxOccurs=\"unbounded\">\r\n          <xsd:element name=\"metadata\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\r\n              <xsd:attribute ref=\"xml:space\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"assembly\">\r\n            <xsd:complexType>\r\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"data\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\r\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\r\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\r\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\r\n              <xsd:attribute ref=\"xml:space\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"resheader\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n        </xsd:choice>\r\n      </xsd:complexType>\r\n    </xsd:element>\r\n  </xsd:schema>\r\n  <resheader name=\"resmimetype\">\r\n    <value>text/microsoft-resx</value>\r\n  </resheader>\r\n  <resheader name=\"version\">\r\n    <value>2.0</value>\r\n  </resheader>\r\n  <resheader name=\"reader\">\r\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r\n  </resheader>\r\n  <resheader name=\"writer\">\r\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r\n  </resheader>\r\n</root>"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/FormShengTreeView.Designer.cs",
    "content": "﻿namespace Sheng.Winform.Controls.Demo\r\n{\r\n    partial class FormShengTreeView\r\n    {\r\n        /// <summary>\r\n        /// Required designer variable.\r\n        /// </summary>\r\n        private System.ComponentModel.IContainer components = null;\r\n\r\n        /// <summary>\r\n        /// Clean up any resources being used.\r\n        /// </summary>\r\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\r\n        protected override void Dispose(bool disposing)\r\n        {\r\n            if (disposing && (components != null))\r\n            {\r\n                components.Dispose();\r\n            }\r\n            base.Dispose(disposing);\r\n        }\r\n\r\n        #region Windows Form Designer generated code\r\n\r\n        /// <summary>\r\n        /// Required method for Designer support - do not modify\r\n        /// the contents of this method with the code editor.\r\n        /// </summary>\r\n        private void InitializeComponent()\r\n        {\r\n            System.Windows.Forms.TreeNode treeNode1 = new System.Windows.Forms.TreeNode(\"节点1\");\r\n            System.Windows.Forms.TreeNode treeNode2 = new System.Windows.Forms.TreeNode(\"节点2\");\r\n            System.Windows.Forms.TreeNode treeNode3 = new System.Windows.Forms.TreeNode(\"节点3\");\r\n            System.Windows.Forms.TreeNode treeNode4 = new System.Windows.Forms.TreeNode(\"节点0\", new System.Windows.Forms.TreeNode[] {\r\n            treeNode1,\r\n            treeNode2,\r\n            treeNode3});\r\n            System.Windows.Forms.TreeNode treeNode5 = new System.Windows.Forms.TreeNode(\"节点5\");\r\n            System.Windows.Forms.TreeNode treeNode6 = new System.Windows.Forms.TreeNode(\"节点6\");\r\n            System.Windows.Forms.TreeNode treeNode7 = new System.Windows.Forms.TreeNode(\"节点4\", new System.Windows.Forms.TreeNode[] {\r\n            treeNode5,\r\n            treeNode6});\r\n            this.shengTreeView1 = new Sheng.Winform.Controls.ShengTreeView();\r\n            this.pictureBox1 = new System.Windows.Forms.PictureBox();\r\n            this.label1 = new System.Windows.Forms.Label();\r\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();\r\n            this.SuspendLayout();\r\n            // \r\n            // shengTreeView1\r\n            // \r\n            this.shengTreeView1.CanDragFunc = null;\r\n            this.shengTreeView1.CanDropFunc = null;\r\n            this.shengTreeView1.DragDropAction = null;\r\n            this.shengTreeView1.HotTracking = true;\r\n            this.shengTreeView1.Location = new System.Drawing.Point(38, 25);\r\n            this.shengTreeView1.Name = \"shengTreeView1\";\r\n            treeNode1.Name = \"节点1\";\r\n            treeNode1.Text = \"节点1\";\r\n            treeNode2.Name = \"节点2\";\r\n            treeNode2.Text = \"节点2\";\r\n            treeNode3.Name = \"节点3\";\r\n            treeNode3.Text = \"节点3\";\r\n            treeNode4.Name = \"节点0\";\r\n            treeNode4.Text = \"节点0\";\r\n            treeNode5.Name = \"节点5\";\r\n            treeNode5.Text = \"节点5\";\r\n            treeNode6.Name = \"节点6\";\r\n            treeNode6.Text = \"节点6\";\r\n            treeNode7.Name = \"节点4\";\r\n            treeNode7.Text = \"节点4\";\r\n            this.shengTreeView1.Nodes.AddRange(new System.Windows.Forms.TreeNode[] {\r\n            treeNode4,\r\n            treeNode7});\r\n            this.shengTreeView1.ShowLines = false;\r\n            this.shengTreeView1.Size = new System.Drawing.Size(232, 265);\r\n            this.shengTreeView1.TabIndex = 0;\r\n            // \r\n            // pictureBox1\r\n            // \r\n            this.pictureBox1.Image = global::Sheng.Winform.Controls.Demo.Resource1._12;\r\n            this.pictureBox1.Location = new System.Drawing.Point(337, 25);\r\n            this.pictureBox1.Name = \"pictureBox1\";\r\n            this.pictureBox1.Size = new System.Drawing.Size(328, 273);\r\n            this.pictureBox1.TabIndex = 1;\r\n            this.pictureBox1.TabStop = false;\r\n            // \r\n            // label1\r\n            // \r\n            this.label1.AutoSize = true;\r\n            this.label1.Location = new System.Drawing.Point(36, 327);\r\n            this.label1.Name = \"label1\";\r\n            this.label1.Size = new System.Drawing.Size(629, 12);\r\n            this.label1.TabIndex = 2;\r\n            this.label1.Text = \"ShengTreeView 是对原生 TreeView 的扩展，使其能够支持 支持Win7/Vista外观 风格的外观，以及节点的拖放操作。\";\r\n            // \r\n            // FormShengTreeView\r\n            // \r\n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);\r\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\r\n            this.ClientSize = new System.Drawing.Size(720, 411);\r\n            this.Controls.Add(this.label1);\r\n            this.Controls.Add(this.pictureBox1);\r\n            this.Controls.Add(this.shengTreeView1);\r\n            this.Name = \"FormShengTreeView\";\r\n            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;\r\n            this.Text = \"FormShengTreeView\";\r\n            this.Load += new System.EventHandler(this.FormShengTreeView_Load);\r\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();\r\n            this.ResumeLayout(false);\r\n            this.PerformLayout();\r\n\r\n        }\r\n\r\n        #endregion\r\n\r\n        private ShengTreeView shengTreeView1;\r\n        private System.Windows.Forms.PictureBox pictureBox1;\r\n        private System.Windows.Forms.Label label1;\r\n    }\r\n}"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/FormShengTreeView.cs",
    "content": "﻿using System;\r\nusing System.Collections.Generic;\r\nusing System.ComponentModel;\r\nusing System.Data;\r\nusing System.Drawing;\r\nusing System.Linq;\r\nusing System.Text;\r\nusing System.Windows.Forms;\r\n\r\nnamespace Sheng.Winform.Controls.Demo\r\n{\r\n    public partial class FormShengTreeView : Form\r\n    {\r\n        public FormShengTreeView()\r\n        {\r\n            InitializeComponent();\r\n        }\r\n\r\n        private void FormShengTreeView_Load(object sender, EventArgs e)\r\n        {\r\n            shengTreeView1.AllowDrop = true;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/FormShengTreeView.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<root>\r\n  <!-- \r\n    Microsoft ResX Schema \r\n    \r\n    Version 2.0\r\n    \r\n    The primary goals of this format is to allow a simple XML format \r\n    that is mostly human readable. The generation and parsing of the \r\n    various data types are done through the TypeConverter classes \r\n    associated with the data types.\r\n    \r\n    Example:\r\n    \r\n    ... ado.net/XML headers & schema ...\r\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\r\n    <resheader name=\"version\">2.0</resheader>\r\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\r\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\r\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\r\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\r\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\r\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\r\n    </data>\r\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\r\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\r\n        <comment>This is a comment</comment>\r\n    </data>\r\n                \r\n    There are any number of \"resheader\" rows that contain simple \r\n    name/value pairs.\r\n    \r\n    Each data row contains a name, and value. The row also contains a \r\n    type or mimetype. Type corresponds to a .NET class that support \r\n    text/value conversion through the TypeConverter architecture. \r\n    Classes that don't support this are serialized and stored with the \r\n    mimetype set.\r\n    \r\n    The mimetype is used for serialized objects, and tells the \r\n    ResXResourceReader how to depersist the object. This is currently not \r\n    extensible. For a given mimetype the value must be set accordingly:\r\n    \r\n    Note - application/x-microsoft.net.object.binary.base64 is the format \r\n    that the ResXResourceWriter will generate, however the reader can \r\n    read any of the formats listed below.\r\n    \r\n    mimetype: application/x-microsoft.net.object.binary.base64\r\n    value   : The object must be serialized with \r\n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\r\n            : and then encoded with base64 encoding.\r\n    \r\n    mimetype: application/x-microsoft.net.object.soap.base64\r\n    value   : The object must be serialized with \r\n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\r\n            : and then encoded with base64 encoding.\r\n\r\n    mimetype: application/x-microsoft.net.object.bytearray.base64\r\n    value   : The object must be serialized into a byte array \r\n            : using a System.ComponentModel.TypeConverter\r\n            : and then encoded with base64 encoding.\r\n    -->\r\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\r\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\r\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\r\n      <xsd:complexType>\r\n        <xsd:choice maxOccurs=\"unbounded\">\r\n          <xsd:element name=\"metadata\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\r\n              <xsd:attribute ref=\"xml:space\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"assembly\">\r\n            <xsd:complexType>\r\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"data\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\r\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\r\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\r\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\r\n              <xsd:attribute ref=\"xml:space\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"resheader\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n        </xsd:choice>\r\n      </xsd:complexType>\r\n    </xsd:element>\r\n  </xsd:schema>\r\n  <resheader name=\"resmimetype\">\r\n    <value>text/microsoft-resx</value>\r\n  </resheader>\r\n  <resheader name=\"version\">\r\n    <value>2.0</value>\r\n  </resheader>\r\n  <resheader name=\"reader\">\r\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r\n  </resheader>\r\n  <resheader name=\"writer\">\r\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r\n  </resheader>\r\n</root>"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/MainToolStripPanel.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Drawing.Drawing2D;\nusing System.Drawing;\nusing System.Windows.Forms;\r\n\r\nnamespace Sheng.Winform.Controls.Demo\n{\n    /// <summary>\n    /// 主工具栏容器\n    /// 重画背景\n    /// </summary>\n    class MainToolStripPanel : ToolStripPanel\n    {\n        protected override void OnPaintBackground(System.Windows.Forms.PaintEventArgs e)\n        {\n            using (LinearGradientBrush brush = new LinearGradientBrush(\n                 new Rectangle(0, 0, this.Width > 0 ? this.Width : 1, this.Height > 0 ? this.Height : 1), Color.White, Color.FromArgb(244, 247, 252), LinearGradientMode.Vertical))\n            {\n                e.Graphics.FillRectangle(brush, this.ClientRectangle);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/Program.cs",
    "content": "﻿using System;\r\nusing System.Collections.Generic;\r\nusing System.Linq;\r\nusing System.Windows.Forms;\r\n\r\nnamespace Sheng.Winform.Controls.Demo\r\n{\r\n    static class Program\r\n    {\r\n        /// <summary>\r\n        /// 应用程序的主入口点。\r\n        /// </summary>\r\n        [STAThread]\r\n        static void Main()\r\n        {\r\n            Application.EnableVisualStyles();\r\n            Application.SetCompatibleTextRenderingDefault(false);\r\n            Application.Run(new Form1());\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\r\nusing System.Runtime.CompilerServices;\r\nusing System.Runtime.InteropServices;\r\n\r\n// 有关程序集的一般信息由以下\r\n// 控制。更改这些特性值可修改\r\n// 与程序集关联的信息。\r\n[assembly: AssemblyTitle(\"Sheng.Winform.Controls.Demo\")]\r\n[assembly: AssemblyDescription(\"\")]\r\n[assembly: AssemblyConfiguration(\"\")]\r\n[assembly: AssemblyCompany(\"\")]\r\n[assembly: AssemblyProduct(\"Sheng.Winform.Controls.Demo\")]\r\n[assembly: AssemblyCopyright(\"Copyright ©  2017\")]\r\n[assembly: AssemblyTrademark(\"\")]\r\n[assembly: AssemblyCulture(\"\")]\r\n\r\n//将 ComVisible 设置为 false 将使此程序集中的类型\r\n//对 COM 组件不可见。  如果需要从 COM 访问此程序集中的类型，\r\n//请将此类型的 ComVisible 特性设置为 true。\r\n[assembly: ComVisible(false)]\r\n\r\n// 如果此项目向 COM 公开，则下列 GUID 用于类型库的 ID\r\n[assembly: Guid(\"8db4a7cc-c631-45bd-bb94-1bc9cf686609\")]\r\n\r\n// 程序集的版本信息由下列四个值组成: \r\n//\r\n//      主版本\r\n//      次版本\r\n//      生成号\r\n//      修订号\r\n//\r\n//可以指定所有这些值，也可以使用“生成号”和“修订号”的默认值，\r\n// 方法是按如下所示使用“*”: :\r\n// [assembly: AssemblyVersion(\"1.0.*\")]\r\n[assembly: AssemblyVersion(\"1.0.0.0\")]\r\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\r\n"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/Properties/Resources.Designer.cs",
    "content": "﻿//------------------------------------------------------------------------------\r\n// <auto-generated>\r\n//     此代码由工具生成。\r\n//     运行时版本: 4.0.30319.42000\r\n//\r\n//     对此文件的更改可能导致不正确的行为，如果\r\n//     重新生成代码，则所做更改将丢失。\r\n// </auto-generated>\r\n//------------------------------------------------------------------------------\r\n\r\nnamespace Sheng.Winform.Controls.Demo.Properties\r\n{\r\n\r\n\r\n    /// <summary>\r\n    ///   强类型资源类，用于查找本地化字符串等。\r\n    /// </summary>\r\n    // 此类是由 StronglyTypedResourceBuilder\r\n    // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。\r\n    // 若要添加或删除成员，请编辑 .ResX 文件，然后重新运行 ResGen\r\n    // (以 /str 作为命令选项)，或重新生成 VS 项目。\r\n    [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Resources.Tools.StronglyTypedResourceBuilder\", \"4.0.0.0\")]\r\n    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\r\n    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]\r\n    internal class Resources\r\n    {\r\n\r\n        private static global::System.Resources.ResourceManager resourceMan;\r\n\r\n        private static global::System.Globalization.CultureInfo resourceCulture;\r\n\r\n        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"Microsoft.Performance\", \"CA1811:AvoidUncalledPrivateCode\")]\r\n        internal Resources()\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        ///   返回此类使用的缓存 ResourceManager 实例。\r\n        /// </summary>\r\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\r\n        internal static global::System.Resources.ResourceManager ResourceManager\r\n        {\r\n            get\r\n            {\r\n                if ((resourceMan == null))\r\n                {\r\n                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager(\"Sheng.Winform.Controls.Demo.Properties.Resources\", typeof(Resources).Assembly);\r\n                    resourceMan = temp;\r\n                }\r\n                return resourceMan;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        ///   覆盖当前线程的 CurrentUICulture 属性\r\n        ///   使用此强类型的资源类的资源查找。\r\n        /// </summary>\r\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\r\n        internal static global::System.Globalization.CultureInfo Culture\r\n        {\r\n            get\r\n            {\r\n                return resourceCulture;\r\n            }\r\n            set\r\n            {\r\n                resourceCulture = value;\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/Properties/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<root>\r\n  <!-- \r\n    Microsoft ResX Schema \r\n    \r\n    Version 2.0\r\n    \r\n    The primary goals of this format is to allow a simple XML format \r\n    that is mostly human readable. The generation and parsing of the \r\n    various data types are done through the TypeConverter classes \r\n    associated with the data types.\r\n    \r\n    Example:\r\n    \r\n    ... ado.net/XML headers & schema ...\r\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\r\n    <resheader name=\"version\">2.0</resheader>\r\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\r\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\r\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\r\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\r\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\r\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\r\n    </data>\r\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\r\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\r\n        <comment>This is a comment</comment>\r\n    </data>\r\n                \r\n    There are any number of \"resheader\" rows that contain simple \r\n    name/value pairs.\r\n    \r\n    Each data row contains a name, and value. The row also contains a \r\n    type or mimetype. Type corresponds to a .NET class that support \r\n    text/value conversion through the TypeConverter architecture. \r\n    Classes that don't support this are serialized and stored with the \r\n    mimetype set.\r\n    \r\n    The mimetype is used for serialized objects, and tells the \r\n    ResXResourceReader how to depersist the object. This is currently not \r\n    extensible. For a given mimetype the value must be set accordingly:\r\n    \r\n    Note - application/x-microsoft.net.object.binary.base64 is the format \r\n    that the ResXResourceWriter will generate, however the reader can \r\n    read any of the formats listed below.\r\n    \r\n    mimetype: application/x-microsoft.net.object.binary.base64\r\n    value   : The object must be serialized with \r\n            : System.Serialization.Formatters.Binary.BinaryFormatter\r\n            : and then encoded with base64 encoding.\r\n    \r\n    mimetype: application/x-microsoft.net.object.soap.base64\r\n    value   : The object must be serialized with \r\n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\r\n            : and then encoded with base64 encoding.\r\n\r\n    mimetype: application/x-microsoft.net.object.bytearray.base64\r\n    value   : The object must be serialized into a byte array \r\n            : using a System.ComponentModel.TypeConverter\r\n            : and then encoded with base64 encoding.\r\n    -->\r\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\r\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\r\n      <xsd:complexType>\r\n        <xsd:choice maxOccurs=\"unbounded\">\r\n          <xsd:element name=\"metadata\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"assembly\">\r\n            <xsd:complexType>\r\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"data\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\r\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" msdata:Ordinal=\"1\" />\r\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\r\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"resheader\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n        </xsd:choice>\r\n      </xsd:complexType>\r\n    </xsd:element>\r\n  </xsd:schema>\r\n  <resheader name=\"resmimetype\">\r\n    <value>text/microsoft-resx</value>\r\n  </resheader>\r\n  <resheader name=\"version\">\r\n    <value>2.0</value>\r\n  </resheader>\r\n  <resheader name=\"reader\">\r\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r\n  </resheader>\r\n  <resheader name=\"writer\">\r\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r\n  </resheader>\r\n</root>"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/Properties/Settings.Designer.cs",
    "content": "﻿//------------------------------------------------------------------------------\r\n// <auto-generated>\r\n//     This code was generated by a tool.\r\n//     Runtime Version:4.0.30319.42000\r\n//\r\n//     Changes to this file may cause incorrect behavior and will be lost if\r\n//     the code is regenerated.\r\n// </auto-generated>\r\n//------------------------------------------------------------------------------\r\n\r\nnamespace Sheng.Winform.Controls.Demo.Properties\r\n{\r\n\r\n\r\n    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]\r\n    [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator\", \"11.0.0.0\")]\r\n    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase\r\n    {\r\n\r\n        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));\r\n\r\n        public static Settings Default\r\n        {\r\n            get\r\n            {\r\n                return defaultInstance;\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/Properties/Settings.settings",
    "content": "﻿<?xml version='1.0' encoding='utf-8'?>\r\n<SettingsFile xmlns=\"http://schemas.microsoft.com/VisualStudio/2004/01/settings\" CurrentProfile=\"(Default)\">\r\n  <Profiles>\r\n    <Profile Name=\"(Default)\" />\r\n  </Profiles>\r\n  <Settings />\r\n</SettingsFile>\r\n"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/Resource1.Designer.cs",
    "content": "﻿//------------------------------------------------------------------------------\r\n// <auto-generated>\r\n//     此代码由工具生成。\r\n//     运行时版本:4.0.30319.42000\r\n//\r\n//     对此文件的更改可能会导致不正确的行为，并且如果\r\n//     重新生成代码，这些更改将会丢失。\r\n// </auto-generated>\r\n//------------------------------------------------------------------------------\r\n\r\nnamespace Sheng.Winform.Controls.Demo {\r\n    using System;\r\n    \r\n    \r\n    /// <summary>\r\n    ///   一个强类型的资源类，用于查找本地化的字符串等。\r\n    /// </summary>\r\n    // 此类是由 StronglyTypedResourceBuilder\r\n    // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。\r\n    // 若要添加或移除成员，请编辑 .ResX 文件，然后重新运行 ResGen\r\n    // (以 /str 作为命令选项)，或重新生成 VS 项目。\r\n    [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Resources.Tools.StronglyTypedResourceBuilder\", \"4.0.0.0\")]\r\n    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\r\n    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]\r\n    internal class Resource1 {\r\n        \r\n        private static global::System.Resources.ResourceManager resourceMan;\r\n        \r\n        private static global::System.Globalization.CultureInfo resourceCulture;\r\n        \r\n        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"Microsoft.Performance\", \"CA1811:AvoidUncalledPrivateCode\")]\r\n        internal Resource1() {\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   返回此类使用的缓存的 ResourceManager 实例。\r\n        /// </summary>\r\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\r\n        internal static global::System.Resources.ResourceManager ResourceManager {\r\n            get {\r\n                if (object.ReferenceEquals(resourceMan, null)) {\r\n                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager(\"Sheng.Winform.Controls.Demo.Resource1\", typeof(Resource1).Assembly);\r\n                    resourceMan = temp;\r\n                }\r\n                return resourceMan;\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   使用此强类型资源类，为所有资源查找\r\n        ///   重写当前线程的 CurrentUICulture 属性。\r\n        /// </summary>\r\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\r\n        internal static global::System.Globalization.CultureInfo Culture {\r\n            get {\r\n                return resourceCulture;\r\n            }\r\n            set {\r\n                resourceCulture = value;\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\r\n        /// </summary>\r\n        internal static System.Drawing.Bitmap _1 {\r\n            get {\r\n                object obj = ResourceManager.GetObject(\"1\", resourceCulture);\r\n                return ((System.Drawing.Bitmap)(obj));\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\r\n        /// </summary>\r\n        internal static System.Drawing.Bitmap _10 {\r\n            get {\r\n                object obj = ResourceManager.GetObject(\"10\", resourceCulture);\r\n                return ((System.Drawing.Bitmap)(obj));\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\r\n        /// </summary>\r\n        internal static System.Drawing.Bitmap _11 {\r\n            get {\r\n                object obj = ResourceManager.GetObject(\"11\", resourceCulture);\r\n                return ((System.Drawing.Bitmap)(obj));\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\r\n        /// </summary>\r\n        internal static System.Drawing.Bitmap _12 {\r\n            get {\r\n                object obj = ResourceManager.GetObject(\"12\", resourceCulture);\r\n                return ((System.Drawing.Bitmap)(obj));\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\r\n        /// </summary>\r\n        internal static System.Drawing.Bitmap _13 {\r\n            get {\r\n                object obj = ResourceManager.GetObject(\"13\", resourceCulture);\r\n                return ((System.Drawing.Bitmap)(obj));\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\r\n        /// </summary>\r\n        internal static System.Drawing.Bitmap _2 {\r\n            get {\r\n                object obj = ResourceManager.GetObject(\"2\", resourceCulture);\r\n                return ((System.Drawing.Bitmap)(obj));\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\r\n        /// </summary>\r\n        internal static System.Drawing.Bitmap _3 {\r\n            get {\r\n                object obj = ResourceManager.GetObject(\"3\", resourceCulture);\r\n                return ((System.Drawing.Bitmap)(obj));\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\r\n        /// </summary>\r\n        internal static System.Drawing.Bitmap _4 {\r\n            get {\r\n                object obj = ResourceManager.GetObject(\"4\", resourceCulture);\r\n                return ((System.Drawing.Bitmap)(obj));\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\r\n        /// </summary>\r\n        internal static System.Drawing.Bitmap _5 {\r\n            get {\r\n                object obj = ResourceManager.GetObject(\"5\", resourceCulture);\r\n                return ((System.Drawing.Bitmap)(obj));\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\r\n        /// </summary>\r\n        internal static System.Drawing.Bitmap _6 {\r\n            get {\r\n                object obj = ResourceManager.GetObject(\"6\", resourceCulture);\r\n                return ((System.Drawing.Bitmap)(obj));\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\r\n        /// </summary>\r\n        internal static System.Drawing.Bitmap _7 {\r\n            get {\r\n                object obj = ResourceManager.GetObject(\"7\", resourceCulture);\r\n                return ((System.Drawing.Bitmap)(obj));\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\r\n        /// </summary>\r\n        internal static System.Drawing.Bitmap _8 {\r\n            get {\r\n                object obj = ResourceManager.GetObject(\"8\", resourceCulture);\r\n                return ((System.Drawing.Bitmap)(obj));\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\r\n        /// </summary>\r\n        internal static System.Drawing.Bitmap _9 {\r\n            get {\r\n                object obj = ResourceManager.GetObject(\"9\", resourceCulture);\r\n                return ((System.Drawing.Bitmap)(obj));\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\r\n        /// </summary>\r\n        internal static System.Drawing.Bitmap Browser_Home {\r\n            get {\r\n                object obj = ResourceManager.GetObject(\"Browser_Home\", resourceCulture);\r\n                return ((System.Drawing.Bitmap)(obj));\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/Resource1.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<root>\r\n  <!-- \r\n    Microsoft ResX Schema \r\n    \r\n    Version 2.0\r\n    \r\n    The primary goals of this format is to allow a simple XML format \r\n    that is mostly human readable. The generation and parsing of the \r\n    various data types are done through the TypeConverter classes \r\n    associated with the data types.\r\n    \r\n    Example:\r\n    \r\n    ... ado.net/XML headers & schema ...\r\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\r\n    <resheader name=\"version\">2.0</resheader>\r\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\r\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\r\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\r\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\r\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\r\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\r\n    </data>\r\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\r\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\r\n        <comment>This is a comment</comment>\r\n    </data>\r\n                \r\n    There are any number of \"resheader\" rows that contain simple \r\n    name/value pairs.\r\n    \r\n    Each data row contains a name, and value. The row also contains a \r\n    type or mimetype. Type corresponds to a .NET class that support \r\n    text/value conversion through the TypeConverter architecture. \r\n    Classes that don't support this are serialized and stored with the \r\n    mimetype set.\r\n    \r\n    The mimetype is used for serialized objects, and tells the \r\n    ResXResourceReader how to depersist the object. This is currently not \r\n    extensible. For a given mimetype the value must be set accordingly:\r\n    \r\n    Note - application/x-microsoft.net.object.binary.base64 is the format \r\n    that the ResXResourceWriter will generate, however the reader can \r\n    read any of the formats listed below.\r\n    \r\n    mimetype: application/x-microsoft.net.object.binary.base64\r\n    value   : The object must be serialized with \r\n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\r\n            : and then encoded with base64 encoding.\r\n    \r\n    mimetype: application/x-microsoft.net.object.soap.base64\r\n    value   : The object must be serialized with \r\n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\r\n            : and then encoded with base64 encoding.\r\n\r\n    mimetype: application/x-microsoft.net.object.bytearray.base64\r\n    value   : The object must be serialized into a byte array \r\n            : using a System.ComponentModel.TypeConverter\r\n            : and then encoded with base64 encoding.\r\n    -->\r\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\r\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\r\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\r\n      <xsd:complexType>\r\n        <xsd:choice maxOccurs=\"unbounded\">\r\n          <xsd:element name=\"metadata\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\r\n              <xsd:attribute ref=\"xml:space\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"assembly\">\r\n            <xsd:complexType>\r\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"data\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\r\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\r\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\r\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\r\n              <xsd:attribute ref=\"xml:space\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"resheader\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n        </xsd:choice>\r\n      </xsd:complexType>\r\n    </xsd:element>\r\n  </xsd:schema>\r\n  <resheader name=\"resmimetype\">\r\n    <value>text/microsoft-resx</value>\r\n  </resheader>\r\n  <resheader name=\"version\">\r\n    <value>2.0</value>\r\n  </resheader>\r\n  <resheader name=\"reader\">\r\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r\n  </resheader>\r\n  <resheader name=\"writer\">\r\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r\n  </resheader>\r\n  <assembly alias=\"System.Windows.Forms\" name=\"System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\" />\r\n  <data name=\"3\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\r\n    <value>Resources\\3.PNG;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\r\n  </data>\r\n  <data name=\"5\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\r\n    <value>Resources\\5.PNG;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\r\n  </data>\r\n  <data name=\"12\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\r\n    <value>Resources\\12.PNG;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\r\n  </data>\r\n  <data name=\"10\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\r\n    <value>Resources\\10.PNG;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\r\n  </data>\r\n  <data name=\"2\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\r\n    <value>Resources\\2.PNG;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\r\n  </data>\r\n  <data name=\"8\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\r\n    <value>Resources\\8.PNG;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\r\n  </data>\r\n  <data name=\"Browser_Home\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\r\n    <value>Resources\\Browser_Home.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\r\n  </data>\r\n  <data name=\"11\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\r\n    <value>Resources\\11.PNG;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\r\n  </data>\r\n  <data name=\"1\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\r\n    <value>Resources\\1.PNG;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\r\n  </data>\r\n  <data name=\"9\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\r\n    <value>Resources\\9.PNG;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\r\n  </data>\r\n  <data name=\"7\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\r\n    <value>Resources\\7.PNG;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\r\n  </data>\r\n  <data name=\"6\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\r\n    <value>Resources\\6.PNG;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\r\n  </data>\r\n  <data name=\"4\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\r\n    <value>Resources\\4.PNG;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\r\n  </data>\r\n  <assembly alias=\"System.Windows.Forms\" name=\"System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\" />\r\n  <data name=\"13\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\r\n    <value>Resources\\13.PNG;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\r\n  </data>\r\n</root>"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/Sheng.Winform.Controls.Demo.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"14.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\r\n  <PropertyGroup>\r\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\r\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\r\n    <ProjectGuid>{8DB4A7CC-C631-45BD-BB94-1BC9CF686609}</ProjectGuid>\r\n    <OutputType>WinExe</OutputType>\r\n    <AppDesignerFolder>Properties</AppDesignerFolder>\r\n    <RootNamespace>Sheng.Winform.Controls.Demo</RootNamespace>\r\n    <AssemblyName>Sheng.Winform.Controls.Demo</AssemblyName>\r\n    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>\r\n    <FileAlignment>512</FileAlignment>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\r\n    <PlatformTarget>AnyCPU</PlatformTarget>\r\n    <DebugSymbols>true</DebugSymbols>\r\n    <DebugType>full</DebugType>\r\n    <Optimize>false</Optimize>\r\n    <OutputPath>bin\\Debug\\</OutputPath>\r\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\r\n    <ErrorReport>prompt</ErrorReport>\r\n    <WarningLevel>4</WarningLevel>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\r\n    <PlatformTarget>AnyCPU</PlatformTarget>\r\n    <DebugType>pdbonly</DebugType>\r\n    <Optimize>true</Optimize>\r\n    <OutputPath>bin\\Release\\</OutputPath>\r\n    <DefineConstants>TRACE</DefineConstants>\r\n    <ErrorReport>prompt</ErrorReport>\r\n    <WarningLevel>4</WarningLevel>\r\n  </PropertyGroup>\r\n  <ItemGroup>\r\n    <Reference Include=\"System\" />\r\n    <Reference Include=\"System.Core\" />\r\n    <Reference Include=\"System.Xml.Linq\" />\r\n    <Reference Include=\"System.Data.DataSetExtensions\" />\r\n    <Reference Include=\"System.Data\" />\r\n    <Reference Include=\"System.Deployment\" />\r\n    <Reference Include=\"System.Drawing\" />\r\n    <Reference Include=\"System.Windows.Forms\" />\r\n    <Reference Include=\"System.Xml\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <Compile Include=\"Form1.cs\">\r\n      <SubType>Form</SubType>\r\n    </Compile>\r\n    <Compile Include=\"Form1.Designer.cs\">\r\n      <DependentUpon>Form1.cs</DependentUpon>\r\n    </Compile>\r\n    <Compile Include=\"FormMisc.cs\">\r\n      <SubType>Form</SubType>\r\n    </Compile>\r\n    <Compile Include=\"FormMisc.Designer.cs\">\r\n      <DependentUpon>FormMisc.cs</DependentUpon>\r\n    </Compile>\r\n    <Compile Include=\"FormShengAdressBar.cs\">\r\n      <SubType>Form</SubType>\r\n    </Compile>\r\n    <Compile Include=\"FormShengAdressBar.Designer.cs\">\r\n      <DependentUpon>FormShengAdressBar.cs</DependentUpon>\r\n    </Compile>\r\n    <Compile Include=\"FormShengComboSelector.cs\">\r\n      <SubType>Form</SubType>\r\n    </Compile>\r\n    <Compile Include=\"FormShengComboSelector.Designer.cs\">\r\n      <DependentUpon>FormShengComboSelector.cs</DependentUpon>\r\n    </Compile>\r\n    <Compile Include=\"FormShengComboSelector2.cs\">\r\n      <SubType>Form</SubType>\r\n    </Compile>\r\n    <Compile Include=\"FormShengComboSelector2.Designer.cs\">\r\n      <DependentUpon>FormShengComboSelector2.cs</DependentUpon>\r\n    </Compile>\r\n    <Compile Include=\"FormShengDataGridView.cs\">\r\n      <SubType>Form</SubType>\r\n    </Compile>\r\n    <Compile Include=\"FormShengDataGridView.Designer.cs\">\r\n      <DependentUpon>FormShengDataGridView.cs</DependentUpon>\r\n    </Compile>\r\n    <Compile Include=\"FormShengImageListView.cs\">\r\n      <SubType>Form</SubType>\r\n    </Compile>\r\n    <Compile Include=\"FormShengImageListView.Designer.cs\">\r\n      <DependentUpon>FormShengImageListView.cs</DependentUpon>\r\n    </Compile>\r\n    <Compile Include=\"FormShengListView.cs\">\r\n      <SubType>Form</SubType>\r\n    </Compile>\r\n    <Compile Include=\"FormShengListView.Designer.cs\">\r\n      <DependentUpon>FormShengListView.cs</DependentUpon>\r\n    </Compile>\r\n    <Compile Include=\"FormShengThumbnailImageListView.cs\">\r\n      <SubType>Form</SubType>\r\n    </Compile>\r\n    <Compile Include=\"FormShengThumbnailImageListView.Designer.cs\">\r\n      <DependentUpon>FormShengThumbnailImageListView.cs</DependentUpon>\r\n    </Compile>\r\n    <Compile Include=\"FormShengTreeView.cs\">\r\n      <SubType>Form</SubType>\r\n    </Compile>\r\n    <Compile Include=\"FormShengTreeView.Designer.cs\">\r\n      <DependentUpon>FormShengTreeView.cs</DependentUpon>\r\n    </Compile>\r\n    <Compile Include=\"MainToolStripPanel.cs\">\r\n      <SubType>Component</SubType>\r\n    </Compile>\r\n    <Compile Include=\"Program.cs\" />\r\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\r\n    <Compile Include=\"Resource1.Designer.cs\">\r\n      <AutoGen>True</AutoGen>\r\n      <DesignTime>True</DesignTime>\r\n      <DependentUpon>Resource1.resx</DependentUpon>\r\n    </Compile>\r\n    <Compile Include=\"StartPageCodePage.cs\" />\r\n    <Compile Include=\"StartPageScheme.cs\" />\r\n    <Compile Include=\"TestListViewItem.cs\" />\r\n    <EmbeddedResource Include=\"Form1.resx\">\r\n      <DependentUpon>Form1.cs</DependentUpon>\r\n    </EmbeddedResource>\r\n    <EmbeddedResource Include=\"FormMisc.resx\">\r\n      <DependentUpon>FormMisc.cs</DependentUpon>\r\n    </EmbeddedResource>\r\n    <EmbeddedResource Include=\"FormShengAdressBar.resx\">\r\n      <DependentUpon>FormShengAdressBar.cs</DependentUpon>\r\n    </EmbeddedResource>\r\n    <EmbeddedResource Include=\"FormShengComboSelector.resx\">\r\n      <DependentUpon>FormShengComboSelector.cs</DependentUpon>\r\n    </EmbeddedResource>\r\n    <EmbeddedResource Include=\"FormShengComboSelector2.resx\">\r\n      <DependentUpon>FormShengComboSelector2.cs</DependentUpon>\r\n    </EmbeddedResource>\r\n    <EmbeddedResource Include=\"FormShengDataGridView.resx\">\r\n      <DependentUpon>FormShengDataGridView.cs</DependentUpon>\r\n    </EmbeddedResource>\r\n    <EmbeddedResource Include=\"FormShengImageListView.resx\">\r\n      <DependentUpon>FormShengImageListView.cs</DependentUpon>\r\n    </EmbeddedResource>\r\n    <EmbeddedResource Include=\"FormShengListView.resx\">\r\n      <DependentUpon>FormShengListView.cs</DependentUpon>\r\n    </EmbeddedResource>\r\n    <EmbeddedResource Include=\"FormShengThumbnailImageListView.resx\">\r\n      <DependentUpon>FormShengThumbnailImageListView.cs</DependentUpon>\r\n    </EmbeddedResource>\r\n    <EmbeddedResource Include=\"FormShengTreeView.resx\">\r\n      <DependentUpon>FormShengTreeView.cs</DependentUpon>\r\n    </EmbeddedResource>\r\n    <EmbeddedResource Include=\"Properties\\Resources.resx\">\r\n      <Generator>ResXFileCodeGenerator</Generator>\r\n      <LastGenOutput>Resources.Designer.cs</LastGenOutput>\r\n      <SubType>Designer</SubType>\r\n    </EmbeddedResource>\r\n    <Compile Include=\"Properties\\Resources.Designer.cs\">\r\n      <AutoGen>True</AutoGen>\r\n      <DependentUpon>Resources.resx</DependentUpon>\r\n    </Compile>\r\n    <EmbeddedResource Include=\"Resource1.resx\">\r\n      <Generator>ResXFileCodeGenerator</Generator>\r\n      <LastGenOutput>Resource1.Designer.cs</LastGenOutput>\r\n    </EmbeddedResource>\r\n    <None Include=\"Properties\\Settings.settings\">\r\n      <Generator>SettingsSingleFileGenerator</Generator>\r\n      <LastGenOutput>Settings.Designer.cs</LastGenOutput>\r\n    </None>\r\n    <Compile Include=\"Properties\\Settings.Designer.cs\">\r\n      <AutoGen>True</AutoGen>\r\n      <DependentUpon>Settings.settings</DependentUpon>\r\n      <DesignTimeSharedInput>True</DesignTimeSharedInput>\r\n    </Compile>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ProjectReference Include=\"..\\Sheng.Winform.Controls.Drawing\\Sheng.Winform.Controls.Drawing.csproj\">\r\n      <Project>{bcd80096-7b6f-4273-a031-186a610c84e5}</Project>\r\n      <Name>Sheng.Winform.Controls.Drawing</Name>\r\n    </ProjectReference>\r\n    <ProjectReference Include=\"..\\Sheng.Winform.Controls.Kernal\\Sheng.Winform.Controls.Kernal.csproj\">\r\n      <Project>{125fb802-2c83-47dc-ba57-910064355ccd}</Project>\r\n      <Name>Sheng.Winform.Controls.Kernal</Name>\r\n    </ProjectReference>\r\n    <ProjectReference Include=\"..\\Sheng.Winform.Controls.Localisation\\Sheng.Winform.Controls.Localisation.csproj\">\r\n      <Project>{e0b8ad36-cc90-41f5-bd00-ec614569c9f9}</Project>\r\n      <Name>Sheng.Winform.Controls.Localisation</Name>\r\n    </ProjectReference>\r\n    <ProjectReference Include=\"..\\Sheng.Winform.Controls.Win32\\Sheng.Winform.Controls.Win32.csproj\">\r\n      <Project>{946ffb43-4864-4967-8d69-8716cda83f7a}</Project>\r\n      <Name>Sheng.Winform.Controls.Win32</Name>\r\n    </ProjectReference>\r\n    <ProjectReference Include=\"..\\Sheng.Winform.Controls\\Sheng.Winform.Controls.csproj\">\r\n      <Project>{8947fdae-9f4b-4d77-91aa-0704acd83dbd}</Project>\r\n      <Name>Sheng.Winform.Controls</Name>\r\n    </ProjectReference>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"Resources\\Browser_Home.png\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <Content Include=\"Images\\1.jpg\">\r\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\r\n    </Content>\r\n    <Content Include=\"Images\\2.jpg\">\r\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\r\n    </Content>\r\n    <Content Include=\"Images\\3.jpg\">\r\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\r\n    </Content>\r\n    <Content Include=\"Images\\4.jpg\">\r\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\r\n    </Content>\r\n    <Content Include=\"Images\\5.jpg\">\r\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\r\n    </Content>\r\n    <Content Include=\"Resources\\1.PNG\" />\r\n    <None Include=\"Resources\\13.PNG\" />\r\n    <None Include=\"Resources\\12.PNG\" />\r\n    <None Include=\"Resources\\11.PNG\" />\r\n    <None Include=\"Resources\\10.PNG\" />\r\n    <None Include=\"Resources\\9.PNG\" />\r\n    <None Include=\"Resources\\8.PNG\" />\r\n    <None Include=\"Resources\\7.PNG\" />\r\n    <None Include=\"Resources\\5.PNG\" />\r\n    <None Include=\"Resources\\6.PNG\" />\r\n    <None Include=\"Resources\\4.PNG\" />\r\n    <None Include=\"Resources\\3.PNG\" />\r\n    <None Include=\"Resources\\2.PNG\" />\r\n  </ItemGroup>\r\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\r\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \r\n       Other similar extension points exist, see Microsoft.Common.targets.\r\n  <Target Name=\"BeforeBuild\">\r\n  </Target>\r\n  <Target Name=\"AfterBuild\">\r\n  </Target>\r\n  -->\r\n</Project>"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/Sheng.Winform.Controls.Demo.csproj.user",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"14.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <PropertyGroup>\r\n    <ProjectView>ProjectFiles</ProjectView>\r\n  </PropertyGroup>\r\n</Project>"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/StartPageCodePage.cs",
    "content": "﻿using System;\r\nusing System.Collections.Generic;\r\nusing System.Linq;\r\nusing System.Text;\r\nusing System.IO;\r\n\r\nnamespace Sheng.Winform.Controls.Demo\r\n{\r\n    class StartPageCodePage\r\n    {\r\n        public StartPageCodePage()\r\n        {\r\n        }\r\n\r\n        public virtual void RenderHeaderSection(StringBuilder builder)\r\n        {\r\n            builder.Append(\"<!DOCTYPE HTML PUBLIC \\\"-//W3C//DTD HTML 4.01 Transitional//EN\\\" \\\"http://www.w3.org/TR/html4/loose.dtd\\\">\");\r\n            builder.Append(\"<html>\");\r\n            builder.Append(\"<head>\");\r\n            builder.Append(\"<meta http-equiv=\\\"Content-Type\\\" content=\\\"text/html; charset=utf-8\\\">\");\r\n            builder.Append(\"<title>欢迎</title>\");\r\n            //builder.Append(\"<link href=\\\"\" +\r\n            //    _environmentService.DataPath +\r\n            //    Path.DirectorySeparatorChar + \"resources\" +\r\n            //    Path.DirectorySeparatorChar + \"startpage\" +\r\n            //    Path.DirectorySeparatorChar + \"style.css\\\" rel=\\\"stylesheet\\\" type=\\\"text/css\\\">\");\r\n            builder.Append(\"</head>\");\r\n\r\n            builder.Append(\"<body style=\\\"font-size:14px;\\\">\");\r\n            builder.Append(\"<table width=\\\"100%\\\"  border=\\\"0\\\" cellspacing=\\\"0\\\" cellpadding=\\\"0\\\">\");\r\n            builder.Append(\"<tr>\");\r\n            //builder.Append(\"<td><img src=\\\"\" + _environmentService.DataPath +\r\n            //    Path.DirectorySeparatorChar + \"resources\" +\r\n            //    Path.DirectorySeparatorChar + \"startpage\" +\r\n            //    Path.DirectorySeparatorChar + \"Top.png\\\" width=\\\"672\\\" height=\\\"74\\\"></td>\");\r\n            builder.Append(\"<td width=\\\"30\\\">&nbsp;</td>\");\r\n            builder.Append(\"<td height=\\\"90\\\" style=\\\"font-size:20px;\\\">\");\r\n            builder.Append(\"升讯威 .Net WinForm 控件库<br/>\");\r\n            builder.Append(\"Sheng.WinForm.Controls<br/>\");\r\n            builder.Append(\"Github : https://github.com/iccb1013/Sheng.Winform.Controls\");\r\n            builder.Append(\"</td>\");\r\n            builder.Append(\"</tr>\");\r\n            builder.Append(\"</table>\");\r\n\r\n            builder.Append(\"<table width=\\\"100%\\\"  border=\\\"0\\\" cellspacing=\\\"0\\\" cellpadding=\\\"0\\\">\");\r\n            builder.Append(\"<tr>\");\r\n            builder.Append(\"<td width=\\\"30\\\">&nbsp;</td>\");\r\n            builder.Append(\"<td height=\\\"30\\\">\");\r\n            builder.Append(\"<a href=\\\"startpage://start/\\\">启始页</a>&nbsp;&nbsp;&nbsp;\");\r\n            builder.Append(\"<a href=\\\"startpage://help/\\\">帮助与技术支持</a>&nbsp;&nbsp;&nbsp;\");\r\n            //builder.Append(\"<a href=\\\"http://www.shengxunwei.com\\\" target=\\\"_blank\\\">网站</a>&nbsp;&nbsp;&nbsp;\");\r\n            builder.Append(\"</td>\");\r\n            builder.Append(\"</tr>\");\r\n            builder.Append(\"</table>\");\r\n\r\n           \r\n        }\r\n\r\n        public virtual void RenderSectionStartBody(StringBuilder builder)\r\n        {\r\n            builder.Append(\"<table width=\\\"100%\\\"  border=\\\"0\\\" cellspacing=\\\"0\\\" cellpadding=\\\"0\\\">\");\r\n            builder.Append(\"<tr><td colspan='2'>&nbsp;</td></tr>\");\r\n            builder.Append(\"<tr>\");\r\n            builder.Append(\"<td width=\\\"30\\\">&nbsp;</td>\");\r\n            builder.Append(\"<td>\");\r\n            builder.Append(\"升讯威 .Net WinForm 控件库 是一个开源的控件库，该控件库源于 升讯威 WinForm Designer IDE。开源的目的是为了分享 .Net Winform 控件开发的方法和理念，你可以在此开源库的基础上进行更深入的二次开发。如需商业应用，请于权版画面声明使用了本控件库，并给出 Github 地址。 <br/><br/>\");\r\n\r\n            builder.Append(\"此启始页控件，是由 WebBrowser 定制的，允许你实现一个类似 VisualStudio 一样的启始页。<br/>\");\r\n            builder.Append(\"也可以使用此控件，实现 Html 页面与客户端混合的应用程序。<br/>\");\r\n            builder.Append(\"此页面中的数据可以由 C# 程序输出，此页面中的 JavaScript 函数可以由 C# 调用，反之亦然，页面中的 JavaScript 代码可以调用 C# 代码中的函数。<br/>\");\r\n\r\n            builder.Append(\"</td>\");\r\n            builder.Append(\"</tr>\");\r\n            builder.Append(\"</table>\");\r\n\r\n            builder.Append(\"<table width=\\\"100%\\\"  border=\\\"0\\\" cellspacing=\\\"0\\\" cellpadding=\\\"0\\\">\");\r\n            builder.Append(\"<tr>\");\r\n            builder.Append(\"<td>&nbsp;</td>\");\r\n            builder.Append(\"</tr>\");\r\n            builder.Append(\"<tr>\");\r\n            builder.Append(\"<td width=\\\"30\\\"><!--这里是最近项目列表--></td>\");\r\n            builder.Append(\"<td>\");\r\n\r\n            //这里是最近项目列表\r\n\r\n            builder.Append(\"最近项目:\");\r\n            builder.Append(\"<table  width=\\\"600\\\"  border=\\\"1\\\" cellpadding=\\\"0\\\" cellspacing=\\\"0\\\" bordercolor=\\\"#CCCCCC\\\" style=\\\"border-collapse:collapse;\\\">\");\r\n            builder.Append(\"<tr bgcolor=\\\"#FAFAFA\\\">\");\r\n            builder.Append(\"<td width=\\\"180\\\" height=\\\"24\\\" bgcolor=\\\"#FAFAFA\\\">&nbsp;&nbsp;<strong>名称</strong></td>\");\r\n            builder.Append(\"<td>&nbsp;&nbsp;<strong>位置</strong></td>\");\r\n            builder.Append(\"</tr>\");\r\n\r\n\r\n            //循环部分\r\n            for (int i = 0; i < 3; i++)\r\n            {\r\n\r\n                builder.Append(\"<tr>\");\r\n                builder.Append(\"<td height=\\\"24\\\">&nbsp;\");\r\n                builder.Append(\"项目名称\");\r\n                builder.Append(\"</td>\");\r\n                builder.Append(\"<td>\");\r\n                builder.Append(\"使用 C# 输出最近的项目。\");\r\n                builder.Append(\"</td>\");\r\n            }\r\n            //循环部分结束\r\n\r\n            builder.Append(\"</table>\");\r\n\r\n            //最近项目列表输出结束\r\n\r\n            builder.Append(\"</td>\");\r\n            builder.Append(\"</tr>\");\r\n            builder.Append(\"<tr>\");\r\n            builder.Append(\"<td>&nbsp;</td>\");\r\n            builder.Append(\"</tr>\");\r\n            builder.Append(\"</table>\");\r\n\r\n            builder.Append(\"<table width=\\\"100%\\\"  border=\\\"0\\\" cellspacing=\\\"0\\\" cellpadding=\\\"0\\\">\");\r\n            builder.Append(\"<tr>\");\r\n            builder.Append(\"<td width=\\\"30\\\">&nbsp;</td>\");\r\n            builder.Append(\"<td>\");\r\n            builder.Append(\"<input type=\\\"button\\\" id=\\\"btnOpenProject\\\" value=\\\"打开项目\\\">\");\r\n            builder.Append(\"&nbsp;&nbsp;&nbsp;&nbsp;\");\r\n            builder.Append(\"<input type=\\\"button\\\" id=\\\"btnNewProject\\\" value=\\\"新建项目\\\">\");\r\n            builder.Append(\"</td>\");\r\n            builder.Append(\"</tr>\");\r\n            builder.Append(\"</table>\");\r\n        }\r\n\r\n        public virtual void RenderSectionHelp(StringBuilder builder)\r\n        {\r\n            builder.Append(@\"\r\n            <table width='100%'  border='0' cellspacing='0' cellpadding='0'>\r\n              <tr>\r\n                <td colspan='2'>&nbsp;</td>\r\n              </tr>\r\n              <tr>\r\n                <td width='30'><!--这里是最近项目列表--></td>\r\n              <td><p>如何获取帮助?<br>\r\n                <br>\r\n                  官方网站：http://www.shengxunwei.com<br/>\r\n                  欢迎加入QQ群：591928344<br/>\r\n                  有任何疑问或咨询也可联系 QQ：279060597\r\n                </p>\r\n                </td>\r\n              </tr>\r\n              <tr>\r\n                <td colspan='2'>&nbsp;</td>\r\n              </tr>\r\n            </table>\r\n            \");\r\n        }\r\n\r\n        public virtual void RenderFinalPageBodySection(StringBuilder builder)\r\n        {\r\n            builder.Append(\"</body>\");\r\n        }\r\n\r\n        public virtual void RenderPageEndSection(StringBuilder builder)\r\n        {\r\n            builder.Append(\"</html>\");\r\n        }\r\n\r\n        public string Render(string section)\r\n        {\r\n            StringBuilder builder = new StringBuilder(2048);\r\n            RenderHeaderSection(builder);\r\n\r\n            switch (section.ToLowerInvariant())\r\n            {\r\n                case StartPageScheme.START_HOST:\r\n                    RenderSectionStartBody(builder);\r\n                    break;\r\n                case StartPageScheme.HELP_HOST:\r\n                    RenderSectionHelp(builder);\r\n                    break;\r\n            }\r\n\r\n            RenderFinalPageBodySection(builder);\r\n            RenderPageEndSection(builder);\r\n\r\n            return builder.ToString();\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/StartPageScheme.cs",
    "content": "﻿using System;\nusing System.Windows.Forms;\n\nusing System.IO;\n\nnamespace Sheng.Winform.Controls.Demo\n{\n    class StartPageScheme : DefaultHtmlViewSchemeExtension\n    {\n        /// <summary>\n        /// startpage\n        /// </summary>\n        public const string SCHEMENAME = \"startpage\";\n        /// <summary>\n        /// startpage://start/\n        /// </summary>\n        public const string STARTPAGE_URI = \"startpage://start/\";\n        /// <summary>\n        /// startpage://project/\n        /// </summary>\n        public const string OPENPROJECT_URI = \"startpage://project/\";\n        /// <summary>\n        /// project\n        /// </summary>\n        public const string OPENPROJECT_HOST = \"project\";\n        /// <summary>\n        /// start\n        /// </summary>\n        public const string START_HOST = \"start\";\n        /// <summary>\n        /// help\n        /// </summary>\n        public const string HELP_HOST = \"help\";\n\n        private StartPageCodePage _page;\n\n\n        #region 公开属性\n\n        private static readonly StartPageScheme _instance = new StartPageScheme();\n        public static StartPageScheme Instance\n        {\n            get { return _instance; }\n        }\n\n        #endregion\n\n        private StartPageScheme()\n        {\n        }\n\n        public override void InterceptNavigate(HtmlViewPane pane, WebBrowserNavigatingEventArgs e)\n        {\n            e.Cancel = true;\n            if (_page == null)\n            {\n                //page = new ICSharpCodePage();\n                _page = new StartPageCodePage();\n                // page.Title = ICSharpCode.Core.StringParser.Parse(\"${res:StartPage.StartPageContentName}\");\n            }\n            string host = e.Url.Host;\n            if (host.Equals(OPENPROJECT_HOST, StringComparison.CurrentCultureIgnoreCase))\n            {\n                //   string projectFile = page.projectFiles[int.Parse(e.Url.LocalPath.Trim('/'))];\n                //   FileUtility.ObservedLoad(new NamedFileOperationDelegate(ProjectService.LoadSolution), projectFile);\n\n                string projectFile = e.Url.LocalPath.TrimStart('/');\n                if (String.IsNullOrEmpty(projectFile) == false)\n                {\n                    //FileInfo最主要的作用是包装这个路径，因为从URL拿下来的路径会用 / ，而windows文件路径应该用 \\\n                    //这个不影响打开文件，但是会使History多记录一个项目打开历史，只是一个 / ，一个\\\n                    FileInfo fileInfo = new FileInfo(projectFile);\n                    if (fileInfo.Exists)\n                    {\n                        //_projectService.OpenProject(fileInfo.FullName);\n                        \n                    }\n                }\n            }\n            else\n            {\n                pane.WebBrowser.DocumentText = _page.Render(host);\n            }\n        }\n\n        public override void DocumentCompleted(HtmlViewPane pane, WebBrowserDocumentCompletedEventArgs e)\n        {\n            //HtmlElement btn;\n            HtmlElement btn = null;\n            btn = pane.WebBrowser.Document.GetElementById(\"btnOpenProject\");\n            if (btn != null)\n            {\n                //为按钮挂接事件\n                //LoggingService.Debug(\"Attached event handler to opencombine button\");\n                btn.Click += delegate { MessageBox.Show(\"调用 C# 中的打开项目方法。\"); };\n            }\n            btn = pane.WebBrowser.Document.GetElementById(\"btnNewProject\");\n            if (btn != null)\n            {\n                btn.Click += delegate { MessageBox.Show(\"调用 C# 中的新建项目方法。\"); };\n            }\n\n            pane.WebBrowser.Navigating += pane_WebBrowser_Navigating;\n            pane.WebBrowser.Navigated += pane_WebBrowser_Navigated;\n        }\n\n        void pane_WebBrowser_Navigated(object sender, WebBrowserNavigatedEventArgs e)\n        {\n            try\n            {\n                WebBrowser webBrowser = (WebBrowser)sender;\n                webBrowser.Navigating -= pane_WebBrowser_Navigating;\n                webBrowser.Navigated -= pane_WebBrowser_Navigated;\n            }\n            catch (Exception ex)\n            {\n                //MessageService.ShowError(ex);\n                MessageBox.Show(ex.Message);\n            }\n        }\n\n        void pane_WebBrowser_Navigating(object sender, WebBrowserNavigatingEventArgs e)\n        {\n            try\n            {\n                if (e.Url.IsFile)\n                {\n                    e.Cancel = true;\n                    string file = e.Url.LocalPath;\n                    //IProjectLoader loader = ProjectService.GetProjectLoader(file);\n                    //if (loader != null)\n                    //{\n                    //    FileUtility.ObservedLoad(new NamedFileOperationDelegate(loader.Load), file);\n                    //}\n                    //else\n                    //{\n                    //    FileService.OpenFile(file);\n                    //}\n                }\n            }\n            catch (Exception ex)\n            {\n                //  MessageService.ShowError(ex);\n                MessageBox.Show(ex.Message);\n            }\n        }\n\n        public override void GoHome(HtmlViewPane pane)\n        {\n            pane.Navigate(STARTPAGE_URI);\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls.Demo/TestListViewItem.cs",
    "content": "﻿using System;\r\nusing System.Collections.Generic;\r\nusing System.Linq;\r\nusing System.Text;\r\n\r\nnamespace Sheng.Winform.Controls.Demo\r\n{\r\n    class TestListViewItem\r\n    {\r\n        public string Name\r\n        {\r\n            get; set;\r\n        }\r\n\r\n        public string Description\r\n        {\r\n            get; set;\r\n        }\r\n\r\n\r\n        static List<TestListViewItem> list = null;\r\n        public static List<TestListViewItem> GetTestData()\r\n        {\r\n            if (list == null)\r\n            {\r\n                list = new List<TestListViewItem>();\r\n\r\n                list.Add(new TestListViewItem()\r\n                {\r\n                    Name = \"鲁迅\",\r\n                    Description = \"鲁迅的方向，就是中华民族新文化的方向。\"\r\n                });\r\n                list.Add(new TestListViewItem()\r\n                {\r\n                    Name = \"徐志摩\",\r\n                    Description = \"代表作品有《再别康桥》，《翡冷翠的一夜》。\"\r\n                });\r\n            }\r\n\r\n            return list;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "Sheng.Winform.Controls.Drawing/BmpAdjuster.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Drawing;\nusing System.Drawing.Imaging;\nusing System.Runtime.InteropServices;\n\nnamespace Sheng.Winform.Controls.Drawing\n{\n    public class BmpAdjuster\n    {\n        #region 原有方法\n\n        public delegate ColorPalette PaletteAdjustEvent(ColorPalette plt);\n\n        public unsafe delegate void ConvertScanLineEvent(IntPtr srcLine, IntPtr dstLine, int width, int srcPixBit, int dstPixBit, Bitmap srcBmp, Bitmap dstBmp);\n\n        private int alpha = 255;\n\n        public BmpAdjuster()\n        {\n\n        }\n\n        /// <summary>\n        /// 初始化的时候给个alpha值,这样在灰图片的时候可以半透明\n        /// </summary>\n        /// <param name=\"alpha\"></param>\n        public BmpAdjuster(int alpha)\n        {\n            this.alpha = alpha;\n        }\n\n        public void AdjustColor(ref Bitmap bmp, PixelFormat format, PaletteAdjustEvent PalleteAdjust, ConvertScanLineEvent ConvertScanLine)\n        {\n            Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);\n            Bitmap bmpOut = new Bitmap(bmp.Width, bmp.Height, format);\n\n            bmpOut.Palette = PalleteAdjust(bmpOut.Palette);\n\n            PixelFormat srcFmt = bmp.PixelFormat;\n            PixelFormat dstFmt = bmpOut.PixelFormat;\n            int srcPixBit = GetPixelSize(srcFmt);\n            int dstPixBit = GetPixelSize(dstFmt);\n\n            BitmapData srcData = null;\n            BitmapData dstData = null;\n            try\n            {\n                srcData = bmp.LockBits(rect, ImageLockMode.ReadOnly, srcFmt);\n                dstData = bmpOut.LockBits(rect, ImageLockMode.WriteOnly, dstFmt);\n\n                unsafe\n                {\n                    byte* srcLine = (byte*)srcData.Scan0.ToPointer();\n                    byte* dstLine = (byte*)dstData.Scan0.ToPointer();\n                    for (int L = 0; L < srcData.Height; L++)\n                    {\n                        ConvertScanLine((IntPtr)srcLine, (IntPtr)dstLine, srcData.Width, srcPixBit, dstPixBit, bmp, bmpOut);\n\n                        srcLine += srcData.Stride;\n                        dstLine += dstData.Stride;\n                    }\n                }\n            }\n            finally\n            {\n                bmp.UnlockBits(srcData);\n                bmpOut.UnlockBits(dstData);\n            }\n\n            bmp = bmpOut;\n        }\n\n        internal int GetPixelSize(PixelFormat format)\n        {\n            switch (format)\n            {\n                case PixelFormat.Format16bppRgb555: return 16;\n                case PixelFormat.Format16bppRgb565: return 16;\n                case PixelFormat.Format24bppRgb: return 24;\n                case PixelFormat.Format32bppRgb: return 32;\n                case PixelFormat.Format1bppIndexed: return 1;\n                case PixelFormat.Format4bppIndexed: return 4;\n                case PixelFormat.Format8bppIndexed: return 8;\n                case PixelFormat.Format16bppArgb1555: return 16;\n                case PixelFormat.Format32bppPArgb: return 32;\n                case PixelFormat.Format16bppGrayScale: return 16;\n                case PixelFormat.Format48bppRgb: return 48;\n                case PixelFormat.Format64bppPArgb: return 64;\n                case PixelFormat.Canonical: return 32;\n                case PixelFormat.Format32bppArgb: return 32;\n                case PixelFormat.Format64bppArgb: return 64;\n            }\n            return 0;\n        }\n\n        public unsafe void Monochrome(ref Bitmap bmp)\n        {\n            AdjustColor(ref bmp, PixelFormat.Format1bppIndexed,\n                new PaletteAdjustEvent(SetBlackWhitePallete),\n                new ConvertScanLineEvent(ConvertBlackWhiteScanLine));\n        }\n\n        ColorPalette SetBlackWhitePallete(ColorPalette plt)\n        {\n            plt.Entries[0] = Color.Black;\n            plt.Entries[1] = Color.White;\n            return plt;\n        }\n\n        unsafe void ConvertBlackWhiteScanLine(IntPtr srcLine, IntPtr dstLine, int width, int srcPixBit, int dstPixBit, Bitmap srcBmp, Bitmap dstBmp)\n        {\n            byte* src = (byte*)srcLine.ToPointer();\n            byte* dst = (byte*)dstLine.ToPointer();\n            int srcPixByte = srcPixBit / 8;\n            int x, v, t = 0;\n\n            for (x = 0; x < width; x++)\n            {\n                v = 28 * src[0] + 151 * src[1] + 77 * src[2];\n                t = (t << 1) | (v > 200 * 256 ? 1 : 0);\n                src += srcPixByte;\n\n                if (x % 8 == 7)\n                {\n                    *dst = (byte)t;\n                    dst++;\n                    t = 0;\n                }\n            }\n\n            if ((x %= 8) != 7)\n            {\n                t <<= 8 - x;\n                *dst = (byte)t;\n            }\n        }\n\n        public void Gray(ref Bitmap bmp)\n        {\n            AdjustColor(ref bmp, PixelFormat.Format8bppIndexed,\n                new PaletteAdjustEvent(SetGrayPallete),\n                new ConvertScanLineEvent(ConvertGaryScanLine));\n        }\n\n        ColorPalette SetGrayPallete(ColorPalette plt)\n        {\n            //for (int i = plt.Entries.Length - 1; i >= 0; i--)\n            //    plt.Entries[i] = Color.FromArgb( i, i, i);\n            for (int i = plt.Entries.Length - 1; i >= 0; i--)\n                plt.Entries[i] = Color.FromArgb(alpha, i, i, i);\n            return plt;\n        }\n\n        unsafe void ConvertGaryScanLine(IntPtr srcLine, IntPtr dstLine, int width, int srcPixBit, int dstPixBit, Bitmap srcBmp, Bitmap dstBmp)\n        {\n            byte* src = (byte*)srcLine.ToPointer();\n            byte* dst = (byte*)dstLine.ToPointer();\n            int srcPixByte = srcPixBit / 8;\n\n            for (int x = 0; x < width; x++)\n            {\n                *dst = (byte)((28 * src[0] + 151 * src[1] + 77 * src[2]) >> 8);\n                src += srcPixByte;\n                dst++;\n            }\n        }\n\n        #endregion\n\n        /// <summary>\n        /// 使图片单色化\n        /// </summary>\n        /// <param name=\"pimage\"></param>\n        /// <returns></returns>\n        public static Bitmap MonochromeLockBits(Bitmap pimage)\n        {\n            Bitmap source = null;\n\n            // If original bitmap is not already in 32 BPP, ARGB format, then convert\n            if (pimage.PixelFormat != PixelFormat.Format32bppArgb)\n            {\n                source = new Bitmap(pimage.Width, pimage.Height, PixelFormat.Format32bppArgb);\n                source.SetResolution(pimage.HorizontalResolution, pimage.VerticalResolution);\n                using (Graphics g = Graphics.FromImage(source))\n                {\n                    g.DrawImageUnscaled(pimage, 0, 0);\n                }\n            }\n            else\n            {\n                source = pimage;\n            }\n\n            // Lock source bitmap in memory\n            BitmapData sourceData = source.LockBits(new Rectangle(0, 0, source.Width, source.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);\n\n            // Copy image data to binary array\n            int imageSize = sourceData.Stride * sourceData.Height;\n            byte[] sourceBuffer = new byte[imageSize];\n            Marshal.Copy(sourceData.Scan0, sourceBuffer, 0, imageSize);\n\n            // Unlock source bitmap\n            source.UnlockBits(sourceData);\n\n            // Create destination bitmap\n            Bitmap destination = new Bitmap(source.Width, source.Height, PixelFormat.Format1bppIndexed);\n\n            // Lock destination bitmap in memory\n            BitmapData destinationData = destination.LockBits(new Rectangle(0, 0, destination.Width, destination.Height), ImageLockMode.WriteOnly, PixelFormat.Format1bppIndexed);\n\n            // Create destination buffer\n            imageSize = destinationData.Stride * destinationData.Height;\n            byte[] destinationBuffer = new byte[imageSize];\n\n            int sourceIndex = 0;\n            int destinationIndex = 0;\n            int pixelTotal = 0;\n            byte destinationValue = 0;\n            int pixelValue = 128;\n            int height = source.Height;\n            int width = source.Width;\n            int threshold = 500;\n\n            // Iterate lines\n            for (int y = 0; y < height; y++)\n            {\n                sourceIndex = y * sourceData.Stride;\n                destinationIndex = y * destinationData.Stride;\n                destinationValue = 0;\n                pixelValue = 128;\n\n                // Iterate pixels\n                for (int x = 0; x < width; x++)\n                {\n                    // Compute pixel brightness (i.e. total of Red, Green, and Blue values)\n                    pixelTotal = sourceBuffer[sourceIndex + 1] + sourceBuffer[sourceIndex + 2] + sourceBuffer[sourceIndex + 3];\n                    if (pixelTotal > threshold)\n                    {\n                        destinationValue += (byte)pixelValue;\n                    }\n                    if (pixelValue == 1)\n                    {\n                        destinationBuffer[destinationIndex] = destinationValue;\n                        destinationIndex++;\n                        destinationValue = 0;\n                        pixelValue = 128;\n                    }\n                    else\n                    {\n                        pixelValue >>= 1;\n                    }\n                    sourceIndex += 4;\n                }\n                if (pixelValue != 128)\n                {\n                    destinationBuffer[destinationIndex] = destinationValue;\n                }\n            }\n\n            // Copy binary image data to destination bitmap\n            Marshal.Copy(destinationBuffer, 0, destinationData.Scan0, imageSize);\n\n            // Unlock destination bitmap\n            destination.UnlockBits(destinationData);\n\n            // Dispose of source if not originally supplied bitmap\n            if (source != pimage)\n            {\n                source.Dispose();\n            }\n\n            // Return\n            return destination;\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls.Drawing/ColorRepresentationHelper.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Drawing;\nusing System.Reflection;\n\nnamespace Sheng.Winform.Controls.Drawing\n{\n    public enum ChooseColorType\n    {\n        /// <summary>\n        /// 自定义\n        /// </summary>\n        Custom = 0,\n        /// <summary>\n        /// 预置\n        /// </summary>\n        Define = 1,\n        /// <summary>\n        /// 系统\n        /// </summary>\n        System = 2\n    }\n\n    /// <summary>\n    /// 颜色表示法\n    /// </summary>\n    public class ColorRepresentationHelper\n    {\n        /// <summary>\n        /// 根据颜色表示字符串获取对应的颜色\n        /// </summary>\n        /// <param name=\"colorValueString\"></param>\n        /// <returns></returns>\n        public static Color GetColorByValue(string colorValueString)\n        {\n            if (colorValueString == null || colorValueString == String.Empty)\n            {\n                return Color.Empty;\n            }\n\n            string[] strArray = colorValueString.Split('.');\n\n            ChooseColorType type =\n                (ChooseColorType)Convert.ToInt32(strArray[0]);\n            Color color = Color.Empty;\n            switch (type)\n            {\n                case ChooseColorType.Custom:\n                    color = Color.FromArgb(Convert.ToInt32(strArray[2]));\n                    break;\n                case ChooseColorType.Define:\n                    color = Color.FromArgb(Convert.ToInt32(strArray[2]));\n                    break;\n                case ChooseColorType.System:\n                    Type typeSystemColors = typeof(System.Drawing.SystemColors);\n                    PropertyInfo p = typeSystemColors.GetProperty(strArray[1]);\n                    color = (Color)p.GetValue(typeSystemColors, null);\n                    break;\n            }\n\n            return color;\n        }\n\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls.Drawing/DrawingTool.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Drawing;\nusing System.Drawing.Imaging;\nusing System.IO;\nusing System.Drawing.Drawing2D;\nusing System.Runtime.InteropServices;\nusing System.Diagnostics;\n\nnamespace Sheng.Winform.Controls.Drawing\n{\n    public static class DrawingTool\n    {\n        #region GetImage\n\n        public static Image GetImage(string filePath)\n        {\n            return GetImage(filePath, true);\n        }\n\n        public static Image GetImage(string filePath, bool memberCopy)\n        {\n            return GetImage(filePath, memberCopy, false);\n        }\n        \n        /// <summary>\n        /// 从文件中获取Image对象\n        /// 这个函数的主要功能是处理一些ico文件\n        /// 一些ico文件的格式可能比较新，直接Image.FormFile，会报内存不足的异常\n        /// </summary>\n        /// <param name=\"filePath\"></param>\n        /// <param name=\"memberCopy\">是否将文件读入内存操作，如果为false,将直接返回Image.FromFile，在此情况下，\n        /// 必须手动释放Image对象，否则文件将一直处于占用状态，如果为true,则在内存中拷贝副本</param>\n        /// <returns></returns>\n        public static Image GetImage(string filePath,bool memberCopy, bool markNotFind)\n        {\n            FileInfo file = new FileInfo(filePath);\n            Image image = null;\n\n            if (!file.Exists)\n            {\n                if (markNotFind)\n                {\n                    image = new Bitmap(16, 16);\n                    Mark.FileNotFind(image);\n                    return image;\n                }\n                else\n                {\n                    return null;\n                }\n            }\n\n\n            switch (file.Extension.ToLower())\n            {\n                case \".ico\": try\n                    {\n                        Icon icon = new Icon(file.FullName);\n                        image = icon.ToBitmap();\n                    }\n                    catch\n                    {\n                        image = new Bitmap(16, 16);\n                         Mark.FileCanNotRead(image);\n                    }\n                    break;\n                default:\n                    if (memberCopy)\n                    {\n                        Image imgTemp = Image.FromFile(file.FullName);\n                        image = new System.Drawing.Bitmap(imgTemp);\n                        imgTemp.Dispose();\n                    }\n                    else\n                    {\n                        // Image.FromFile(file.FullName);会使文件一直处于被占用状态，必须手动释放\n                        image = Image.FromFile(file.FullName);\n                    }\n                    break;\n            }\n          \n            return image;\n        }\n\n        #endregion\n\n        #region ImageToIcon\n\n        /// <summary>\n        /// 将图像转为Icon对象,使用png格式\n        /// </summary>\n        /// <param name=\"image\"></param>\n        /// <returns></returns>\n        public static Icon ImageToIcon(Image image)\n        {\n            return ImageToIcon(image, ImageFormat.Png);\n        }\n\n        /// <summary>\n        /// 将图像转为Icon对象\n        /// </summary>\n        /// <param name=\"image\"></param>\n        /// <param name=\"format\"></param>\n        /// <returns></returns>\n        public static Icon ImageToIcon(Image image, ImageFormat format)\n        {\n            System.IO.Stream ms = new MemoryStream();\n            image.Save(ms, format);\n            Icon icon = Icon.FromHandle(new Bitmap(ms).GetHicon());\n            ms.Close();\n            return icon;\n        }\n\n        #endregion\n\n        #region GetScaleImage\n\n        /// <summary>\n        /// 返回适应指定容器大小的图像\n        /// 如果图像的尺寸(长或宽)超出了容器范围,将按比例获取图像的缩略图返回,否则直接返回图像\n        /// 此方法最终调用 Image.GetThumbnailImage\n        /// 但是注意,在指定的容器尺寸过小时,返回的Image尺寸不可知,是在为了显示16x16的小缩略图是发现了此问题\n        /// 使用 GetScaleImage\n        /// </summary>\n        /// <param name=\"image\"></param>\n        /// <param name=\"containerWidth\"></param>\n        /// <param name=\"containerHeight\"></param>\n        /// <returns></returns>\n        public static Image GetAutoScaleThumbnailImage(Image image, int containerWidth, int containerHeight)\n        {\n            if (image.Size.Width > containerWidth ||\n                image.Size.Height > containerHeight)\n            {\n                double height = containerHeight;\n                double width = containerWidth;\n\n                double new_height;\n                double new_width;\n                double scale;\n                new_height = height;\n                new_width = width;\n                if ((image.Width > width) || (image.Height > height))\n                {\n                    if (image.Width > width)\n                    {\n                        scale = image.Width / width;\n                        new_width = image.Width / scale;\n                        new_height = image.Height / scale;\n                    }\n                    else\n                    {\n                        scale = image.Height / height;\n                        new_width = image.Width / scale;\n                        new_height = image.Height / scale;\n                    }\n                }\n\n                return image.GetThumbnailImage(Convert.ToInt32(new_width), Convert.ToInt32(new_height),\n                   thumbnailCallback, IntPtr.Zero);\n                \n            }\n            else\n            {\n                return image;\n            }\n\n        }\n\n        static Image.GetThumbnailImageAbort thumbnailCallback = new Image.GetThumbnailImageAbort(ThumbnailCallback);\n        private static bool ThumbnailCallback()\n        {\n            return false;\n        }\n\n        /// <summary>\n        /// 返回适应指定容器大小的图像\n        /// 在需要的情况下,此方法创建一个新对象,进行绘制\n        /// </summary>\n        /// <param name=\"image\"></param>\n        /// <param name=\"containerWidth\"></param>\n        /// <param name=\"containerHeight\"></param>\n        /// <returns></returns>\n        public static Image GetScaleImage(Image image, Size size)\n        {\n            if (image.Size.Width > size.Width ||\n                image.Size.Height > size.Height)\n            {\n                double width = size.Width;\n                double height = size.Height;\n\n                double new_width;\n                double new_height;\n                double scale;\n                new_height = height;\n                new_width = width;\n                if ((image.Width > width) || (image.Height > height))\n                {\n                    if (image.Width > width)\n                    {\n                        scale = image.Width / width;\n                        new_width = image.Width / scale;\n                        new_height = image.Height / scale;\n                    }\n                    else\n                    {\n                        scale = image.Height / height;\n                        new_width = image.Width / scale;\n                        new_height = image.Height / scale;\n                    }\n                }\n\n                Bitmap bitmap = new Bitmap(Convert.ToInt32(new_width), Convert.ToInt32(new_height));\n\n                Graphics g = Graphics.FromImage(bitmap);\n\n                g.DrawImage(image, 0, 0, bitmap.Width, bitmap.Height);\n\n                return bitmap;\n            }\n            else\n            {\n                return image;\n            }\n        }\n\n        /// <summary>\n        /// 返回适应指定容器大小的图像\n        /// 在需要的情况下,此方法创建一个新对象,进行绘制\n        /// </summary>\n        /// <param name=\"image\"></param>\n        /// <param name=\"containerWidth\"></param>\n        /// <param name=\"containerHeight\"></param>\n        /// <returns></returns>\n        public static Image GetScaleImage(Image image, int containerWidth, int containerHeight)\n        {\n            if (containerWidth == null || containerHeight == null)\n            {\n                Debug.Assert(false, \"containerWidth 或 containerHeight为空\");\n                throw new ArgumentNullException();\n            }\n\n            return GetScaleImage(image, new Size(containerWidth, containerHeight));\n        }\n\n        #endregion\n\n        /// <summary>\n        /// Gets the bounding rectangle of an image required to fit\n        /// in to the given rectangle keeping the image aspect ratio.\n        /// </summary>\n        /// <param name=\"image\">The source image.</param>\n        /// <param name=\"fit\">The rectangle to fit in to.</param>\n        /// <param name=\"hAlign\">Horizontal image aligment in percent.</param>\n        /// <param name=\"vAlign\">Vertical image aligment in percent.</param>\n        /// <returns>New image size.</returns>\n        public static Rectangle GetSizedImageBounds(Image image, Rectangle fit, float hAlign, float vAlign)\n        {\n            if (hAlign < 0 || hAlign > 100.0f)\n                throw new ArgumentException(\"hAlign must be between 0.0 and 100.0 (inclusive).\", \"hAlign\");\n            if (vAlign < 0 || vAlign > 100.0f)\n                throw new ArgumentException(\"vAlign must be between 0.0 and 100.0 (inclusive).\", \"vAlign\");\n            Size scaled = GetSizedImageBounds(image, fit.Size);\n            int x = fit.Left + (int)(hAlign / 100.0f * (float)(fit.Width - scaled.Width));\n            int y = fit.Top + (int)(vAlign / 100.0f * (float)(fit.Height - scaled.Height));\n\n            return new Rectangle(x, y, scaled.Width, scaled.Height);\n        }\n        /// <summary>\n        /// Gets the bounding rectangle of an image required to fit\n        /// in to the given rectangle keeping the image aspect ratio.\n        /// The image will be centered in the fit box.\n        /// </summary>\n        /// <param name=\"image\">The source image.</param>\n        /// <param name=\"fit\">The rectangle to fit in to.</param>\n        /// <returns>New image size.</returns>\n        public static Rectangle GetSizedImageBounds(Image image, Rectangle fit)\n        {\n            return GetSizedImageBounds(image, fit, 50.0f, 50.0f);\n        }\n\n        /// <summary>\n        /// Gets the scaled size of an image required to fit\n        /// in to the given size keeping the image aspect ratio.\n        /// </summary>\n        /// <param name=\"image\">The source image.</param>\n        /// <param name=\"fit\">The size to fit in to.</param>\n        /// <returns>New image size.</returns>\n        public static Size GetSizedImageBounds(Image image, Size fit)\n        {\n            float f = System.Math.Max((float)image.Width / (float)fit.Width, (float)image.Height / (float)fit.Height);\n            if (f < 1.0f) f = 1.0f; // Do not upsize small images\n            int width = (int)System.Math.Round((float)image.Width / f);\n            int height = (int)System.Math.Round((float)image.Height / f);\n            return new Size(width, height);\n        }\n\n\n        #region RoundedRect\n\n        /// <summary>\n        /// 获取一个圆角矩形\n        /// </summary>\n        /// <param name=\"width\"></param>\n        /// <param name=\"height\"></param>\n        /// <param name=\"radius\">角度</param>\n        /// <returns></returns>\n        public static GraphicsPath RoundedRect(int width, int height, int radius)\n        {\n            RectangleF baseRect = new RectangleF(0, 0, width, height);\n            return RoundedRect(baseRect, radius);\n        }\n\n        /// <summary>\n        /// 获取一个圆角矩形\n        /// </summary>\n        /// <param name=\"width\"></param>\n        /// <param name=\"height\"></param>\n        /// <param name=\"radius\">角度</param>\n        /// <returns></returns>\n        public static GraphicsPath RoundedRect(RectangleF baseRect, int radius)\n        {\n            //RectangleF baseRect = new RectangleF(0, 0, width, height);\n            float diameter = radius * 2.0f;\n            SizeF sizeF = new SizeF(diameter, diameter);\n            RectangleF arc = new RectangleF(baseRect.Location, sizeF);\n            GraphicsPath path = new GraphicsPath();\n\n            // top left arc \n            path.AddArc(arc, 180, 90);\n\n            // top right arc \n            arc.X = baseRect.Right - diameter;\n            path.AddArc(arc, 270, 90);\n\n            // bottom right arc \n            arc.Y = baseRect.Bottom - diameter;\n            path.AddArc(arc, 0, 90);\n\n            // bottom left arc\n            arc.X = baseRect.Left;\n            path.AddArc(arc, 90, 90);\n\n            path.CloseFigure();\n            return path;\n        }\n\n        #endregion\n\n        #region GetArrowPath\n\n        public static GraphicsPath GetArrowPath(PointF startPoint, PointF endPoint)\n        {\n            return GetArrowPath(startPoint, endPoint, 7);\n        }\n\n        public static GraphicsPath GetArrowPath(PointF startPoint, PointF endPoint, double arrowLength)\n        {\n            return GetArrowPath(startPoint, endPoint, arrowLength, 1);\n        }\n\n        /// <summary>\n        /// 返回一个表示箭头的Path\n        /// 如果开始坐标和结束坐标之间的距离大于箭头的大小，箭头向结束坐标对齐，顶着结束坐标\n        /// </summary>\n        /// <param name=\"startPoint\">开始坐标</param>\n        /// <param name=\"endPoint\">结束坐标（顶点，方向）</param>\n        /// <param name=\"arrowLength\">箭头的长短，大小</param>\n        /// <param name=\"relativeValue\">箭头的粗细</param>\n        /// <returns></returns>\n        public static GraphicsPath GetArrowPath(PointF startPoint, PointF endPoint,\n            double arrowLength, double relativeValue)\n        {\n            //http://www.cnblogs.com/jasenkin/archive/2011/01/04/graphic_drawing_arrow_head_II.html\n\n            double distance = Math.Abs(Math.Sqrt(\n                (startPoint.X - endPoint.X) * (startPoint.X - endPoint.X) +\n                (startPoint.Y - endPoint.Y) * (startPoint.Y - endPoint.Y)));\n\n            if (distance == 0)\n            {\n                return new GraphicsPath();\n            }\n\n            double xa = endPoint.X + arrowLength * ((startPoint.X - endPoint.X)\n                + (startPoint.Y - endPoint.Y) / relativeValue) / distance;\n            double ya = endPoint.Y + arrowLength * ((startPoint.Y - endPoint.Y)\n                - (startPoint.X - endPoint.X) / relativeValue) / distance;\n            double xb = endPoint.X + arrowLength * ((startPoint.X - endPoint.X)\n                - (startPoint.Y - endPoint.Y) / relativeValue) / distance;\n            double yb = endPoint.Y + arrowLength * ((startPoint.Y - endPoint.Y)\n                + (startPoint.X - endPoint.X) / relativeValue) / distance;\n\n            PointF[] polygonPoints =\n            { \n                 new PointF(endPoint.X , endPoint.Y), \n                 new PointF( (float)xa   ,  (float)ya),\n                 new PointF( (float)xb   ,  (float)yb)\n            };\n\n            GraphicsPath path = new GraphicsPath();\n            path.AddLines(polygonPoints);\n\n            return path;\n        }\n\n\n        #endregion\n\n        #region Mark\n\n        /// <summary>\n        /// 在指定的Image上绘制特定标记\n        /// </summary>\n        public static class Mark\n        {\n            /// <summary>\n            /// 文件不存在\n            /// </summary>\n            /// <param name=\"img\"></param>\n            [Obsolete(\"改用 FileNotFind(Size size)\")]\n            public static void FileNotFind(Image image)\n            {\n                if (image == null)\n                {\n                    Debug.Assert(false, \"image = null\");\n                    return;\n                }\n\n                Graphics g = Graphics.FromImage(image);\n                g.DrawRectangle(Pens.Red, 0, 0, image.Width - 1, image.Height - 1);\n                g.DrawLine(Pens.Red, 0, 0, image.Width, image.Height);\n                g.DrawLine(Pens.Red, image.Width, 0, 0, image.Height);\n                g.Dispose();\n            }\n\n            /// <summary>\n            /// 文件不存在\n            /// </summary>\n            /// <param name=\"size\"></param>\n            public static Image FileNotFind(Size size)\n            {\n                Image image = new Bitmap(size.Width, size.Height);\n\n                Graphics g = Graphics.FromImage(image);\n                g.Clear(Color.White);\n                g.DrawRectangle(Pens.Red, 0, 0, image.Width - 1, image.Height - 1);\n                g.DrawLine(Pens.Red, 0, 0, image.Width, image.Height);\n                g.DrawLine(Pens.Red, image.Width, 0, 0, image.Height);\n                g.Dispose();\n\n                return image;\n            }\n\n            /// <summary>\n            /// 无法读取文件\n            /// </summary>\n            /// <param name=\"image\"></param>\n             [Obsolete(\"改用 FileCanNotRead(Size size)\")]\n            public static void FileCanNotRead(Image image)\n            {\n                if (image == null)\n                {\n                    Debug.Assert(false, \"image = null\");\n                    return;\n                }\n\n                Graphics g = Graphics.FromImage(image);\n                g.DrawRectangle(Pens.Red, 0, 0, image.Width - 1, image.Height - 1);\n                g.DrawLine(Pens.Red, 0, 0, image.Width, image.Height);\n                g.DrawLine(Pens.Red, image.Width, 0, 0, image.Height);\n                g.Dispose();\n            }\n\n            public static Image FileCanNotRead(Size size)\n            {\n                Image image = new Bitmap(size.Width, size.Height);\n\n                Graphics g = Graphics.FromImage(image);\n                g.Clear(Color.White);\n                g.DrawRectangle(Pens.Red, 0, 0, image.Width - 1, image.Height - 1);\n                g.DrawLine(Pens.Red, 0, 0, image.Width, image.Height);\n                g.DrawLine(Pens.Red, image.Width, 0, 0, image.Height);\n                g.Dispose();\n\n                return image;\n            }\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls.Drawing/GraphPlotting.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Drawing;\nusing System.Runtime.InteropServices;\nusing System.Drawing.Imaging;\n\nnamespace SEDrawing\n{\n    public class GraphPlotting\n    {\n        /// <summary>\n        /// 最大圆角半径\n        /// </summary>\n        protected const int roundMaxRoundRadius = 3;\n        /// <summary>\n        /// 最小矩形边长，用于自动处理圆角大小\n        /// </summary>\n        protected const int roundMinBorderLength = 20;\n\n        /// <summary>\n        /// 绘制一个圆角矩形.\n        /// </summary>\n        /// <param name=\"currentGraphicObject\">当前屏幕的图形对象</param>\n        /// <param name=\"lineColor\">矩形线条的颜色</param>\n        /// <param name=\"nLeft\">矩形左上角X坐标</param>\n        /// <param name=\"nTop\">矩形左上角Y坐标</param>\n        /// <param name=\"nRight\">矩形右下角X坐标</param>\n        /// <param name=\"nBottom\">矩形右下角Y坐标</param>\n        /// <param name=\"round\">圆角的半径长度</param>\n        public static void DrawRoundRect(System.Drawing.Graphics currentGraphicObject, Pen drawPen, int nLeft, int nTop, int nRight, int nBottom, int round)\n        {\n            if (round > roundMaxRoundRadius)\n            {\n                round = roundMaxRoundRadius;\n            }\n            else if (round < 0)\n            {\n                round = 0;\n            }\n            if (Math.Abs(nRight - nLeft) < roundMinBorderLength && Math.Abs(nBottom - nTop) < roundMinBorderLength)\n            {\n                round = 1;\n            }\n\n            Point Polygon1 = new Point(nLeft + round, nTop);\n            Point Polygon2 = new Point(nRight - round + 1, nTop);\n\n            Point Polygon3 = new Point(nLeft, nTop + round);\n            Point Polygon4 = new Point(nRight + 1, nTop + round);\n\n            Point Polygon5 = new Point(nLeft, nBottom - round);\n            Point Polygon6 = new Point(nRight + 1, nBottom - round);\n\n            Point Polygon7 = new Point(nLeft + round, nBottom + 1);\n            Point Polygon8 = new Point(nRight - round, nBottom + 1);\n\n            //四条主线(上下左右)\n            currentGraphicObject.DrawLine(drawPen, Polygon1.X, Polygon1.Y, Polygon2.X, Polygon2.Y);\n            currentGraphicObject.DrawLine(drawPen, Polygon7.X, Polygon7.Y, Polygon8.X, Polygon8.Y);\n            currentGraphicObject.DrawLine(drawPen, Polygon3.X, Polygon3.Y, Polygon5.X, Polygon5.Y);\n            currentGraphicObject.DrawLine(drawPen, Polygon4.X, Polygon4.Y, Polygon6.X, Polygon6.Y);\n\n            //四个边角\n            currentGraphicObject.DrawLine(drawPen, Polygon1.X, Polygon1.Y, Polygon3.X, Polygon3.Y);\n            currentGraphicObject.DrawLine(drawPen, Polygon2.X, Polygon2.Y, Polygon4.X, Polygon4.Y);\n            currentGraphicObject.DrawLine(drawPen, Polygon5.X, Polygon5.Y, Polygon7.X, Polygon7.Y);\n            currentGraphicObject.DrawLine(drawPen, Polygon6.X, Polygon6.Y, Polygon8.X, Polygon8.Y);\n        }\n        /// <summary>\n        /// 绘制一个圆角矩形.\n        /// </summary>\n        /// <param name=\"currentGraphicObject\">当前屏幕的图形对象</param>\n        /// <param name=\"lineColor\">矩形线条的颜色</param>\n        /// <param name=\"rect\">要绘制的矩形对象</param>\n        /// <param name=\"round\">圆角的半径长度</param>\n        public static void DrawRoundRect(System.Drawing.Graphics currentGraphicObject, Pen drawPen, Rectangle rect, int round)\n        {\n            DrawRoundRect(currentGraphicObject, drawPen, rect.Left, rect.Top, rect.Right, rect.Bottom, round);\n        }\n        /// <summary>\n        /// 绘制一个圆角矩形.\n        /// </summary>\n        /// <param name=\"currentGraphicObject\">当前屏幕的图形对象</param>\n        /// <param name=\"lineColor\">矩形线条的颜色</param>\n        /// <param name=\"rect\">要绘制的矩形对象</param>\n        public static void DrawRoundRect(System.Drawing.Graphics currentGraphicObject, Pen drawPen, Rectangle rect)\n        {\n            DrawRoundRect(currentGraphicObject, drawPen, rect.Left, rect.Top, rect.Right, rect.Bottom, 2);\n        }\n\n        /// <summary>\n        /// 填充一个圆角矩形.\n        /// </summary>\n        /// <param name=\"currentGraphicObject\">当前屏幕的图形对象</param>\n        /// <param name=\"lineColor\">矩形线条的颜色</param>\n        /// <param name=\"nLeft\">矩形左上角X坐标</param>\n        /// <param name=\"nTop\">矩形左上角Y坐标</param>\n        /// <param name=\"nRight\">矩形右下角X坐标</param>\n        /// <param name=\"nBottom\">矩形右下角Y坐标</param>\n        /// <param name=\"round\">圆角的半径长度</param>\n        public static void FillRoundRect(System.Drawing.Graphics currentGraphicObject, Brush brush, int nLeft, int nTop, int nRight, int nBottom, int round)\n        {\n            if (round > roundMaxRoundRadius)\n            {\n                round = roundMaxRoundRadius;\n            }\n            else if (round < 0)\n            {\n                round = 0;\n            }\n            if (Math.Abs(nRight - nLeft) < roundMinBorderLength && Math.Abs(nBottom - nTop) < roundMinBorderLength)\n            {\n                round = 1;\n            }\n\n            Point Polygon1 = new Point(nLeft + round, nTop);\n            Point Polygon2 = new Point(nRight - round + 1, nTop);\n\n            Point Polygon3 = new Point(nLeft, nTop + round);\n            Point Polygon4 = new Point(nRight + 1, nTop + round);\n\n            Point Polygon5 = new Point(nLeft, nBottom - round);\n            Point Polygon6 = new Point(nRight + 1, nBottom - round);\n\n            Point Polygon7 = new Point(nLeft + round, nBottom + 1);\n            Point Polygon8 = new Point(nRight - round, nBottom + 1);\n\n            currentGraphicObject.FillPolygon(brush, new Point[]{   Polygon1,\n                      Polygon3,\n                      Polygon5,\n                      Polygon7,\n                      Polygon8,\n                      Polygon6,\n                      Polygon4,\n                      Polygon2});\n        }\n        /// <summary>\n        /// 填充一个圆角矩形.\n        /// </summary>\n        /// <param name=\"currentGraphicObject\">当前屏幕的图形对象</param>\n        /// <param name=\"lineColor\">矩形线条的颜色</param>\n        /// <param name=\"rect\">要填充的矩形</param>\n        /// <param name=\"indentSize\">填充区域针对矩形的缩进距离</param>\n        /// <param name=\"round\">圆角的半径长度</param>\n        public static void FillRoundRect(System.Drawing.Graphics currentGraphicObject, Brush brush, Rectangle rect, int indentSize, int round)\n        {\n            FillRoundRect(currentGraphicObject, brush, rect.Left + indentSize, rect.Top + indentSize, rect.Right - indentSize + 1, rect.Bottom - indentSize + 1, round);\n        }\n        /// <summary>\n        /// 填充一个圆角矩形.\n        /// </summary>\n        /// <param name=\"currentGraphicObject\">当前屏幕的图形对象</param>\n        /// <param name=\"lineColor\">矩形线条的颜色</param>\n        /// <param name=\"rect\">要填充的矩形</param>\n        public static void FillRoundRect(System.Drawing.Graphics currentGraphicObject, Brush brush, Rectangle rect)\n        {\n            FillRoundRect(currentGraphicObject, brush, rect, 0, 2);\n        }\n\n        /// <summary>\n        /// 使图片单色化\n        /// </summary>\n        /// <param name=\"pimage\"></param>\n        /// <returns></returns>\n        public static Bitmap MonochromeLockBits(Bitmap pimage)\n        {\n            Bitmap source = null;\n\n            // If original bitmap is not already in 32 BPP, ARGB format, then convert\n            if (pimage.PixelFormat != PixelFormat.Format32bppArgb)\n            {\n                source = new Bitmap(pimage.Width, pimage.Height, PixelFormat.Format32bppArgb);\n                source.SetResolution(pimage.HorizontalResolution, pimage.VerticalResolution);\n                using (Graphics g = Graphics.FromImage(source))\n                {\n                    g.DrawImageUnscaled(pimage, 0, 0);\n                }\n            }\n            else\n            {\n                source = pimage;\n            }\n\n            // Lock source bitmap in memory\n            BitmapData sourceData = source.LockBits(new Rectangle(0, 0, source.Width, source.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);\n\n            // Copy image data to binary array\n            int imageSize = sourceData.Stride * sourceData.Height;\n            byte[] sourceBuffer = new byte[imageSize];\n            Marshal.Copy(sourceData.Scan0, sourceBuffer, 0, imageSize);\n\n            // Unlock source bitmap\n            source.UnlockBits(sourceData);\n\n            // Create destination bitmap\n            Bitmap destination = new Bitmap(source.Width, source.Height, PixelFormat.Format1bppIndexed);\n\n            // Lock destination bitmap in memory\n            BitmapData destinationData = destination.LockBits(new Rectangle(0, 0, destination.Width, destination.Height), ImageLockMode.WriteOnly, PixelFormat.Format1bppIndexed);\n\n            // Create destination buffer\n            imageSize = destinationData.Stride * destinationData.Height;\n            byte[] destinationBuffer = new byte[imageSize];\n\n            int sourceIndex = 0;\n            int destinationIndex = 0;\n            int pixelTotal = 0;\n            byte destinationValue = 0;\n            int pixelValue = 128;\n            int height = source.Height;\n            int width = source.Width;\n            int threshold = 500;\n\n            // Iterate lines\n            for (int y = 0; y < height; y++)\n            {\n                sourceIndex = y * sourceData.Stride;\n                destinationIndex = y * destinationData.Stride;\n                destinationValue = 0;\n                pixelValue = 128;\n\n                // Iterate pixels\n                for (int x = 0; x < width; x++)\n                {\n                    // Compute pixel brightness (i.e. total of Red, Green, and Blue values)\n                    pixelTotal = sourceBuffer[sourceIndex + 1] + sourceBuffer[sourceIndex + 2] + sourceBuffer[sourceIndex + 3];\n                    if (pixelTotal > threshold)\n                    {\n                        destinationValue += (byte)pixelValue;\n                    }\n                    if (pixelValue == 1)\n                    {\n                        destinationBuffer[destinationIndex] = destinationValue;\n                        destinationIndex++;\n                        destinationValue = 0;\n                        pixelValue = 128;\n                    }\n                    else\n                    {\n                        pixelValue >>= 1;\n                    }\n                    sourceIndex += 4;\n                }\n                if (pixelValue != 128)\n                {\n                    destinationBuffer[destinationIndex] = destinationValue;\n                }\n            }\n\n            // Copy binary image data to destination bitmap\n            Marshal.Copy(destinationBuffer, 0, destinationData.Scan0, imageSize);\n\n            // Unlock destination bitmap\n            destination.UnlockBits(destinationData);\n\n            // Dispose of source if not originally supplied bitmap\n            if (source != pimage)\n            {\n                source.Dispose();\n            }\n\n            // Return\n            return destination;\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls.Drawing/GraphicsExtension.cs",
    "content": "﻿/* GraphicsExtension - [Extended Graphics]\n * Author name:           Arun Reginald Zaheeruddin\n * Current version:       1.0.0.4 (12b)\n * Release documentation: http://www.codeproject.com\n * License information:   Microsoft Public License (Ms-PL) [http://www.opensource.org/licenses/ms-pl.html]\n * \n * Enhancements and history\n * ------------------------\n * 1.0.0.1 (20 Jul 2009): Initial release with modified code from previous CodeProject article.\n * 1.0.0.2 (25 Jul 2009): Added functionality that allows selected corners on a rectangle to be rounded.\n *                        Modified code to adapt to an anti-aliased output while drawing and filling rounded rectangles.\n * 1.0.0.3 (26 Jul 2009): Added DrawRoundedRectangle and FillRoundedRectangle methods that take a Rectangle and RectangleF object.\n * 1.0.0.4 (27 Jul 2009): Added font metrics and measuring utility that measures a font's height, leading, ascent, etc.\n * \n * Issues addressed\n * ----------------\n * 1. Rounded rectangles - rounding edges of a rectangle.\n * 2. Font Metrics - Measuring a font's height, leading, ascent, etc.\n */\nusing System;\nusing System.Drawing;\nusing System.Drawing.Drawing2D;\nusing System.Runtime.InteropServices;\n\nnamespace Sheng.Winform.Controls.Drawing\n{\n\tstatic class GraphicsExtension\n\t{\n\t\tprivate static GraphicsPath GenerateRoundedRectangle(\n\t\t\t\tthis Graphics graphics,\n\t\t\t\tRectangleF rectangle,\n\t\t\t\tfloat radius,\n\t\t\t\tRectangleEdgeFilter filter)\n\t\t{\n\t\t\tfloat diameter;\n\t\t\tGraphicsPath path = new GraphicsPath();\n\t\t\tif (radius <= 0.0F || filter == RectangleEdgeFilter.None)\n\t\t\t{\n\t\t\t\tpath.AddRectangle(rectangle);\n\t\t\t\tpath.CloseFigure();\n\t\t\t\treturn path;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (radius >= (Math.Min(rectangle.Width, rectangle.Height)) / 2.0)\n\t\t\t\t\treturn graphics.GenerateCapsule(rectangle);\n\t\t\t\tdiameter = radius * 2.0F;\n\t\t\t\tSizeF sizeF = new SizeF(diameter, diameter);\n\t\t\t\tRectangleF arc = new RectangleF(rectangle.Location, sizeF);\n\t\t\t\tif ((RectangleEdgeFilter.TopLeft & filter) == RectangleEdgeFilter.TopLeft)\n\t\t\t\t\tpath.AddArc(arc, 180, 90);\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tpath.AddLine(arc.X, arc.Y + arc.Height, arc.X, arc.Y);\n\t\t\t\t\tpath.AddLine(arc.X, arc.Y, arc.X + arc.Width, arc.Y);\n\t\t\t\t}\n\t\t\t\tarc.X = rectangle.Right - diameter;\n\t\t\t\tif ((RectangleEdgeFilter.TopRight & filter) == RectangleEdgeFilter.TopRight)\n\t\t\t\t\tpath.AddArc(arc, 270, 90);\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tpath.AddLine(arc.X, arc.Y, arc.X + arc.Width, arc.Y);\n\t\t\t\t\tpath.AddLine(arc.X + arc.Width, arc.Y + arc.Height, arc.X + arc.Width, arc.Y);\n\t\t\t\t}\n\t\t\t\tarc.Y = rectangle.Bottom - diameter;\n\t\t\t\tif ((RectangleEdgeFilter.BottomRight & filter) == RectangleEdgeFilter.BottomRight)\n\t\t\t\t\tpath.AddArc(arc, 0, 90);\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tpath.AddLine(arc.X + arc.Width, arc.Y, arc.X + arc.Width, arc.Y + arc.Height);\n\t\t\t\t\tpath.AddLine(arc.X, arc.Y + arc.Height, arc.X + arc.Width, arc.Y + arc.Height);\n\t\t\t\t}\n\t\t\t\tarc.X = rectangle.Left;\n\t\t\t\tif ((RectangleEdgeFilter.BottomLeft & filter) == RectangleEdgeFilter.BottomLeft)\n\t\t\t\t\tpath.AddArc(arc, 90, 90);\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tpath.AddLine(arc.X + arc.Width, arc.Y + arc.Height, arc.X, arc.Y + arc.Height);\n\t\t\t\t\tpath.AddLine(arc.X, arc.Y + arc.Height, arc.X, arc.Y);\n\t\t\t\t}\n\t\t\t\tpath.CloseFigure();\n\t\t\t}\n\t\t\treturn path;\n\t\t}\n\t\tprivate static GraphicsPath GenerateCapsule(\n\t\t\t\tthis Graphics graphics,\n\t\t\t\tRectangleF rectangle)\n\t\t{\n\t\t\tfloat diameter;\n\t\t\tRectangleF arc;\n\t\t\tGraphicsPath path = new GraphicsPath();\n\t\t\ttry\n\t\t\t{\n\t\t\t\tif (rectangle.Width > rectangle.Height)\n\t\t\t\t{\n\t\t\t\t\tdiameter = rectangle.Height;\n\t\t\t\t\tSizeF sizeF = new SizeF(diameter, diameter);\n\t\t\t\t\tarc = new RectangleF(rectangle.Location, sizeF);\n\t\t\t\t\tpath.AddArc(arc, 90, 180);\n\t\t\t\t\tarc.X = rectangle.Right - diameter;\n\t\t\t\t\tpath.AddArc(arc, 270, 180);\n\t\t\t\t}\n\t\t\t\telse if (rectangle.Width < rectangle.Height)\n\t\t\t\t{\n\t\t\t\t\tdiameter = rectangle.Width;\n\t\t\t\t\tSizeF sizeF = new SizeF(diameter, diameter);\n\t\t\t\t\tarc = new RectangleF(rectangle.Location, sizeF);\n\t\t\t\t\tpath.AddArc(arc, 180, 180);\n\t\t\t\t\tarc.Y = rectangle.Bottom - diameter;\n\t\t\t\t\tpath.AddArc(arc, 0, 180);\n\t\t\t\t}\n\t\t\t\telse path.AddEllipse(rectangle);\n\t\t\t}\n\t\t\tcatch { path.AddEllipse(rectangle); }\n\t\t\tfinally { path.CloseFigure(); }\n\t\t\treturn path;\n\t\t}\n\t\tpublic static void DrawRoundedRectangle(\n\t\t\t\tthis Graphics graphics,\n\t\t\t\tPen pen,\n\t\t\t\tfloat x,\n\t\t\t\tfloat y,\n\t\t\t\tfloat width,\n\t\t\t\tfloat height,\n\t\t\t\tfloat radius,\n\t\t\t\tRectangleEdgeFilter filter)\n\t\t{\n\t\t\tRectangleF rectangle = new RectangleF(x, y, width, height);\n\t\t\tGraphicsPath path = graphics.GenerateRoundedRectangle(rectangle, radius, filter);\n\t\t\tSmoothingMode old = graphics.SmoothingMode;\n\t\t\tgraphics.SmoothingMode = SmoothingMode.AntiAlias;\n\t\t\tgraphics.DrawPath(pen, path);\n\t\t\tgraphics.SmoothingMode = old;\n\t\t}\n\t\tpublic static void DrawRoundedRectangle(\n\t\t\t\tthis Graphics graphics,\n\t\t\t\tPen pen,\n\t\t\t\tfloat x,\n\t\t\t\tfloat y,\n\t\t\t\tfloat width,\n\t\t\t\tfloat height,\n\t\t\t\tfloat radius)\n\t\t{\n\t\t\tgraphics.DrawRoundedRectangle(\n\t\t\t\t\tpen,\n\t\t\t\t\tx,\n\t\t\t\t\ty,\n\t\t\t\t\twidth,\n\t\t\t\t\theight,\n\t\t\t\t\tradius,\n\t\t\t\t\tRectangleEdgeFilter.All);\n\t\t}\n\t\tpublic static void DrawRoundedRectangle(\n\t\t\t\tthis Graphics graphics,\n\t\t\t\tPen pen,\n\t\t\t\tint x,\n\t\t\t\tint y,\n\t\t\t\tint width,\n\t\t\t\tint height,\n\t\t\t\tint radius)\n\t\t{\n\t\t\tgraphics.DrawRoundedRectangle(\n\t\t\t\t\tpen,\n\t\t\t\t\tConvert.ToSingle(x),\n\t\t\t\t\tConvert.ToSingle(y),\n\t\t\t\t\tConvert.ToSingle(width),\n\t\t\t\t\tConvert.ToSingle(height),\n\t\t\t\t\tConvert.ToSingle(radius));\n\t\t}\n\t\tpublic static void DrawRoundedRectangle(\n\t\t\tthis Graphics graphics,\n\t\t\tPen pen,\n\t\t\tRectangle rectangle,\n\t\t\tint radius,\n\t\t\tRectangleEdgeFilter filter)\n\t\t{\n\t\t\tgraphics.DrawRoundedRectangle(\n\t\t\t\tpen,\n\t\t\t\trectangle.X,\n\t\t\t\trectangle.Y,\n\t\t\t\trectangle.Width,\n\t\t\t\trectangle.Height,\n\t\t\t\tradius,\n\t\t\t\tfilter);\n\t\t}\n\t\tpublic static void DrawRoundedRectangle(\n\t\t\tthis Graphics graphics,\n\t\t\tPen pen,\n\t\t\tRectangle rectangle,\n\t\t\tint radius)\n\t\t{\n\t\t\tgraphics.DrawRoundedRectangle(\n\t\t\t\tpen,\n\t\t\t\trectangle.X,\n\t\t\t\trectangle.Y,\n\t\t\t\trectangle.Width,\n\t\t\t\trectangle.Height,\n\t\t\t\tradius,\n\t\t\t\tRectangleEdgeFilter.All);\n\t\t}\n\t\tpublic static void DrawRoundedRectangle(\n\t\t\tthis Graphics graphics,\n\t\t\tPen pen,\n\t\t\tRectangleF rectangle,\n\t\t\tint radius,\n\t\t\tRectangleEdgeFilter filter)\n\t\t{\n\t\t\tgraphics.DrawRoundedRectangle(\n\t\t\t\tpen,\n\t\t\t\trectangle.X,\n\t\t\t\trectangle.Y,\n\t\t\t\trectangle.Width,\n\t\t\t\trectangle.Height,\n\t\t\t\tradius,\n\t\t\t\tfilter);\n\t\t}\n\t\tpublic static void DrawRoundedRectangle(\n\t\t\tthis Graphics graphics,\n\t\t\tPen pen,\n\t\t\tRectangleF rectangle,\n\t\t\tint radius)\n\t\t{\n\t\t\tgraphics.DrawRoundedRectangle(\n\t\t\t\tpen,\n\t\t\t\trectangle.X,\n\t\t\t\trectangle.Y,\n\t\t\t\trectangle.Width,\n\t\t\t\trectangle.Height,\n\t\t\t\tradius,\n\t\t\t\tRectangleEdgeFilter.All);\n\t\t}\n\t\tpublic static void FillRoundedRectangle(\n\t\t\t\tthis Graphics graphics,\n\t\t\t\tBrush brush,\n\t\t\t\tfloat x,\n\t\t\t\tfloat y,\n\t\t\t\tfloat width,\n\t\t\t\tfloat height,\n\t\t\t\tfloat radius,\n\t\t\t\tRectangleEdgeFilter filter)\n\t\t{\n\t\t\tRectangleF rectangle = new RectangleF(x, y, width, height);\n\t\t\tGraphicsPath path = graphics.GenerateRoundedRectangle(rectangle, radius, filter);\n\t\t\tSmoothingMode old = graphics.SmoothingMode;\n\t\t\tgraphics.SmoothingMode = SmoothingMode.AntiAlias;\n\t\t\tgraphics.FillPath(brush, path);\n\t\t\tgraphics.SmoothingMode = old;\n\t\t}\n\t\tpublic static void FillRoundedRectangle(\n\t\t\t\tthis Graphics graphics,\n\t\t\t\tBrush brush,\n\t\t\t\tfloat x,\n\t\t\t\tfloat y,\n\t\t\t\tfloat width,\n\t\t\t\tfloat height,\n\t\t\t\tfloat radius)\n\t\t{\n\t\t\tgraphics.FillRoundedRectangle(\n\t\t\t\t\tbrush,\n\t\t\t\t\tx,\n\t\t\t\t\ty,\n\t\t\t\t\twidth,\n\t\t\t\t\theight,\n\t\t\t\t\tradius,\n\t\t\t\t\tRectangleEdgeFilter.All);\n\t\t}\n\t\tpublic static void FillRoundedRectangle(\n\t\t\t\tthis Graphics graphics,\n\t\t\t\tBrush brush,\n\t\t\t\tint x,\n\t\t\t\tint y,\n\t\t\t\tint width,\n\t\t\t\tint height,\n\t\t\t\tint radius)\n\t\t{\n\t\t\tgraphics.FillRoundedRectangle(\n\t\t\t\t\tbrush,\n\t\t\t\t\tConvert.ToSingle(x),\n\t\t\t\t\tConvert.ToSingle(y),\n\t\t\t\t\tConvert.ToSingle(width),\n\t\t\t\t\tConvert.ToSingle(height),\n\t\t\t\t\tConvert.ToSingle(radius));\n\t\t}\n\t\tpublic static void FillRoundedRectangle(\n\t\t\tthis Graphics graphics,\n\t\t\tBrush brush,\n\t\t\tRectangle rectangle,\n\t\t\tint radius,\n\t\t\tRectangleEdgeFilter filter)\n\t\t{\n\t\t\tgraphics.FillRoundedRectangle(\n\t\t\t\tbrush,\n\t\t\t\trectangle.X,\n\t\t\t\trectangle.Y,\n\t\t\t\trectangle.Width,\n\t\t\t\trectangle.Height,\n\t\t\t\tradius,\n\t\t\t\tfilter);\n\t\t}\n\t\tpublic static void FillRoundedRectangle(\n\t\t\tthis Graphics graphics,\n\t\t\tBrush brush,\n\t\t\tRectangle rectangle,\n\t\t\tint radius)\n\t\t{\n\t\t\tgraphics.FillRoundedRectangle(\n\t\t\t\tbrush,\n\t\t\t\trectangle.X,\n\t\t\t\trectangle.Y,\n\t\t\t\trectangle.Width,\n\t\t\t\trectangle.Height,\n\t\t\t\tradius,\n\t\t\t\tRectangleEdgeFilter.All);\n\t\t}\n\t\tpublic static void FillRoundedRectangle(\n\t\t\tthis Graphics graphics,\n\t\t\tBrush brush,\n\t\t\tRectangleF rectangle,\n\t\t\tint radius,\n\t\t\tRectangleEdgeFilter filter)\n\t\t{\n\t\t\tgraphics.FillRoundedRectangle(\n\t\t\t\tbrush,\n\t\t\t\trectangle.X,\n\t\t\t\trectangle.Y,\n\t\t\t\trectangle.Width,\n\t\t\t\trectangle.Height,\n\t\t\t\tradius,\n\t\t\t\tfilter);\n\t\t}\n\t\tpublic static void FillRoundedRectangle(\n\t\t\tthis Graphics graphics,\n\t\t\tBrush brush,\n\t\t\tRectangleF rectangle,\n\t\t\tint radius)\n\t\t{\n\t\t\tgraphics.FillRoundedRectangle(\n\t\t\t\tbrush,\n\t\t\t\trectangle.X,\n\t\t\t\trectangle.Y,\n\t\t\t\trectangle.Width,\n\t\t\t\trectangle.Height,\n\t\t\t\tradius,\n\t\t\t\tRectangleEdgeFilter.All);\n\t\t}\n\t\tpublic static FontMetrics GetFontMetrics(\n\t\t\tthis Graphics graphics,\n\t\t\tFont font)\n\t\t{\n\t\t\treturn FontMetricsImpl.GetFontMetrics(graphics, font);\n\t\t}\n\t\tprivate class FontMetricsImpl : FontMetrics\n\t\t{\n\t\t\t[StructLayout(LayoutKind.Sequential)]\n\t\t\tpublic struct TEXTMETRIC\n\t\t\t{\n\t\t\t\tpublic int tmHeight;\n\t\t\t\tpublic int tmAscent;\n\t\t\t\tpublic int tmDescent;\n\t\t\t\tpublic int tmInternalLeading;\n\t\t\t\tpublic int tmExternalLeading;\n\t\t\t\tpublic int tmAveCharWidth;\n\t\t\t\tpublic int tmMaxCharWidth;\n\t\t\t\tpublic int tmWeight;\n\t\t\t\tpublic int tmOverhang;\n\t\t\t\tpublic int tmDigitizedAspectX;\n\t\t\t\tpublic int tmDigitizedAspectY;\n\t\t\t\tpublic char tmFirstChar;\n\t\t\t\tpublic char tmLastChar;\n\t\t\t\tpublic char tmDefaultChar;\n\t\t\t\tpublic char tmBreakChar;\n\t\t\t\tpublic byte tmItalic;\n\t\t\t\tpublic byte tmUnderlined;\n\t\t\t\tpublic byte tmStruckOut;\n\t\t\t\tpublic byte tmPitchAndFamily;\n\t\t\t\tpublic byte tmCharSet;\n\t\t\t}\n\t\t\t[DllImport(\"gdi32.dll\", CharSet = CharSet.Unicode)]\n\t\t\tpublic static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);\n\t\t\t[DllImport(\"gdi32.dll\", CharSet = CharSet.Unicode)]\n\t\t\tpublic static extern bool GetTextMetrics(IntPtr hdc, out TEXTMETRIC lptm);\n\t\t\t[DllImport(\"gdi32.dll\", CharSet = CharSet.Unicode)]\n\t\t\tpublic static extern bool DeleteObject(IntPtr hdc);\n\t\t\tprivate TEXTMETRIC GenerateTextMetrics(\n\t\t\t\tGraphics graphics,\n\t\t\t\tFont font)\n\t\t\t{\n\t\t\t\tIntPtr hDC = IntPtr.Zero;\n\t\t\t\tTEXTMETRIC textMetric;\n\t\t\t\tIntPtr hFont = IntPtr.Zero;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\thDC = graphics.GetHdc();\n\t\t\t\t\thFont = font.ToHfont();\n\t\t\t\t\tIntPtr hFontDefault = SelectObject(hDC, hFont);\n\t\t\t\t\tbool result = GetTextMetrics(hDC, out textMetric);\n\t\t\t\t\tSelectObject(hDC, hFontDefault);\n\t\t\t\t}\n\t\t\t\tfinally\n\t\t\t\t{\n\t\t\t\t\tif (hFont != IntPtr.Zero) DeleteObject(hFont);\n\t\t\t\t\tif (hDC != IntPtr.Zero) graphics.ReleaseHdc(hDC);\n\t\t\t\t}\n\t\t\t\treturn textMetric;\n\t\t\t}\n\t\t\tprivate TEXTMETRIC metrics;\n\t\t\tpublic override int Height { get { return this.metrics.tmHeight; } }\n\t\t\tpublic override int Ascent { get { return this.metrics.tmAscent; } }\n\t\t\tpublic override int Descent { get { return this.metrics.tmDescent; } }\n\t\t\tpublic override int InternalLeading { get { return this.metrics.tmInternalLeading; } }\n\t\t\tpublic override int ExternalLeading { get { return this.metrics.tmExternalLeading; } }\n\t\t\tpublic override int AverageCharacterWidth { get { return this.metrics.tmAveCharWidth; } }\n\t\t\tpublic override int MaximumCharacterWidth { get { return this.metrics.tmMaxCharWidth; } }\n\t\t\tpublic override int Weight { get { return this.metrics.tmWeight; } }\n\t\t\tpublic override int Overhang { get { return this.metrics.tmOverhang; } }\n\t\t\tpublic override int DigitizedAspectX { get { return this.metrics.tmDigitizedAspectX; } }\n\t\t\tpublic override int DigitizedAspectY { get { return this.metrics.tmDigitizedAspectY; } }\n\t\t\tprivate FontMetricsImpl(Graphics graphics, Font font)\n\t\t\t{\n\t\t\t\tthis.metrics = this.GenerateTextMetrics(graphics, font);\n\t\t\t}\n\t\t\tpublic static FontMetrics GetFontMetrics(\n\t\t\t\tGraphics graphics,\n\t\t\t\tFont font)\n\t\t\t{\n\t\t\t\treturn new FontMetricsImpl(graphics, font);\n\t\t\t}\n\t\t}\n\n        public enum RectangleEdgeFilter\n        {\n            None = 0,\n            TopLeft = 1,\n            TopRight = 2,\n            BottomLeft = 4,\n            BottomRight = 8,\n            All = TopLeft | TopRight | BottomLeft | BottomRight\n        }\n        public abstract class FontMetrics\n        {\n            public virtual int Height { get { return 0; } }\n            public virtual int Ascent { get { return 0; } }\n            public virtual int Descent { get { return 0; } }\n            public virtual int InternalLeading { get { return 0; } }\n            public virtual int ExternalLeading { get { return 0; } }\n            public virtual int AverageCharacterWidth { get { return 0; } }\n            public virtual int MaximumCharacterWidth { get { return 0; } }\n            public virtual int Weight { get { return 0; } }\n            public virtual int Overhang { get { return 0; } }\n            public virtual int DigitizedAspectX { get { return 0; } }\n            public virtual int DigitizedAspectY { get { return 0; } }\n        }\n\t}\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls.Drawing/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// 有关程序集的常规信息通过以下\n// 特性集控制。更改这些特性值可修改\n// 与程序集关联的信息。\n[assembly: AssemblyTitle(\"Sheng.Winform.Controls.Drawing\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"sheng.c\")]\n[assembly: AssemblyProduct(\"Sheng.Winform.Controls.Drawing\")]\n[assembly: AssemblyCopyright(\"Copyright © sheng.c 2010\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// 将 ComVisible 设置为 false 使此程序集中的类型\n// 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型，\n// 则将该类型上的 ComVisible 特性设置为 true。\n[assembly: ComVisible(false)]\n\n// 如果此项目向 COM 公开，则下列 GUID 用于类型库的 ID\n[assembly: Guid(\"a22cba9a-9dc0-4c3c-bd34-8c681a3f0d7f\")]\n\n// 程序集的版本信息由下面四个值组成:\n//\n//      主版本\n//      次版本 \n//      内部版本号\n//      修订号\n//\n// 可以指定所有这些值，也可以使用“内部版本号”和“修订号”的默认值，\n// 方法是按如下所示使用“*”:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "Sheng.Winform.Controls.Drawing/Sheng.Winform.Controls.Drawing.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <PropertyGroup>\r\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\r\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\r\n    <ProductVersion>8.0.30703</ProductVersion>\r\n    <SchemaVersion>2.0</SchemaVersion>\r\n    <ProjectGuid>{BCD80096-7B6F-4273-A031-186A610C84E5}</ProjectGuid>\r\n    <OutputType>Library</OutputType>\r\n    <AppDesignerFolder>Properties</AppDesignerFolder>\r\n    <RootNamespace>Sheng.Winform.Controls.Drawing</RootNamespace>\r\n    <AssemblyName>Sheng.Winform.Controls.Drawing</AssemblyName>\r\n    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>\r\n    <FileAlignment>512</FileAlignment>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\r\n    <DebugSymbols>true</DebugSymbols>\r\n    <DebugType>full</DebugType>\r\n    <Optimize>false</Optimize>\r\n    <OutputPath>bin\\Debug\\</OutputPath>\r\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\r\n    <ErrorReport>prompt</ErrorReport>\r\n    <WarningLevel>4</WarningLevel>\r\n    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\r\n    <DebugType>pdbonly</DebugType>\r\n    <Optimize>true</Optimize>\r\n    <OutputPath>bin\\Release\\</OutputPath>\r\n    <DefineConstants>TRACE</DefineConstants>\r\n    <ErrorReport>prompt</ErrorReport>\r\n    <WarningLevel>4</WarningLevel>\r\n  </PropertyGroup>\r\n  <ItemGroup>\r\n    <Reference Include=\"System\" />\r\n    <Reference Include=\"System.Core\" />\r\n    <Reference Include=\"System.Drawing\" />\r\n    <Reference Include=\"System.Xml.Linq\" />\r\n    <Reference Include=\"System.Data.DataSetExtensions\" />\r\n    <Reference Include=\"System.Data\" />\r\n    <Reference Include=\"System.Xml\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <Compile Include=\"BmpAdjuster.cs\" />\r\n    <Compile Include=\"ColorRepresentationHelper.cs\" />\r\n    <Compile Include=\"DrawingTool.cs\" />\r\n    <Compile Include=\"GraphicsExtension.cs\" />\r\n    <Compile Include=\"GraphPlotting.cs\" />\r\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ProjectReference Include=\"..\\Localisation\\Sheng.SailingEase.Drawing.Localisation\\Drawing.Localisation.csproj\">\r\n      <Project>{5E6C6CAD-1818-420D-A296-19F71AE66B72}</Project>\r\n      <Name>Drawing.Localisation</Name>\r\n    </ProjectReference>\r\n  </ItemGroup>\r\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\r\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\r\n</Project>"
  },
  {
    "path": "Sheng.Winform.Controls.Drawing/Sheng.Winform.Controls.Drawing.csproj.user",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <PropertyGroup>\n    <ProjectView>ProjectFiles</ProjectView>\n  </PropertyGroup>\n</Project>"
  },
  {
    "path": "Sheng.Winform.Controls.Kernal/EnvironmentHelper.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing Sheng.Winform.Controls.Win32;\n\nnamespace Sheng.Winform.Controls.Kernal\n{\n    public static class EnvironmentHelper\n    {\n        /// <summary>\n        /// 是否支持 Windows Vista 以上的玻璃效果\n        /// </summary>\n        public static bool SupportAreo\n        {\n            get\n            {\n                if (Environment.OSVersion.Version.Major < 6)\n                {\n                    return false;\n                }\n\n                return true;\n            }\n        }\n\n        /// <summary>\n        /// 是否打开了玻璃效果\n        /// </summary>\n        public static bool DwmIsCompositionEnabled\n        {\n            get\n            {\n                return DwmApi.DwmIsCompositionEnabled();\n            }\n        }\n\n        /// <summary>\n        /// 获取应用程序主窗体\n        /// </summary>\n        public static System.Windows.Forms.Form MainForm\n        {\n            get;\n            set;\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls.Kernal/FastReflection/ConstructorInvoker.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Reflection;\nusing System.Linq.Expressions;\n\nnamespace Sheng.Winform.Controls.Kernal\n{\n    public interface IConstructorInvoker\n    {\n        object Invoke(params object[] parameters);\n    }\n\n    public class ConstructorInvoker : IConstructorInvoker\n    {\n        private Func<object[], object> m_invoker;\n\n        public ConstructorInfo ConstructorInfo { get; private set; }\n\n        public ConstructorInvoker(ConstructorInfo constructorInfo)\n        {\n            this.ConstructorInfo = constructorInfo;\n            this.m_invoker = InitializeInvoker(constructorInfo);\n        }\n\n        private Func<object[], object> InitializeInvoker(ConstructorInfo constructorInfo)\n        {\n            // Target: (object)new T((T0)parameters[0], (T1)parameters[1], ...)\n\n            // parameters to execute\n            var parametersParameter = Expression.Parameter(typeof(object[]), \"parameters\");\n\n            // build parameter list\n            var parameterExpressions = new List<Expression>();\n            var paramInfos = constructorInfo.GetParameters();\n            for (int i = 0; i < paramInfos.Length; i++)\n            {\n                // (Ti)parameters[i]\n                var valueObj = Expression.ArrayIndex(parametersParameter, Expression.Constant(i));\n                var valueCast = Expression.Convert(valueObj, paramInfos[i].ParameterType);\n\n                parameterExpressions.Add(valueCast);\n            }\n\n            // new T((T0)parameters[0], (T1)parameters[1], ...)\n            var instanceCreate = Expression.New(constructorInfo, parameterExpressions);\n\n            // (object)new T((T0)parameters[0], (T1)parameters[1], ...)\n            var instanceCreateCast = Expression.Convert(instanceCreate, typeof(object));\n\n            var lambda = Expression.Lambda<Func<object[], object>>(instanceCreateCast, parametersParameter);\n\n            return lambda.Compile();\n        }\n\n        public object Invoke(params object[] parameters)\n        {\n            return this.m_invoker(parameters);\n        }\n\n        #region IConstructorInvoker Members\n\n        object IConstructorInvoker.Invoke(params object[] parameters)\n        {\n            return this.Invoke(parameters);\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls.Kernal/FastReflection/ConstructorInvokerPool.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Reflection;\nusing System.Diagnostics;\n\nnamespace Sheng.Winform.Controls.Kernal\n{\n    public class ConstructorInvokerPool : FastReflectionPool<Type[], IConstructorInvoker>\n    {\n        public ConstructorInvokerPool()\n        {\n            CustomCompare = true;\n        }\n\n        protected override bool Compare(Type[] key1, Type[] key2)\n        {\n            return key1.SequenceEqual(key2);\n        }\n\n        protected override IConstructorInvoker Create(Type type, Type[] key)\n        {\n            if (type == null || key == null)\n            {\n                Debug.Assert(false, \"type 或 key 为空\");\n                throw new ArgumentNullException();\n            }\n\n            ConstructorInfo constructorInfo = type.GetConstructor(key);\n\n            if (constructorInfo == null)\n            {\n                Debug.Assert(false, \"没有指定的ConstructorInfo\");\n                throw new InvalidOperationException();\n            }\n\n            return new ConstructorInvoker(constructorInfo);\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls.Kernal/FastReflection/FastReflectionPool.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Reflection;\n\nnamespace Sheng.Winform.Controls.Kernal\n{\n    /*\n     *  想用 Dictionary<Type, Dictionary<object, TAccessor>>\n     *  因为用于获取类构造函数的方法， type.GetConstructor\n     *  接收的是一个Types数组，而一般的GetProperty,GetMethod接收的都是一个String\n     *  构造函数接收的是Types数组，光光用Types数组做为缓存的Key\n     *  是没意义的，因为两个同样内容的数组Eques是不会相同的，必须使用扩展方法判断数组的内容是否相同\n     *  所以用 GetAccessorKeyFunc 来专门为以Type数组做为缓存的构造函数Cache查找缓存中的key\n     *  但是用object的话，在构造函数缓存中定位key时，每次都要进行Type数组和object的转换\n     *  比较麻烦，也可能会消耗性能，FastReflection的目的就是追求高性能，\n     *  所以加一个TKeyType来标识key的类型\n     */\n    //这个缓存是全局的\n    public abstract class FastReflectionPool<TKeyType, TAccessor> : IFastReflectionPool<TKeyType,TAccessor>\n    {\n        private object _mutex = new object();\n\n        private Dictionary<Type, Dictionary<TKeyType, TAccessor>> _cache =\n            new Dictionary<Type, Dictionary<TKeyType, TAccessor>>();\n\n        private bool _customCompare = false;\n        public bool CustomCompare { get { return _customCompare; } set { _customCompare = value; } }\n        protected virtual bool Compare(TKeyType key1, TKeyType key2)\n        {\n            return false;\n        }\n\n        public TAccessor Get(Type type, TKeyType key)\n        {\n            TAccessor accessor;\n            Dictionary<TKeyType, TAccessor> accessorCache;\n\n            if (this._cache.TryGetValue(type, out accessorCache))\n            {\n                TKeyType accessorKey;\n                if (_customCompare)\n                {\n                    accessorKey = accessorCache.Keys.Single((k) => { return Compare(k, key); });\n                }\n                else\n                {\n                    accessorKey = key;\n                }\n\n                if (accessorCache.TryGetValue(key, out accessor))\n                {\n                    return accessor;\n                }\n            }\n\n            lock (_mutex)\n            {\n                if (this._cache.ContainsKey(type) == false)\n                {\n                    this._cache[type] = new Dictionary<TKeyType, TAccessor>();\n                }\n                \n                accessor = Create(type, key);\n                this._cache[type][key] = accessor;\n\n                return accessor;\n            }\n        }\n\n        protected abstract TAccessor Create(Type type, TKeyType key);\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls.Kernal/FastReflection/FieldAccessor.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Reflection;\nusing System.Linq.Expressions;\n\nnamespace Sheng.Winform.Controls.Kernal\n{\n    public interface IFieldAccessor\n    {\n        object GetValue(object instance);\n    }\n\n    public class FieldAccessor : IFieldAccessor\n    {\n        private Func<object, object> m_getter;\n\n        public FieldInfo FieldInfo { get; private set; }\n\n        public FieldAccessor(FieldInfo fieldInfo)\n        {\n            this.FieldInfo = fieldInfo;\n        }\n\n        private void InitializeGet(FieldInfo fieldInfo)\n        {\n            // target: (object)(((TInstance)instance).Field)\n\n            // preparing parameter, object type\n            var instance = Expression.Parameter(typeof(object), \"instance\");\n\n            // non-instance for static method, or ((TInstance)instance)\n            var instanceCast = fieldInfo.IsStatic ? null :\n                Expression.Convert(instance, fieldInfo.ReflectedType);\n\n            // ((TInstance)instance).Property\n            var fieldAccess = Expression.Field(instanceCast, fieldInfo);\n\n            // (object)(((TInstance)instance).Property)\n            var castFieldValue = Expression.Convert(fieldAccess, typeof(object));\n\n            // Lambda expression\n            var lambda = Expression.Lambda<Func<object, object>>(castFieldValue, instance);\n\n            this.m_getter = lambda.Compile();\n        }\n\n        public object GetValue(object instance)\n        {\n            return this.m_getter(instance);\n        }\n\n        #region IFieldAccessor Members\n\n        object IFieldAccessor.GetValue(object instance)\n        {\n            return this.GetValue(instance);\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls.Kernal/FastReflection/FieldAccessorPool.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Reflection;\nusing System.Diagnostics;\n\nnamespace Sheng.Winform.Controls.Kernal\n{\n    public class FieldAccessorPool : FastReflectionPool<string,IFieldAccessor>\n    {\n        protected override IFieldAccessor Create(Type type, string key)\n        {\n            if (type == null || String.IsNullOrEmpty(key))\n            {\n                Debug.Assert(false, \"type 或 key 为空\");\n                throw new ArgumentNullException();\n            }\n\n            FieldInfo fieldInfo = type.GetField(key);\n\n            if (fieldInfo == null)\n            {\n                Debug.Assert(false, \"没有指定的FieldInfo:\" + key);\n                throw new MissingFieldException(key);\n            }\n\n            return new FieldAccessor(fieldInfo);\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls.Kernal/FastReflection/IFastReflectionPool.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nnamespace Sheng.Winform.Controls.Kernal\n{\n    public interface IFastReflectionPool<TKeyType, TAccessor>\n    {\n        TAccessor Get(Type type, TKeyType key);\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls.Kernal/FastReflection/MethodInvoker.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Reflection;\nusing System.Linq.Expressions;\n\nnamespace Sheng.Winform.Controls.Kernal\n{\n    public interface IMethodInvoker\n    {\n        object Invoke(object instance, params object[] parameters);\n    }\n\n    public class MethodInvoker : IMethodInvoker\n    {\n        private Func<object, object[], object> m_invoker;\n\n        public MethodInfo MethodInfo { get; private set; }\n\n        public MethodInvoker(MethodInfo methodInfo)\n        {\n            this.MethodInfo = methodInfo;\n            this.m_invoker = CreateInvokeDelegate(methodInfo);\n        }\n\n        public object Invoke(object instance, params object[] parameters)\n        {\n            return this.m_invoker(instance, parameters);\n        }\n\n        private static Func<object, object[], object> CreateInvokeDelegate(MethodInfo methodInfo)\n        {\n            // Target: ((TInstance)instance).Method((T0)parameters[0], (T1)parameters[1], ...)\n\n            // parameters to execute\n            var instanceParameter = Expression.Parameter(typeof(object), \"instance\");\n            var parametersParameter = Expression.Parameter(typeof(object[]), \"parameters\");\n\n            // build parameter list\n            var parameterExpressions = new List<Expression>();\n            var paramInfos = methodInfo.GetParameters();\n            for (int i = 0; i < paramInfos.Length; i++)\n            {\n                // (Ti)parameters[i]\n                BinaryExpression valueObj = Expression.ArrayIndex(\n                    parametersParameter, Expression.Constant(i));\n                UnaryExpression valueCast = Expression.Convert(\n                    valueObj, paramInfos[i].ParameterType);\n\n                parameterExpressions.Add(valueCast);\n            }\n\n            // non-instance for static method, or ((TInstance)instance)\n            var instanceCast = methodInfo.IsStatic ? null :\n                Expression.Convert(instanceParameter, methodInfo.ReflectedType);\n\n            // static invoke or ((TInstance)instance).Method\n            var methodCall = Expression.Call(instanceCast, methodInfo, parameterExpressions);\n\n            // ((TInstance)instance).Method((T0)parameters[0], (T1)parameters[1], ...)\n            if (methodCall.Type == typeof(void))\n            {\n                var lambda = Expression.Lambda<Action<object, object[]>>(\n                        methodCall, instanceParameter, parametersParameter);\n\n                Action<object, object[]> execute = lambda.Compile();\n                return (instance, parameters) =>\n                {\n                    execute(instance, parameters);\n                    return null;\n                };\n            }\n            else\n            {\n                var castMethodCall = Expression.Convert(methodCall, typeof(object));\n                var lambda =Expression.Lambda<Func<object, object[], object>>(\n                    castMethodCall, instanceParameter, parametersParameter);\n\n                return lambda.Compile();\n            }\n        }\n\n        #region IMethodInvoker Members\n\n        object IMethodInvoker.Invoke(object instance, params object[] parameters)\n        {\n            return this.Invoke(instance, parameters);\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls.Kernal/FastReflection/MethodInvokerPool.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Reflection;\nusing System.Diagnostics;\n\nnamespace Sheng.Winform.Controls.Kernal\n{\n    public class MethodInvokerPool : FastReflectionPool<string,IMethodInvoker>\n    {\n        protected override IMethodInvoker Create(Type type, string key)\n        {\n            if (type == null || String.IsNullOrEmpty(key))\n            {\n                Debug.Assert(false, \"type 或 key 为空\");\n                throw new ArgumentNullException();\n            }\n\n            MethodInfo methodInfo = type.GetMethod(key);\n\n            if (methodInfo == null)\n            {\n                Debug.Assert(false, \"没有指定的MethodInfo:\" + key);\n                throw new MissingMemberException(key);\n            }\n\n            return new MethodInvoker(methodInfo);\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls.Kernal/FastReflection/PropertyAccessor.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Linq.Expressions;\nusing System.Reflection;\n\nnamespace Sheng.Winform.Controls.Kernal\n{\n    public interface IPropertyAccessor\n    {\n        object GetValue(object instance);\n\n        void SetValue(object instance, object value);\n    }\n\n    public class PropertyAccessor : IPropertyAccessor\n    {\n        private Func<object, object> m_getter;\n        private MethodInvoker m_setMethodInvoker;\n\n        public PropertyInfo PropertyInfo { get; private set; }\n\n        public PropertyAccessor(PropertyInfo propertyInfo)\n        {\n            this.PropertyInfo = propertyInfo;\n            this.InitializeGet(propertyInfo);\n            this.InitializeSet(propertyInfo);\n        }\n\n        private void InitializeGet(PropertyInfo propertyInfo)\n        {\n            if (!propertyInfo.CanRead) return;\n\n            // Target: (object)(((TInstance)instance).Property)\n\n            // preparing parameter, object type\n            var instance = Expression.Parameter(typeof(object), \"instance\");\n\n            // non-instance for static method, or ((TInstance)instance)\n            var instanceCast = propertyInfo.GetGetMethod(true).IsStatic ? null :\n                Expression.Convert(instance, propertyInfo.ReflectedType);\n\n            // ((TInstance)instance).Property\n            var propertyAccess = Expression.Property(instanceCast, propertyInfo);\n\n            // (object)(((TInstance)instance).Property)\n            var castPropertyValue = Expression.Convert(propertyAccess, typeof(object));\n\n            // Lambda expression\n            var lambda = Expression.Lambda<Func<object, object>>(castPropertyValue, instance);\n\n            this.m_getter = lambda.Compile();\n        }\n\n        private void InitializeSet(PropertyInfo propertyInfo)\n        {\n            if (!propertyInfo.CanWrite) return;\n            this.m_setMethodInvoker = new MethodInvoker(propertyInfo.GetSetMethod(true));\n        }\n\n        public object GetValue(object o)\n        {\n            if (this.m_getter == null)\n            {\n                throw new NotSupportedException(\"Get method is not defined for this property.\");\n            }\n\n            return this.m_getter(o);\n        }\n\n        public void SetValue(object o, object value)\n        {\n            if (this.m_setMethodInvoker == null)\n            {\n                throw new NotSupportedException(\"Set method is not defined for this property.\");\n            }\n\n            this.m_setMethodInvoker.Invoke(o, new object[] { value });\n        }\n\n        #region IPropertyAccessor Members\n\n        object IPropertyAccessor.GetValue(object instance)\n        {\n            return this.GetValue(instance);\n        }\n\n        void IPropertyAccessor.SetValue(object instance, object value)\n        {\n            this.SetValue(instance, value);\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls.Kernal/FastReflection/PropertyAccessorPool.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Reflection;\nusing System.Diagnostics;\n\nnamespace Sheng.Winform.Controls.Kernal\n{\n    public class PropertyAccessorPool : FastReflectionPool<string,IPropertyAccessor>\n    {\n        protected override IPropertyAccessor Create(Type type, string key)\n        {\n            if (type == null || String.IsNullOrEmpty(key))\n            {\n                Debug.Assert(false, \"type 或 key 为空\");\n                throw new ArgumentNullException();\n            }\n\n            PropertyInfo propertyInfo = type.GetProperty(key);\n\n            if (propertyInfo == null)\n            {\n                Debug.Assert(false, \"没有指定的PropertyInfo:\" + key);\n                throw new MissingMemberException(key);\n            }\n\n            return new PropertyAccessor(propertyInfo);\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls.Kernal/FastReflection/ReflectionPool.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Diagnostics;\n\nnamespace Sheng.Winform.Controls.Kernal\n{\n    public static class ReflectionPool\n    {\n        private static ConstructorInvokerPool _constructorInvokerPool = new ConstructorInvokerPool();\n\n        private static FieldAccessorPool _fieldAccessorPool = new FieldAccessorPool();\n\n        private static MethodInvokerPool _methodInvokerPool = new MethodInvokerPool();\n\n        private static PropertyAccessorPool _propertyAccessorPool = new PropertyAccessorPool();\n\n        static ReflectionPool()\n        {\n        }\n\n        public static object GetPropertyValue(object instance, string propertyName)\n        {\n            if (instance == null || String.IsNullOrEmpty(propertyName))\n            {\n                Debug.Assert(false, \"instance 或 propertyName 为空\");\n                throw new ArgumentNullException();\n            }\n\n            return _propertyAccessorPool.Get(instance.GetType(), propertyName).GetValue(instance);\n        }\n\n        public static void SetPropertyValue(object instance, string propertyName, object value)\n        {\n            if (instance == null || String.IsNullOrEmpty(propertyName))\n            {\n                Debug.Assert(false, \"instance 或 propertyName 为空\");\n                throw new ArgumentNullException();\n            }\n\n            _propertyAccessorPool.Get(instance.GetType(), propertyName).SetValue(instance, value);\n        }\n\n        public static object GetFieldValue(object instance, string fieldName)\n        {\n            if (instance == null || String.IsNullOrEmpty(fieldName))\n            {\n                Debug.Assert(false, \"instance 或 fieldName 为空\");\n                throw new ArgumentNullException();\n            }\n\n            return _fieldAccessorPool.Get(instance.GetType(), fieldName).GetValue(instance);\n        }\n\n        public static object GetMethodValue(object instance, string methodName)\n        {\n            if (instance == null || String.IsNullOrEmpty(methodName))\n            {\n                Debug.Assert(false, \"instance 或 methodName 为空\");\n                throw new ArgumentNullException();\n            }\n\n            return _methodInvokerPool.Get(instance.GetType(), methodName).Invoke(instance);\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls.Kernal/ImageAndTypeMappingCodon.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Drawing;\n\nnamespace Sheng.Winform.Controls.Kernal\n{\n    public class ImageAndTypeMappingCodon\n    {\n        private Type _dataBoundType;\n        /// <summary>\n        /// 所对应的绑定数据类型\n        /// </summary>\n        public Type DataBoundType\n        {\n            get { return _dataBoundType; }\n            set { _dataBoundType = value; }\n        }\n\n        private bool _actOnSubClass = false;\n        /// <summary>\n        /// 是否对 DataBoundType 的子类型有效\n        /// 默认无效\n        /// 如果设置为 true，又同时添加了基类与子类的 codon，则运行时会取到哪个codon不确定\n        /// 通常取先添加的那个\n        /// </summary>\n        public bool ActOnSubClass\n        {\n            get { return _actOnSubClass; }\n            set { _actOnSubClass = value; }\n        }\n\n        private Image _image;\n        public Image Image\n        {\n            get { return _image; }\n            set { _image = value; }\n        }\n\n        public ImageAndTypeMappingCodon(Type dataBoundType, Image image)\n            : this(dataBoundType, image, false)\n        {\n\n        }\n\n        public ImageAndTypeMappingCodon(Type dataBoundType, Image image, bool actOnSubClass)\n        {\n            _dataBoundType = dataBoundType;\n            _image = image;\n            _actOnSubClass = actOnSubClass;\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls.Kernal/Localisation/LocalisationHelper.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Resources;\nusing System.Text.RegularExpressions;\nusing System.Windows.Forms;\n\nnamespace Sheng.Winform.Controls.Kernal\n{\n    public class LocalisationHelper\n    {\n        #region 私有成员\n\n        private ResourceManager _resourceManager;\n\n        //TODO:匹配窗体元素的正则没有使用零宽断言这一技术，有时间改进一下\n        //取${}花括号中间的字符串\n        /*\n         * 这是一个使用了零宽断言的表达式\n         * (?<=exp)\t匹配exp后面的位置\n         * (?=exp)\t匹配exp前面的位置\n         * * 重复零次或更多次\n         * +\t重复一次或更多次\n         * ?\t重复零次或一次\n         * {n}\t重复n次\n         * {n,}\t重复n次或更多次\n         * {n,m}\t重复n到m次\n         */\n        private readonly static Regex patternInner = new Regex(@\"(?<=\\${)([^\\}]*)?(?=\\})\",\n            RegexOptions.Compiled | RegexOptions.CultureInvariant);\n\n        //取${}形式的完整字符串\n        private readonly static Regex pattern = new Regex(@\"\\$\\{[^\\}]+\\}\",\n           RegexOptions.Compiled | RegexOptions.CultureInvariant);\n\n        #endregion\n\n        #region 构造\n\n        public LocalisationHelper(ResourceManager resourceManager)\n        {\n            _resourceManager = resourceManager;\n        }\n\n        #endregion\n\n        #region 公开方法\n\n        public string GetString(string name)\n        {\n            return _resourceManager.GetString(name);\n        }\n\n        /// <summary>\n        /// 如果输入的字符串包含 \"${...}\" 这样的格式,则认为是指代资源文件中的一个字符串资源\n        /// </summary>\n        /// <param name=\"input\"></param>\n        /// <returns></returns>\n        public string Parse(string input)\n        {\n            if (input == null)\n                return String.Empty;\n\n            string result = input;\n            string resString;\n            MatchCollection matchs = pattern.Matches(input);\n            foreach (Match match in matchs)\n            {\n                resString = GetString(patternInner.Match(match.Value).Value);\n                //防止界面上的${}串写错没有取到对应的资源文本\n                if (resString != null)\n                {\n                    resString = resString.Replace(\"$NewLine$\", System.Environment.NewLine);\n                    result = result.Replace(match.Value, resString);\n                }\n                else\n                {\n                    //用一条斜杠表示没有拿到资源，以访问在一个大字符串中有没拿到的资源一时看不到\n                    result = result.Replace(match.Value, \"/\");\n                }\n            }\n\n            return result;\n        }\n\n        #region ApplyResource , 为界面应用语言文本资源\n\n        public void ApplyResource(UserControl userControl)\n        {\n            userControl.Text = Parse(userControl.Text);\n\n            foreach (Control control in userControl.Controls)\n            {\n                ApplyResource(control);\n            }\n        }\n\n        public void ApplyResource(Form form)\n        {\n            form.Text = Parse(form.Text);\n\n            foreach (Control control in form.Controls)\n            {\n                ApplyResource(control);\n            }\n        }\n\n        public void ApplyResource(Control control)\n        {\n            control.Text = Parse(control.Text);\n\n            if (control.Controls != null)\n            {\n                foreach (Control ctrl in control.Controls)\n                {\n                    ApplyResource(ctrl);\n                }\n            }\n\n            if (control.ContextMenuStrip != null)\n            {\n                ContextMenuStrip contextMenuStrip = control.ContextMenuStrip as ContextMenuStrip;\n                ApplyResource(contextMenuStrip);\n            }\n\n            //如果是datagridview,为列头文本应用资料\n            if (control is DataGridView)\n            {\n                DataGridView dataGridView = control as DataGridView;\n                ApplyResource(dataGridView);\n            }\n\n            if (control is ToolStrip)\n            {\n                ToolStrip toolStrip = control as ToolStrip;\n                ApplyResource(toolStrip);\n            }\n        }\n\n        public void ApplyResource(DataGridView dataGridView)\n        {\n            foreach (DataGridViewColumn column in dataGridView.Columns)\n            {\n                column.HeaderText = Parse(column.HeaderText);\n            }\n        }\n\n        public void ApplyResource(ToolStrip toolStrip)\n        {\n             foreach (System.Windows.Forms.ToolStripItem item in toolStrip.Items)\n            {\n                item.Text = Parse(item.Text);\n                if (item is ToolStripDropDownItem)\n                {\n                    ToolStripDropDownItem toolStripDropDownItem = item as ToolStripDropDownItem;\n                    ApplyResource(toolStripDropDownItem.DropDownItems);\n                }\n            }\n        }\n\n        public void ApplyResource(ContextMenuStrip contextMenuStrip)\n        {\n            ApplyResource(contextMenuStrip.Items);\n        }\n\n        public void ApplyResource(ToolStripItemCollection items)\n        {\n            foreach (System.Windows.Forms.ToolStripItem item in items)\n            {\n                item.Text = Parse(item.Text);\n                if (item is ToolStripMenuItem)\n                {\n                    ToolStripMenuItem toolStripMenuItem = item as ToolStripMenuItem;\n                    ApplyResource(toolStripMenuItem.DropDownItems);\n                }\n            }\n        }\n\n        #endregion\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls.Kernal/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// 有关程序集的常规信息通过以下\n// 特性集控制。更改这些特性值可修改\n// 与程序集关联的信息。\n[assembly: AssemblyTitle(\"Sheng.Winform.Controls.Kernal\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"sheng.c\")]\n[assembly: AssemblyProduct(\"Sheng.Winform.Controls.Kernal\")]\n[assembly: AssemblyCopyright(\"Copyright © sheng.c 2010\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// 将 ComVisible 设置为 false 使此程序集中的类型\n// 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型，\n// 则将该类型上的 ComVisible 特性设置为 true。\n[assembly: ComVisible(false)]\n\n// 如果此项目向 COM 公开，则下列 GUID 用于类型库的 ID\n[assembly: Guid(\"99c52ab8-65dd-43c8-aea1-33c4c5ec3fe5\")]\n\n// 程序集的版本信息由下面四个值组成:\n//\n//      主版本\n//      次版本 \n//      内部版本号\n//      修订号\n//\n// 可以指定所有这些值，也可以使用“内部版本号”和“修订号”的默认值，\n// 方法是按如下所示使用“*”:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "Sheng.Winform.Controls.Kernal/Sheng.Winform.Controls.Kernal.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <PropertyGroup>\r\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\r\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\r\n    <ProductVersion>8.0.30703</ProductVersion>\r\n    <SchemaVersion>2.0</SchemaVersion>\r\n    <ProjectGuid>{125FB802-2C83-47DC-BA57-910064355CCD}</ProjectGuid>\r\n    <OutputType>Library</OutputType>\r\n    <AppDesignerFolder>Properties</AppDesignerFolder>\r\n    <RootNamespace>Sheng.Winform.Controls.Kernal</RootNamespace>\r\n    <AssemblyName>Sheng.Winform.Controls.Kernal</AssemblyName>\r\n    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>\r\n    <FileAlignment>512</FileAlignment>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\r\n    <DebugSymbols>true</DebugSymbols>\r\n    <DebugType>full</DebugType>\r\n    <Optimize>false</Optimize>\r\n    <OutputPath>bin\\Debug\\</OutputPath>\r\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\r\n    <ErrorReport>prompt</ErrorReport>\r\n    <WarningLevel>4</WarningLevel>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\r\n    <DebugType>pdbonly</DebugType>\r\n    <Optimize>true</Optimize>\r\n    <OutputPath>bin\\Release\\</OutputPath>\r\n    <DefineConstants>TRACE</DefineConstants>\r\n    <ErrorReport>prompt</ErrorReport>\r\n    <WarningLevel>4</WarningLevel>\r\n  </PropertyGroup>\r\n  <ItemGroup>\r\n    <Reference Include=\"System\" />\r\n    <Reference Include=\"System.Core\" />\r\n    <Reference Include=\"System.Drawing\" />\r\n    <Reference Include=\"System.Management\" />\r\n    <Reference Include=\"System.Windows.Forms\" />\r\n    <Reference Include=\"System.Xml.Linq\" />\r\n    <Reference Include=\"System.Data.DataSetExtensions\" />\r\n    <Reference Include=\"System.Data\" />\r\n    <Reference Include=\"System.Xml\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <Compile Include=\"EnvironmentHelper.cs\" />\r\n    <Compile Include=\"FastReflection\\ConstructorInvoker.cs\" />\r\n    <Compile Include=\"FastReflection\\ConstructorInvokerPool.cs\" />\r\n    <Compile Include=\"FastReflection\\FastReflectionPool.cs\" />\r\n    <Compile Include=\"FastReflection\\FieldAccessor.cs\" />\r\n    <Compile Include=\"FastReflection\\FieldAccessorPool.cs\" />\r\n    <Compile Include=\"FastReflection\\IFastReflectionPool.cs\" />\r\n    <Compile Include=\"FastReflection\\MethodInvoker.cs\" />\r\n    <Compile Include=\"FastReflection\\MethodInvokerPool.cs\" />\r\n    <Compile Include=\"FastReflection\\PropertyAccessor.cs\" />\r\n    <Compile Include=\"FastReflection\\PropertyAccessorPool.cs\" />\r\n    <Compile Include=\"FastReflection\\ReflectionPool.cs\" />\r\n    <Compile Include=\"ImageAndTypeMappingCodon.cs\" />\r\n    <Compile Include=\"Localisation\\LocalisationHelper.cs\" />\r\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ProjectReference Include=\"..\\Sheng.Winform.Controls.Win32\\Sheng.Winform.Controls.Win32.csproj\">\r\n      <Project>{946FFB43-4864-4967-8D69-8716CDA83F7A}</Project>\r\n      <Name>Sheng.Winform.Controls.Win32</Name>\r\n    </ProjectReference>\r\n  </ItemGroup>\r\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\r\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\r\n</Project>"
  },
  {
    "path": "Sheng.Winform.Controls.Kernal/Sheng.Winform.Controls.Kernal.csproj.user",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <PropertyGroup>\r\n    <ProjectView>ProjectFiles</ProjectView>\r\n  </PropertyGroup>\r\n</Project>"
  },
  {
    "path": "Sheng.Winform.Controls.Localisation/Chinese (Simplified).Designer.cs",
    "content": "//------------------------------------------------------------------------------\n// <auto-generated>\n//     此代码由工具生成。\n//     运行时版本:2.0.50727.4927\n//\n//     对此文件的更改可能会导致不正确的行为，并且如果\n//     重新生成代码，这些更改将会丢失。\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nnamespace Sheng.Winform.Controls.Localisation {\n    using System;\n    \n    \n    /// <summary>\n    ///   强类型资源类，用于查找本地化字符串等。\n    /// </summary>\n    // 此类是由 StronglyTypedResourceBuilder\n    // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。\n    // 若要添加或移除成员，请编辑 .ResX 文件，然后重新运行 ResGen\n    // (以 /str 作为命令选项)，或重新生成 VS 项目。\n    [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Resources.Tools.StronglyTypedResourceBuilder\", \"2.0.0.0\")]\n    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\n    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]\n    public class Chinese__Simplified_ : ILanguage {\n        \n        private global::System.Resources.ResourceManager resourceMan;\n        \n        private global::System.Globalization.CultureInfo resourceCulture;\n        \n        public Chinese__Simplified_() {\n        }\n        \n        /// <summary>\n        ///   返回此类使用的缓存 ResourceManager 实例。\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        public global::System.Resources.ResourceManager ResourceManager {\n            get {\n                if (object.ReferenceEquals(resourceMan, null)) {\n                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager(\"Sheng.Winform.Controls.Localisation.Chinese (Simplified)\", typeof(Chinese__Simplified_).Assembly);\n                    resourceMan = temp;\n                }\n                return resourceMan;\n            }\n        }\n        \n        /// <summary>\n        ///   为使用此强类型资源类的所有资源查找\n        ///   重写当前线程的 CurrentUICulture 属性。\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        public global::System.Globalization.CultureInfo Culture {\n            get {\n                if (object.ReferenceEquals(resourceCulture, null)) {\n                    global::System.Globalization.CultureInfo temp = new global::System.Globalization.CultureInfo(\"zh-CHS\");\n                    resourceCulture = temp;\n                }\n                return resourceCulture;\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 消息 的本地化字符串。\n        /// </summary>\n        public string MessageBoxCaptiton_Message {\n            get {\n                return ResourceManager.GetString(\"MessageBoxCaptiton_Message\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 底部 的本地化字符串。\n        /// </summary>\n        public string SEPaginationDataGridView_EnumNavigationLocation_Bottom {\n            get {\n                return ResourceManager.GetString(\"SEPaginationDataGridView_EnumNavigationLocation_Bottom\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 顶部 的本地化字符串。\n        /// </summary>\n        public string SEPaginationDataGridView_EnumNavigationLocation_Top {\n            get {\n                return ResourceManager.GetString(\"SEPaginationDataGridView_EnumNavigationLocation_Top\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 更大 (48x48) 的本地化字符串。\n        /// </summary>\n        public string SEToolStripImageSize_ExtraLarge {\n            get {\n                return ResourceManager.GetString(\"SEToolStripImageSize_ExtraLarge\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 大 (32x32) 的本地化字符串。\n        /// </summary>\n        public string SEToolStripImageSize_Large {\n            get {\n                return ResourceManager.GetString(\"SEToolStripImageSize_Large\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 中 (24x24) 的本地化字符串。\n        /// </summary>\n        public string SEToolStripImageSize_Medium {\n            get {\n                return ResourceManager.GetString(\"SEToolStripImageSize_Medium\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 小 (16x16) 的本地化字符串。\n        /// </summary>\n        public string SEToolStripImageSize_Small {\n            get {\n                return ResourceManager.GetString(\"SEToolStripImageSize_Small\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///  Returns true if the current language is the default language.\n        /// </summary>\n        public bool IsDefault {\n            get {\n                return false;\n            }\n        }\n        \n        /// <summary>\n        ///  Returns a System.String that represents the current System.Object.\n        /// </summary>\n        public override string ToString() {\n            return Culture.EnglishName;\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls.Localisation/Chinese (Simplified).resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"MessageBoxCaptiton_Message\" xml:space=\"preserve\">\n    <value>消息</value>\n  </data>\n  <data name=\"SEToolStripImageSize_Small\" xml:space=\"preserve\">\n    <value>小 (16x16)</value>\n  </data>\n  <data name=\"SEToolStripImageSize_Medium\" xml:space=\"preserve\">\n    <value>中 (24x24)</value>\n  </data>\n  <data name=\"SEToolStripImageSize_Large\" xml:space=\"preserve\">\n    <value>大 (32x32)</value>\n  </data>\n  <data name=\"SEToolStripImageSize_ExtraLarge\" xml:space=\"preserve\">\n    <value>更大 (48x48)</value>\n  </data>\n  <data name=\"SEPaginationDataGridView_EnumNavigationLocation_Bottom\" xml:space=\"preserve\">\n    <value>底部</value>\n  </data>\n  <data name=\"SEPaginationDataGridView_EnumNavigationLocation_Top\" xml:space=\"preserve\">\n    <value>顶部</value>\n  </data>\n</root>"
  },
  {
    "path": "Sheng.Winform.Controls.Localisation/ILanguage.cs",
    "content": "//------------------------------------------------------------------------------\n// <auto-generated>\n//     此代码由工具生成。\n//     运行时版本:2.0.50727.4927\n//\n//     对此文件的更改可能会导致不正确的行为，并且如果\n//     重新生成代码，这些更改将会丢失。\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nnamespace Sheng.Winform.Controls.Localisation {\n    \n    \n    public interface ILanguage {\n        \n        /// <summary>\n        ///   返回此类使用的缓存 ResourceManager 实例。\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        global::System.Resources.ResourceManager ResourceManager {\n            get;\n        }\n        \n        /// <summary>\n        ///   为使用此强类型资源类的所有资源查找\n        ///   重写当前线程的 CurrentUICulture 属性。\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        global::System.Globalization.CultureInfo Culture {\n            get;\n        }\n        \n        /// <summary>\n        ///   查找类似 消息 的本地化字符串。\n        /// </summary>\n        string MessageBoxCaptiton_Message {\n            get;\n        }\n        \n        /// <summary>\n        ///   查找类似 底部 的本地化字符串。\n        /// </summary>\n        string SEPaginationDataGridView_EnumNavigationLocation_Bottom {\n            get;\n        }\n        \n        /// <summary>\n        ///   查找类似 顶部 的本地化字符串。\n        /// </summary>\n        string SEPaginationDataGridView_EnumNavigationLocation_Top {\n            get;\n        }\n        \n        /// <summary>\n        ///   查找类似 更大 (48x48) 的本地化字符串。\n        /// </summary>\n        string SEToolStripImageSize_ExtraLarge {\n            get;\n        }\n        \n        /// <summary>\n        ///   查找类似 大 (32x32) 的本地化字符串。\n        /// </summary>\n        string SEToolStripImageSize_Large {\n            get;\n        }\n        \n        /// <summary>\n        ///   查找类似 中 (24x24) 的本地化字符串。\n        /// </summary>\n        string SEToolStripImageSize_Medium {\n            get;\n        }\n        \n        /// <summary>\n        ///   查找类似 小 (16x16) 的本地化字符串。\n        /// </summary>\n        string SEToolStripImageSize_Small {\n            get;\n        }\n        \n        /// <summary>\n        ///  Returns true if the current language is the default language.\n        /// </summary>\n        bool IsDefault {\n            get;\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls.Localisation/Language.cs",
    "content": "//------------------------------------------------------------------------------\n// <auto-generated>\n//     此代码由工具生成。\n//     运行时版本:2.0.50727.3082\n//\n//     对此文件的更改可能会导致不正确的行为，并且如果\n//     重新生成代码，这些更改将会丢失。\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nusing System.Text.RegularExpressions;\nusing System.Resources;\nnamespace Sheng.Winform.Controls.Localisation {\n    \n    \n    public class Language {\n        \n        private static ILanguage _Language;\n        \n        private Language() {\n        }\n        \n        /// <summary>\n        ///  Call GetLanguages() to retrieve a list of possible languages that can be used to set this property.\n        ///  The default value is the default language.\n        /// </summary>\n        public static ILanguage Current {\n            get {\n                if ((_Language == null)) {\n                    //System.Collections.Generic.List<ILanguage> list = Language.GetLanguages();\n                    //for (int i = 0; (i < list.Count); i = (i + 1)) {\n                    //    if (list[i].IsDefault) {\n                    //        _Language = list[i];\n                    //        return _Language;\n                    //    }\n                    //}\n\n                    _Language = new Chinese__Simplified_();\n                }\n                return _Language;\n            }\n            set {\n                _Language = value;\n            }\n        }\n        \n        /// <summary>\n        ///  Gets a list of available languages defined in this assembly.\n        /// </summary>\n        public static System.Collections.Generic.List<ILanguage> GetLanguages() {\n            System.Collections.Generic.List<ILanguage> items = new System.Collections.Generic.List<ILanguage>();\n            System.Type[] exportedTypes = System.Reflection.Assembly.GetExecutingAssembly().GetExportedTypes();\n            for (int i = 0; (i < exportedTypes.Length); i = (i + 1)) {\n                if (exportedTypes[i].IsClass) {\n                    if ((exportedTypes[i].GetInterface(\"ILanguage\") != null)) {\n                        try {\n                            object obj = System.Activator.CreateInstance(exportedTypes[i]);\n                            ILanguage interfaceReference = ((ILanguage)(obj));\n                            if ((interfaceReference != null)) {\n                                items.Add(interfaceReference);\n                            }\n                        }\n                        catch (System.Exception ) {\n                        }\n                    }\n                }\n            }\n            return items;\n        }\n\n\n        public static string GetString(string name)\n        {\n            return Current.ResourceManager.GetString(name);\n        }\n\n        //取${}花括号中间的字符串\n        readonly static Regex patternInner = new Regex(@\"(?<=\\${)([^\\}]*)?(?=\\})\",\n            RegexOptions.Compiled | RegexOptions.CultureInvariant);\n\n        //取${}形式的完整字符串\n        readonly static Regex pattern = new Regex(@\"\\$\\{[^\\}]+\\}\",\n           RegexOptions.Compiled | RegexOptions.CultureInvariant);\n        /// <summary>\n        /// 如果输入的字符串包含 \"${...}\" 这样的格式,则认为是指代资源文件中的一个字符串资源\n        /// </summary>\n        /// <param name=\"input\"></param>\n        /// <returns></returns>\n        public static string Parse(string input)\n        {\n            if (input == null)\n            {\n                return null;\n            }\n\n            string result = input;\n            string resString;\n            MatchCollection matchs = pattern.Matches(input);\n            foreach (Match match in matchs)\n            {\n                resString = GetString(patternInner.Match(match.Value).Value);\n                resString = resString.Replace(\"$NewLine$\", System.Environment.NewLine);\n                result = result.Replace(match.Value, resString);\n            }\n\n            return result;\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls.Localisation/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// 有关程序集的常规信息通过以下\n// 特性集控制。更改这些特性值可修改\n// 与程序集关联的信息。\n[assembly: AssemblyTitle(\"Sheng.Winform.Controls.Localisation\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"sheng.c\")]\n[assembly: AssemblyProduct(\"Sheng.Winform.Controls.Localisation\")]\n[assembly: AssemblyCopyright(\"Copyright © sheng.c 2010\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// 将 ComVisible 设置为 false 使此程序集中的类型\n// 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型，\n// 则将该类型上的 ComVisible 特性设置为 true。\n[assembly: ComVisible(false)]\n\n// 如果此项目向 COM 公开，则下列 GUID 用于类型库的 ID\n[assembly: Guid(\"4f1ce980-4891-4c1c-b5c4-2e6289d02858\")]\n\n// 程序集的版本信息由下面四个值组成:\n//\n//      主版本\n//      次版本 \n//      内部版本号\n//      修订号\n//\n// 可以指定所有这些值，也可以使用“内部版本号”和“修订号”的默认值，\n// 方法是按如下所示使用“*”:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "Sheng.Winform.Controls.Localisation/Sheng.Winform.Controls.Localisation.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <PropertyGroup>\r\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\r\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\r\n    <ProductVersion>8.0.30703</ProductVersion>\r\n    <SchemaVersion>2.0</SchemaVersion>\r\n    <ProjectGuid>{E0B8AD36-CC90-41F5-BD00-EC614569C9F9}</ProjectGuid>\r\n    <OutputType>Library</OutputType>\r\n    <AppDesignerFolder>Properties</AppDesignerFolder>\r\n    <RootNamespace>Sheng.Winform.Controls.Localisation</RootNamespace>\r\n    <AssemblyName>Sheng.Winform.Controls.Localisation</AssemblyName>\r\n    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>\r\n    <FileAlignment>512</FileAlignment>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\r\n    <DebugSymbols>true</DebugSymbols>\r\n    <DebugType>full</DebugType>\r\n    <Optimize>false</Optimize>\r\n    <OutputPath>bin\\Debug\\</OutputPath>\r\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\r\n    <ErrorReport>prompt</ErrorReport>\r\n    <WarningLevel>4</WarningLevel>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\r\n    <DebugType>pdbonly</DebugType>\r\n    <Optimize>true</Optimize>\r\n    <OutputPath>bin\\Release\\</OutputPath>\r\n    <DefineConstants>TRACE</DefineConstants>\r\n    <ErrorReport>prompt</ErrorReport>\r\n    <WarningLevel>4</WarningLevel>\r\n  </PropertyGroup>\r\n  <ItemGroup>\r\n    <Reference Include=\"System\" />\r\n    <Reference Include=\"System.Core\" />\r\n    <Reference Include=\"System.Xml.Linq\" />\r\n    <Reference Include=\"System.Data.DataSetExtensions\" />\r\n    <Reference Include=\"System.Data\" />\r\n    <Reference Include=\"System.Xml\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <Compile Include=\"Chinese %28Simplified%29.Designer.cs\" />\r\n    <Compile Include=\"ILanguage.cs\" />\r\n    <Compile Include=\"Language.cs\" />\r\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <EmbeddedResource Include=\"Chinese %28Simplified%29.resx\" />\r\n  </ItemGroup>\r\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\r\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\r\n</Project>"
  },
  {
    "path": "Sheng.Winform.Controls.Localisation/Sheng.Winform.Controls.Localisation.csproj.user",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <PropertyGroup>\n    <ProjectView>ProjectFiles</ProjectView>\n  </PropertyGroup>\n</Project>"
  },
  {
    "path": "Sheng.Winform.Controls.Win32/DwmApi.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Runtime.InteropServices;\nusing System.Drawing;\n\nnamespace Sheng.Winform.Controls.Win32\n{\n    public class DwmApi\n    {\n         [DllImport(\"dwmapi.dll\", PreserveSig = false)]\n        public static extern void DwmEnableBlurBehindWindow(IntPtr hWnd, DWM_BLURBEHIND pBlurBehind);\n\n        [DllImport(\"dwmapi.dll\", PreserveSig = false)]\n        public static extern void DwmExtendFrameIntoClientArea(IntPtr hWnd, MARGINS pMargins);\n\n        [DllImport(\"dwmapi.dll\", PreserveSig = false)]\n        public static extern bool DwmIsCompositionEnabled();\n\n        [DllImport(\"dwmapi.dll\", PreserveSig = false)]\n        public static extern void DwmGetColorizationColor(\n            out int pcrColorization,\n            [MarshalAs(UnmanagedType.Bool)]out bool pfOpaqueBlend);\n\n        [DllImport(\"dwmapi.dll\", PreserveSig = false)]\n        public static extern void DwmEnableComposition(bool bEnable);\n\n        [DllImport(\"dwmapi.dll\", PreserveSig = false)]\n        public static extern IntPtr DwmRegisterThumbnail(IntPtr dest, IntPtr source);\n\n        [DllImport(\"dwmapi.dll\", PreserveSig = false)]\n        public static extern void DwmUnregisterThumbnail(IntPtr hThumbnail);\n\n        [DllImport(\"dwmapi.dll\", PreserveSig = false)]\n        public static extern void DwmUpdateThumbnailProperties(IntPtr hThumbnail, DWM_THUMBNAIL_PROPERTIES props);\n\n        [DllImport(\"dwmapi.dll\", PreserveSig = false)]\n        public static extern void DwmQueryThumbnailSourceSize(IntPtr hThumbnail, out Size size);\n\n        [StructLayout(LayoutKind.Sequential)]\n        public class DWM_THUMBNAIL_PROPERTIES\n        {\n            public uint dwFlags;\n            public RECT rcDestination;\n            public RECT rcSource;\n            public byte opacity;\n            [MarshalAs(UnmanagedType.Bool)]\n            public bool fVisible;\n            [MarshalAs(UnmanagedType.Bool)]\n            public bool fSourceClientAreaOnly;\n\n            public const uint DWM_TNP_RECTDESTINATION = 0x00000001;\n            public const uint DWM_TNP_RECTSOURCE = 0x00000002;\n            public const uint DWM_TNP_OPACITY = 0x00000004;\n            public const uint DWM_TNP_VISIBLE = 0x00000008;\n            public const uint DWM_TNP_SOURCECLIENTAREAONLY = 0x00000010;\n        }\n\n        [StructLayout(LayoutKind.Sequential)]\n        public class MARGINS\n        {\n            public int cxLeftWidth, cxRightWidth, cyTopHeight, cyBottomHeight;\n\n            public MARGINS(int left, int top, int right, int bottom)\n            {\n                cxLeftWidth = left; cyTopHeight = top;\n                cxRightWidth = right; cyBottomHeight = bottom;\n            }\n        }\n\n        [StructLayout(LayoutKind.Sequential)]\n        public class DWM_BLURBEHIND\n        {\n            public uint dwFlags;\n            [MarshalAs(UnmanagedType.Bool)]\n            public bool fEnable;\n            public IntPtr hRegionBlur;\n            [MarshalAs(UnmanagedType.Bool)]\n            public bool fTransitionOnMaximized;\n\n            public const uint DWM_BB_ENABLE = 0x00000001;\n            public const uint DWM_BB_BLURREGION = 0x00000002;\n            public const uint DWM_BB_TRANSITIONONMAXIMIZED = 0x00000004;\n        }\n\n        [StructLayout(LayoutKind.Sequential)]\n        public struct RECT\n        {\n            public int left, top, right, bottom;\n\n            public RECT(int left, int top, int right, int bottom)\n            {\n                this.left = left; this.top = top; this.right = right; this.bottom = bottom;\n            }\n        }\n    \n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls.Win32/ExplorerTreeView.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Runtime.InteropServices;\nusing System.Windows.Forms;\n\nnamespace Sheng.Winform.Controls.Win32\n{\n    public class ExplorerTreeView\n    {\n        const int TV_FIRST = 0x1100;\n        const int TVM_SETEXTENDEDSTYLE = TV_FIRST + 44;\n        const int TVM_GETEXTENDEDSTYLE = TV_FIRST + 45;\n        const int TVS_EX_FADEINOUTEXPANDOS = 0x0040;\n        const int TVS_EX_DOUBLEBUFFER = 0x0004;\n\n        [DllImport(\"uxtheme.dll\", CharSet = CharSet.Auto)]\n        public extern static int SetWindowTheme(IntPtr hWnd, string subAppName, string subIdList);\n\n        [DllImport(\"user32.dll\", CharSet = CharSet.Auto)]\n        public extern static IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);\n\n        private static int TreeView_GetExtendedStyle(IntPtr handle)\n        {\n            IntPtr ptr = SendMessage(handle, TVM_GETEXTENDEDSTYLE, IntPtr.Zero, IntPtr.Zero);\n            return ptr.ToInt32();\n        }\n\n        private static void TreeView_SetExtendedStyle(IntPtr handle, int extendedStyle, int mask)\n        {\n            SendMessage(handle, TVM_SETEXTENDEDSTYLE, new IntPtr(mask), new IntPtr(extendedStyle));\n        }\n\n        // Modify a WinForms TreeView control to use the new Explorer style theme\n        public static void ApplyTreeViewThemeStyles(TreeView treeView)\n        {\n            if (treeView == null)\n            {\n                throw new ArgumentNullException(\"treeView\");\n            }\n\n            treeView.HotTracking = true;\n            treeView.ShowLines = false;\n\n            IntPtr hwnd = treeView.Handle;\n            SetWindowTheme(hwnd, \"Explorer\", null);\n            int exstyle = TreeView_GetExtendedStyle(hwnd);\n            exstyle |= TVS_EX_DOUBLEBUFFER | TVS_EX_FADEINOUTEXPANDOS;\n            TreeView_SetExtendedStyle(hwnd, exstyle, 0);\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls.Win32/Kernel32.cs",
    "content": "﻿using System.Text;\nusing System.Runtime.InteropServices;\n\nnamespace Sheng.Winform.Controls.Win32\n{\n    public static class Kernel32\n    {\n        [DllImport(\"kernel32\")]\n        public static extern long WritePrivateProfileString(string section,\n            string key, string val, string filePath);\n\n        [DllImport(\"kernel32\")]\n        public static extern int GetPrivateProfileString(string section,\n            string key, string def, StringBuilder retVal,\n            int size, string filePath);\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls.Win32/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// 有关程序集的常规信息通过以下\n// 特性集控制。更改这些特性值可修改\n// 与程序集关联的信息。\n[assembly: AssemblyTitle(\"Sheng.Winform.Controls.Win32\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"sheng.c\")]\n[assembly: AssemblyProduct(\"Sheng.Winform.Controls.Win32\")]\n[assembly: AssemblyCopyright(\"Copyright © sheng.c 2010\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// 将 ComVisible 设置为 false 使此程序集中的类型\n// 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型，\n// 则将该类型上的 ComVisible 特性设置为 true。\n[assembly: ComVisible(false)]\n\n// 如果此项目向 COM 公开，则下列 GUID 用于类型库的 ID\n[assembly: Guid(\"7ef84788-823f-450d-b723-45df1346c4a7\")]\n\n// 程序集的版本信息由下面四个值组成:\n//\n//      主版本\n//      次版本 \n//      内部版本号\n//      修订号\n//\n// 可以指定所有这些值，也可以使用“内部版本号”和“修订号”的默认值，\n// 方法是按如下所示使用“*”:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "Sheng.Winform.Controls.Win32/Shell32.cs",
    "content": "﻿using System;\nusing System.Runtime.InteropServices;\n\nnamespace Sheng.Winform.Controls.Win32\n{\n    public static class Shell32\n    {\n        public const int SHCNE_ASSOCCHANGED = 0x08000000;\n        public const int SHCNF_IDLIST = 0x0;\n\n        [DllImport(\"shell32.dll\")]\n        public static extern void SHChangeNotify(int wEventId, int uFlags, IntPtr dwItem1, IntPtr dwItem2);\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls.Win32/Sheng.Winform.Controls.Win32.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <PropertyGroup>\r\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\r\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\r\n    <ProductVersion>8.0.30703</ProductVersion>\r\n    <SchemaVersion>2.0</SchemaVersion>\r\n    <ProjectGuid>{946FFB43-4864-4967-8D69-8716CDA83F7A}</ProjectGuid>\r\n    <OutputType>Library</OutputType>\r\n    <AppDesignerFolder>Properties</AppDesignerFolder>\r\n    <RootNamespace>Sheng.Winform.Controls.Win32</RootNamespace>\r\n    <AssemblyName>Sheng.Winform.Controls.Win32</AssemblyName>\r\n    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>\r\n    <FileAlignment>512</FileAlignment>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\r\n    <DebugSymbols>true</DebugSymbols>\r\n    <DebugType>full</DebugType>\r\n    <Optimize>false</Optimize>\r\n    <OutputPath>bin\\Debug\\</OutputPath>\r\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\r\n    <ErrorReport>prompt</ErrorReport>\r\n    <WarningLevel>4</WarningLevel>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\r\n    <DebugType>pdbonly</DebugType>\r\n    <Optimize>true</Optimize>\r\n    <OutputPath>bin\\Release\\</OutputPath>\r\n    <DefineConstants>TRACE</DefineConstants>\r\n    <ErrorReport>prompt</ErrorReport>\r\n    <WarningLevel>4</WarningLevel>\r\n  </PropertyGroup>\r\n  <ItemGroup>\r\n    <Reference Include=\"System\" />\r\n    <Reference Include=\"System.Core\" />\r\n    <Reference Include=\"System.Drawing\" />\r\n    <Reference Include=\"System.Windows.Forms\" />\r\n    <Reference Include=\"System.Xml.Linq\" />\r\n    <Reference Include=\"System.Data.DataSetExtensions\" />\r\n    <Reference Include=\"System.Data\" />\r\n    <Reference Include=\"System.Xml\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <Compile Include=\"DwmApi.cs\" />\r\n    <Compile Include=\"ExplorerTreeView.cs\" />\r\n    <Compile Include=\"Kernel32.cs\" />\r\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\r\n    <Compile Include=\"Shell32.cs\" />\r\n    <Compile Include=\"User32.cs\" />\r\n    <Compile Include=\"WinMessage.cs\" />\r\n  </ItemGroup>\r\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\r\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\r\n</Project>"
  },
  {
    "path": "Sheng.Winform.Controls.Win32/Sheng.Winform.Controls.Win32.csproj.user",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <PropertyGroup>\r\n    <ProjectView>ProjectFiles</ProjectView>\r\n  </PropertyGroup>\r\n</Project>"
  },
  {
    "path": "Sheng.Winform.Controls.Win32/User32.cs",
    "content": "﻿using System;\nusing System.Runtime.InteropServices;\n\nnamespace Sheng.Winform.Controls.Win32\n{\n    public static class User32\n    {\n        //WM_COPYDATA消息所要求的数据结构\n        public struct CopyDataStruct\n        {\n            public IntPtr dwData;\n            public int cbData;\n\n            [MarshalAs(UnmanagedType.LPStr)]\n            public string lpData;\n        }\n\n        public const int WM_COPYDATA = 0x004A;\n\n        /// <summary>\n        /// 通过窗口的标题来查找窗口的句柄\n        /// </summary>\n        /// <param name=\"lpClassName\"></param>\n        /// <param name=\"lpWindowName\"></param>\n        /// <returns></returns>\n        [DllImport(\"User32.dll\", EntryPoint = \"FindWindow\")]\n        public static extern int FindWindow(string lpClassName, string lpWindowName);\n\n        /// <summary>\n        /// 发送 Windows 消息\n        /// </summary>\n        /// <param name=\"hWnd\"></param>\n        /// <param name=\"Msg\"></param>\n        /// <param name=\"wParam\"></param>\n        /// <param name=\"lParam\"></param>\n        /// <returns></returns>\n        [DllImport(\"User32.dll\", EntryPoint = \"SendMessage\")]\n        public static extern int SendMessage\n            (\n            int hWnd,                        // 目标窗口的句柄  \n            int Msg,                        // 在这里是WM_COPYDATA\n            int wParam,                    // 第一个消息参数\n            ref  CopyDataStruct lParam        // 第二个消息参数\n            );\n\n\n        public const int SC_RESTORE = 0xF120; //还原\n        public const int SC_MOVE = 0xF010; //移动\n        public const int SC_SIZE = 0xF000; //大小\n        public const int SC_MINIMIZE = 0xF020; //最小化\n        public const int SC_MAXIMIZE = 0xF030; //最大化\n        public const int SC_CLOSE = 0xF060; //关闭\n\n        public const int MF_DISABLE = 0x1;\n        public const int MF_ENABLE = 0x0;\n\n        [DllImport(\"user32.dll\")]\n        public static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);\n\n        [DllImport(\"user32.dll\")]\n        public static extern int EnableMenuItem(IntPtr hMenu, int wIDEnableItem, int wEnable);\n\n        public const int WM_PAINT = 0x000f;\n        public const int WM_ERASEBKGND = 0x0014;\n        public const int WM_NCPAINT = 0x0085;\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls.Win32/WinMessage.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Diagnostics;\n\nnamespace Sheng.Winform.Controls.Win32\n{\n    public static class WinMessage\n    {\n        /// <summary>\n        /// 发送消息，只能传递一个自定义的消息ID和消息字符串，想传一个结构，但没成功\n        /// </summary>\n        /// <param name=\"destProcessName\">目标进程名称，如果有多个，则给每个都发送</param>\n        /// <param name=\"msgID\">自定义数据，可以通过这个来决定如何解析下面的strMsg</param>\n        /// <param name=\"strMsg\">传递的消息，是一个字符串</param>\n        public static void SendMessage(string destProcessName, int msgID, string strMsg)\n        {\n            if (strMsg == null)\n                return;\n\n            //按进程名称查找，同名称的进程可能有许多，所以返回的是一个数组\n            Process[] foundProcess = Process.GetProcessesByName(destProcessName);\n            foreach (Process p in foundProcess)\n            {\n                int toWindowHandler = p.MainWindowHandle.ToInt32();\n                if (toWindowHandler != 0)\n                {\n                    User32.CopyDataStruct cds;\n                    cds.dwData = (IntPtr)msgID;   //这里可以传入一些自定义的数据，但只能是4字节整数      \n                    cds.lpData = strMsg;            //消息字符串\n                    cds.cbData = System.Text.Encoding.Default.GetBytes(strMsg).Length + 1;  //注意，这里的长度是按字节来算的\n\n                    //发送方的窗口的句柄, 由于本系统中的接收方不关心是该消息是从哪个窗口发出的，所以就直接填0了\n                    int fromWindowHandler = 0;\n                    User32.SendMessage(toWindowHandler, User32.WM_COPYDATA, fromWindowHandler, ref  cds);\n                }\n            }\n        }\n\n        /// <summary>\n        /// 接收消息，得到消息字符串\n        /// </summary>\n        /// <param name=\"m\">System.Windows.Forms.Message m</param>\n        /// <returns>接收到的消息字符串</returns>\n        public static string ReceiveMessage(ref  System.Windows.Forms.Message m)\n        {\n            if (m.Msg == User32.WM_COPYDATA)\n            {\n                User32.CopyDataStruct cds = (User32.CopyDataStruct)m.GetLParam(typeof(User32.CopyDataStruct));\n                return cds.lpData;\n            }\n            else\n            {\n                return String.Empty;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Sheng.Winform.Controls.sln",
    "content": "﻿\r\nMicrosoft Visual Studio Solution File, Format Version 12.00\r\n# Visual Studio 14\r\nVisualStudioVersion = 14.0.25420.1\r\nMinimumVisualStudioVersion = 10.0.40219.1\r\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"Sheng.Winform.Controls\", \"Sheng.Winform.Controls\\Sheng.Winform.Controls.csproj\", \"{8947FDAE-9F4B-4D77-91AA-0704ACD83DBD}\"\r\nEndProject\r\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"Sheng.Winform.Controls.Drawing\", \"Sheng.Winform.Controls.Drawing\\Sheng.Winform.Controls.Drawing.csproj\", \"{BCD80096-7B6F-4273-A031-186A610C84E5}\"\r\nEndProject\r\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"Sheng.Winform.Controls.Kernal\", \"Sheng.Winform.Controls.Kernal\\Sheng.Winform.Controls.Kernal.csproj\", \"{125FB802-2C83-47DC-BA57-910064355CCD}\"\r\nEndProject\r\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"Sheng.Winform.Controls.Win32\", \"Sheng.Winform.Controls.Win32\\Sheng.Winform.Controls.Win32.csproj\", \"{946FFB43-4864-4967-8D69-8716CDA83F7A}\"\r\nEndProject\r\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"Sheng.Winform.Controls.Localisation\", \"Sheng.Winform.Controls.Localisation\\Sheng.Winform.Controls.Localisation.csproj\", \"{E0B8AD36-CC90-41F5-BD00-EC614569C9F9}\"\r\nEndProject\r\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"Sheng.Winform.Controls.Demo\", \"Sheng.Winform.Controls.Demo\\Sheng.Winform.Controls.Demo.csproj\", \"{8DB4A7CC-C631-45BD-BB94-1BC9CF686609}\"\r\nEndProject\r\nGlobal\r\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\r\n\t\tDebug|Any CPU = Debug|Any CPU\r\n\t\tRelease|Any CPU = Release|Any CPU\r\n\tEndGlobalSection\r\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\r\n\t\t{8947FDAE-9F4B-4D77-91AA-0704ACD83DBD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r\n\t\t{8947FDAE-9F4B-4D77-91AA-0704ACD83DBD}.Debug|Any CPU.Build.0 = Debug|Any CPU\r\n\t\t{8947FDAE-9F4B-4D77-91AA-0704ACD83DBD}.Release|Any CPU.ActiveCfg = Release|Any CPU\r\n\t\t{8947FDAE-9F4B-4D77-91AA-0704ACD83DBD}.Release|Any CPU.Build.0 = Release|Any CPU\r\n\t\t{BCD80096-7B6F-4273-A031-186A610C84E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r\n\t\t{BCD80096-7B6F-4273-A031-186A610C84E5}.Debug|Any CPU.Build.0 = Debug|Any CPU\r\n\t\t{BCD80096-7B6F-4273-A031-186A610C84E5}.Release|Any CPU.ActiveCfg = Release|Any CPU\r\n\t\t{BCD80096-7B6F-4273-A031-186A610C84E5}.Release|Any CPU.Build.0 = Release|Any CPU\r\n\t\t{125FB802-2C83-47DC-BA57-910064355CCD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r\n\t\t{125FB802-2C83-47DC-BA57-910064355CCD}.Debug|Any CPU.Build.0 = Debug|Any CPU\r\n\t\t{125FB802-2C83-47DC-BA57-910064355CCD}.Release|Any CPU.ActiveCfg = Release|Any CPU\r\n\t\t{125FB802-2C83-47DC-BA57-910064355CCD}.Release|Any CPU.Build.0 = Release|Any CPU\r\n\t\t{946FFB43-4864-4967-8D69-8716CDA83F7A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r\n\t\t{946FFB43-4864-4967-8D69-8716CDA83F7A}.Debug|Any CPU.Build.0 = Debug|Any CPU\r\n\t\t{946FFB43-4864-4967-8D69-8716CDA83F7A}.Release|Any CPU.ActiveCfg = Release|Any CPU\r\n\t\t{946FFB43-4864-4967-8D69-8716CDA83F7A}.Release|Any CPU.Build.0 = Release|Any CPU\r\n\t\t{E0B8AD36-CC90-41F5-BD00-EC614569C9F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r\n\t\t{E0B8AD36-CC90-41F5-BD00-EC614569C9F9}.Debug|Any CPU.Build.0 = Debug|Any CPU\r\n\t\t{E0B8AD36-CC90-41F5-BD00-EC614569C9F9}.Release|Any CPU.ActiveCfg = Release|Any CPU\r\n\t\t{E0B8AD36-CC90-41F5-BD00-EC614569C9F9}.Release|Any CPU.Build.0 = Release|Any CPU\r\n\t\t{8DB4A7CC-C631-45BD-BB94-1BC9CF686609}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r\n\t\t{8DB4A7CC-C631-45BD-BB94-1BC9CF686609}.Debug|Any CPU.Build.0 = Debug|Any CPU\r\n\t\t{8DB4A7CC-C631-45BD-BB94-1BC9CF686609}.Release|Any CPU.ActiveCfg = Release|Any CPU\r\n\t\t{8DB4A7CC-C631-45BD-BB94-1BC9CF686609}.Release|Any CPU.Build.0 = Release|Any CPU\r\n\tEndGlobalSection\r\n\tGlobalSection(SolutionProperties) = preSolution\r\n\t\tHideSolutionNode = FALSE\r\n\tEndGlobalSection\r\nEndGlobal\r\n"
  }
]