轉(C# 類似右鍵菜單彈出窗體)

来源:https://www.cnblogs.com/wangyonglai/archive/2018/12/13/10112172.html
-Advertisement-
Play Games

文章來自 https://www.cnblogs.com/ahdung/p/FloatLayerBase.html 每天進步一點點 新建類 FloatLayerBase 繼承Form, 自己有點小改動public void Show(Control control, Point endPoint) ...


文章來自 https://www.cnblogs.com/ahdung/p/FloatLayerBase.html

每天進步一點點

新建類  FloatLayerBase 繼承Form,

自己有點小改動public void Show(Control control, Point endPoint) 添加參數 endPoint 避免窗體在最右邊或下邊時彈出窗體被遮掩。

 

public partial class FloatLayerBase : Form
    {
        /// <summary>
        /// 滑鼠消息篩選器
        /// </summary>
        //由於本窗體為WS_CHILD,所以不會收到在窗體以外點擊滑鼠的消息
        //該消息篩選器的作用就是讓本窗體獲知滑鼠點擊情況,進而根據滑鼠是否在本窗體以外的區域點擊,做出相應處理
        readonly AppMouseMessageHandler _mouseMsgFilter;

        /// <summary>
        /// 指示本窗體是否已ShowDialog過
        /// </summary>
        //由於多次ShowDialog會使OnLoad/OnShown重入,故需設置此標記以供重入時判斷
        bool _isShowDialogAgain;

        //邊框相關欄位
        BorderStyle _borderType;
        Border3DStyle _border3DStyle;
        ButtonBorderStyle _borderSingleStyle;
        Color _borderColor;

        /// <summary>
        /// 獲取或設置邊框類型
        /// </summary>
        [Description("獲取或設置邊框類型。")]
        [DefaultValue(BorderStyle.Fixed3D)]
        public BorderStyle BorderType
        {
            get { return _borderType; }
            set
            {
                if (_borderType == value) { return; }
                _borderType = value;
                Invalidate();
            }
        }

        /// <summary>
        /// 獲取或設置三維邊框樣式
        /// </summary>
        [Description("獲取或設置三維邊框樣式。")]
        [DefaultValue(Border3DStyle.RaisedInner)]
        public Border3DStyle Border3DStyle
        {
            get { return _border3DStyle; }
            set
            {
                if (_border3DStyle == value) { return; }
                _border3DStyle = value;
                Invalidate();
            }
        }

        /// <summary>
        /// 獲取或設置線型邊框樣式
        /// </summary>
        [Description("獲取或設置線型邊框樣式。")]
        [DefaultValue(ButtonBorderStyle.Solid)]
        public ButtonBorderStyle BorderSingleStyle
        {
            get { return _borderSingleStyle; }
            set
            {
                if (_borderSingleStyle == value) { return; }
                _borderSingleStyle = value;
                Invalidate();
            }
        }

        /// <summary>
        /// 獲取或設置邊框顏色(僅當邊框類型為線型時有效)
        /// </summary>
        [Description("獲取或設置邊框顏色(僅當邊框類型為線型時有效)。")]
        [DefaultValue(typeof(Color), "DarkGray")]
        public Color BorderColor
        {
            get { return _borderColor; }
            set
            {
                if (_borderColor == value) { return; }
                _borderColor = value;
                Invalidate();
            }
        }

        protected override sealed CreateParams CreateParams
        {
            get
            {
                CreateParams prms = base.CreateParams;

                //prms.Style = 0;
                //prms.Style |= -2147483648;   //WS_POPUP
                prms.Style |= 0x40000000;      //WS_CHILD  重要,只有CHILD窗體才不會搶父窗體焦點
                prms.Style |= 0x4000000;       //WS_CLIPSIBLINGS
                prms.Style |= 0x10000;         //WS_TABSTOP
                prms.Style &= ~0x40000;        //WS_SIZEBOX       去除
                prms.Style &= ~0x800000;       //WS_BORDER        去除
                prms.Style &= ~0x400000;       //WS_DLGFRAME      去除
                //prms.Style &= ~0x20000;      //WS_MINIMIZEBOX   去除
                //prms.Style &= ~0x10000;      //WS_MAXIMIZEBOX   去除

                prms.ExStyle = 0;
                //prms.ExStyle |= 0x1;         //WS_EX_DLGMODALFRAME 立體邊框
                //prms.ExStyle |= 0x8;         //WS_EX_TOPMOST
                prms.ExStyle |= 0x10000;       //WS_EX_CONTROLPARENT
                //prms.ExStyle |= 0x80;        //WS_EX_TOOLWINDOW
                //prms.ExStyle |= 0x100;       //WS_EX_WINDOWEDGE
                //prms.ExStyle |= 0x8000000;   //WS_EX_NOACTIVATE
                //prms.ExStyle |= 0x4;         //WS_EX_NOPARENTNOTIFY

                return prms;
            }
        }

        public FloatLayerBase()
        {
            //初始化消息篩選器。添加和移除在顯示/隱藏時負責
            _mouseMsgFilter = new AppMouseMessageHandler(this);
            //InitializeComponent();
            InitBaseProperties();
            //初始化邊框相關
            _borderType = BorderStyle.Fixed3D;
            _border3DStyle = System.Windows.Forms.Border3DStyle.RaisedInner;
            _borderSingleStyle = ButtonBorderStyle.Solid;
            _borderColor = Color.DarkGray;
        }


        protected override void OnLoad(EventArgs e)
        {
            //防止重入
            if (_isShowDialogAgain) { return; }

            //需得減掉兩層邊框寬度,運行時尺寸才與設計時完全相符,原因不明
            //確定與ControlBox、FormBorderStyle有關,但具體聯繫不明
            if (!DesignMode)
            {
                Size size = SystemInformation.FrameBorderSize;
                this.Size -= size + size;//不可以用ClientSize,後者會根據視窗風格重新調整Size
            }
            base.OnLoad(e);
        }

        protected override void OnShown(EventArgs e)
        {
            //防止重入
            if (_isShowDialogAgain) { return; }

            //在OnShown中為首次ShowDialog設標記
            if (Modal) { _isShowDialogAgain = true; }

            if (!DesignMode)
            {
                //激活首控制項
                Control firstControl;
                if ((firstControl = GetNextControl(this, true)) != null)
                {
                    firstControl.Focus();
                }
            }
            base.OnShown(e);
        }

        protected override void WndProc(ref Message m)
        {
            //當本窗體作為ShowDialog彈出時,在收到WM_SHOWWINDOW前,Owner會被Disable
            //故需在收到該消息後立即Enable它,不然Owner窗體和本窗體都將處於無響應狀態
            if (m.Msg == 0x18 && m.WParam != IntPtr.Zero && m.LParam == IntPtr.Zero
                && Modal && Owner != null && !Owner.IsDisposed)
            {
                if (Owner.IsMdiChild)
                {
                    //當Owner是MDI子窗體時,被Disable的是MDI主窗體
                    //並且Parent也會指向MDI主窗體,故需改回為Owner,這樣彈出窗體的Location才會相對於Owner而非MDIParent
                    NativeMethods.EnableWindow(Owner.MdiParent.Handle, true);
                    NativeMethods.SetParent(this.Handle, Owner.Handle);//只能用API設置Parent,因為模式窗體是TopLevel,.Net拒絕為頂級窗體設置Parent
                }
                else
                {
                    NativeMethods.EnableWindow(Owner.Handle, true);
                }
            }
            base.WndProc(ref m);
        }

        //畫邊框
        protected override void OnPaintBackground(PaintEventArgs e)
        {
            base.OnPaintBackground(e);

            if (_borderType == BorderStyle.Fixed3D)//繪製3D邊框
            {
                ControlPaint.DrawBorder3D(e.Graphics, ClientRectangle, Border3DStyle);
            }
            else if (_borderType == BorderStyle.FixedSingle)//繪製線型邊框
            {
                ControlPaint.DrawBorder(e.Graphics, ClientRectangle, BorderColor, BorderSingleStyle);
            }
        }

        //顯示後添加滑鼠消息篩選器以開始捕捉,隱藏時則移除篩選器。之所以不放Dispose中是想儘早移除篩選器
        protected override void OnVisibleChanged(EventArgs e)
        {
            if (!DesignMode)
            {
                if (Visible) { Application.AddMessageFilter(_mouseMsgFilter); }
                else { Application.RemoveMessageFilter(_mouseMsgFilter); }
            }
            base.OnVisibleChanged(e);
        }

        //實現窗體客戶區拖動
        //在WndProc中實現這個較麻煩,所以放到這裡做
        protected override void OnMouseDown(MouseEventArgs e)
        {
            //讓滑鼠點擊客戶區時達到與點擊標題欄一樣的效果,以此實現客戶區拖動
            NativeMethods.ReleaseCapture();
            NativeMethods.SendMessage(Handle, 0xA1/*WM_NCLBUTTONDOWN*/, (IntPtr)2/*CAPTION*/, IntPtr.Zero);

            base.OnMouseDown(e);
        }

        /// <summary>
        /// 顯示為模式窗體
        /// </summary>
        /// <param name="control">顯示在該控制項下方</param>
        public DialogResult ShowDialog(Control control, Point endPoint)
        {
            return ShowDialog(control, 0, control.Height, endPoint);
        }

        /// <summary>
        /// 顯示為模式窗體
        /// </summary>
        /// <param name="control">觸發彈出窗體的控制項</param>
        /// <param name="offsetX">相對control水平偏移</param>
        /// <param name="offsetY">相對control垂直偏移</param>
        public DialogResult ShowDialog(Control control, int offsetX, int offsetY, Point endPoint)
        {
            return ShowDialog(control, new Point(offsetX, offsetY), endPoint);
        }

        /// <summary>
        /// 顯示為模式窗體
        /// </summary>
        /// <param name="control">觸發彈出窗體的控制項</param>
        /// <param name="offset">相對control偏移</param>
        public DialogResult ShowDialog(Control control, Point offset, Point endPoint)
        {
            return this.ShowDialogInternal(control, offset, endPoint);
        }

        /// <summary>
        /// 顯示為模式窗體
        /// </summary>
        /// <param name="item">顯示在該工具欄項的下方</param>
        public DialogResult ShowDialog(ToolStripItem item, Point endPoint)
        {
            return ShowDialog(item, 0, item.Height, endPoint);
        }

        /// <summary>
        /// 顯示為模式窗體
        /// </summary>
        /// <param name="item">觸發彈出窗體的工具欄項</param>
        /// <param name="offsetX">相對item水平偏移</param>
        /// <param name="offsetY">相對item垂直偏移</param>
        public DialogResult ShowDialog(ToolStripItem item, int offsetX, int offsetY, Point endPoint)
        {
            return ShowDialog(item, new Point(offsetX, offsetY), endPoint);
        }

        /// <summary>
        /// 顯示為模式窗體
        /// </summary>
        /// <param name="item">觸發彈出窗體的工具欄項</param>
        /// <param name="offset">相對item偏移</param>
        public DialogResult ShowDialog(ToolStripItem item, Point offset, Point endPoint)
        {
            return this.ShowDialogInternal(item, offset, endPoint);
        }

        /// <summary>
        /// 顯示窗體
        /// </summary>
        /// <param name="control">顯示在該控制項下方</param>
        public void Show(Control control, Point endPoint)
        {
            Show(control, 0, control.Height,endPoint);
        }

        /// <summary>
        /// 顯示窗體
        /// </summary>
        /// <param name="control">觸發彈出窗體的控制項</param>
        /// <param name="offsetX">相對control水平偏移</param>
        /// <param name="offsetY">相對control垂直偏移</param>
        public void Show(Control control, int offsetX, int offsetY, Point endPoint)
        {
            Show(control, new Point(offsetX, offsetY), endPoint);
        }

        /// <summary>
        /// 顯示窗體
        /// </summary>
        /// <param name="control">觸發彈出窗體的控制項</param>
        /// <param name="offset">相對control偏移</param>
        public void Show(Control control, Point offset, Point endPoint)
        {
            this.ShowInternal(control, offset, endPoint);
        }

        /// <summary>
        /// 顯示窗體
        /// </summary>
        /// <param name="item">顯示在該工具欄下方</param>
        public void Show(ToolStripItem item, Point endPoint)
        {
            Show(item, 0, item.Height, endPoint);
        }

        /// <summary>
        /// 顯示窗體
        /// </summary>
        /// <param name="item">觸發彈出窗體的工具欄項</param>
        /// <param name="offsetX">相對item水平偏移</param>
        /// <param name="offsetY">相對item垂直偏移</param>
        public void Show(ToolStripItem item, int offsetX, int offsetY, Point endPoint)
        {
            Show(item, new Point(offsetX, offsetY),endPoint);
        }

        /// <summary>
        /// 顯示窗體
        /// </summary>
        /// <param name="item">觸發彈出窗體的工具欄項</param>
        /// <param name="offset">相對item偏移</param>
        public void Show(ToolStripItem item, Point offset, Point endPoint)
        {
            this.ShowInternal(item, offset, endPoint);
        }

        /// <summary>
        /// ShowDialog內部方法
        /// </summary>
        private DialogResult ShowDialogInternal(Component controlOrItem, Point offset, Point endPoint)
        {
            //快速連續彈出本窗體將有可能遇到尚未Hide的情況下再次彈出,這會引發異常,故需做處理
            if (this.Visible) { return System.Windows.Forms.DialogResult.None; }

            this.SetLocationAndOwner(controlOrItem, offset, endPoint);
            return base.ShowDialog();
        }

        /// <summary>
        /// Show內部方法
        /// </summary>
        private void ShowInternal(Component controlOrItem, Point offset, Point endPoint)
        {
            if (this.Visible) { return; }//原因見ShowDialogInternal

            this.SetLocationAndOwner(controlOrItem, offset, endPoint);
            base.Show();
        }

        /// <summary>
        /// 設置坐標及所有者
        /// </summary>
        /// <param name="controlOrItem">控制項或工具欄項</param>
        /// <param name="offset">相對偏移</param>
        private void SetLocationAndOwner(Component controlOrItem, Point offset, Point endPoint)
        {
            Point pt = Point.Empty;

            if (controlOrItem is ToolStripItem)
            {
                ToolStripItem item = (ToolStripItem)controlOrItem;
                pt.Offset(item.Bounds.Location);
                controlOrItem = item.Owner;
            }

            Control c = (Control)controlOrItem;
            pt.Offset(GetControlLocationInForm(c));
            pt.Offset(offset);
            if (pt.X + this.RestoreBounds.Width > endPoint.X)//右邊超出界面
            {
                pt.X = pt.X + c.Width - this.RestoreBounds.Width;
            }

            this.Location = pt;

            //設置Owner屬性與Show[Dialog](Owner)有不同,當Owner是MDIChild時,後者會改Owner為MDIParent
            this.Owner = c.FindForm();
        }

        /// <summary>
        /// 獲取控制項在窗體中的坐標
        /// </summary>
        private static Point GetControlLocationInForm(Control c)
        {
            Point pt = c.Location;
            //Control c1 = c.Parent;
            while (!((c = c.Parent) is Form))
            {
                pt.Offset(c.Location);
            }
            return pt;
        }


        #region 屏蔽對本類影響重大的基類方法和屬性

        /// <summary>
        /// 初始化部分基類屬性
        /// </summary>
        private void InitBaseProperties()
        {
            base.ControlBox = false;                           //重要
            //必須得是SizableToolWindow才能支持調整大小的同時,不受SystemInformation.MinWindowTrackSize的限制
            base.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow;
            base.Text = string.Empty;                          //重要
            base.HelpButton = false;
            base.Icon = null;
            base.IsMdiContainer = false;
            base.MaximizeBox = false;
            base.MinimizeBox = false;
            base.ShowIcon = false;
            base.ShowInTaskbar = false;
            base.StartPosition = FormStartPosition.Manual;     //重要
            base.TopMost = false;
            base.WindowState = FormWindowState.Normal;
        }

        //屏蔽原方法
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        [Obsolete("請使用別的重載!", true)]
        public new DialogResult ShowDialog() { throw new NotImplementedException(); }

        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        [Obsolete("請使用別的重載!", true)]
        public new DialogResult ShowDialog(IWin32Window owner) { throw new NotImplementedException(); }

        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        [Obsolete("請使用別的重載!", true)]
        public new void Show() { throw new NotImplementedException(); }

        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        [Obsolete("請使用別的重載!", true)]
        public new void Show(IWin32Window owner) { throw new NotImplementedException(); }

        //屏蔽原屬性
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        [Obsolete("禁用該屬性!", true)]
        public new bool ControlBox { get { return false; } set { } }

        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        [Obsolete("設置邊框請使用Border相關屬性!", true)]
        public new FormBorderStyle FormBorderStyle { get { return System.Windows.Forms.FormBorderStyle.SizableToolWindow; } set { } }

        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        [Obsolete("禁用該屬性!", true)]
        public override sealed string Text { get { return string.Empty; } set { } }

        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        [Obsolete("禁用該屬性!", true)]
        public new bool HelpButton { get { return false; } set { } }

        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        [Obsolete("禁用該屬性!", true)]
        public new Image Icon { get { return null; } set { } }

        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        [Obsolete("禁用該屬性!", true)]
        public new bool IsMdiContainer { get { return false; } set { } }

        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        [Obsolete("禁用該屬性!", true)]
        public new bool MaximizeBox { get { return false; } set { } }

        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        [Obsolete("禁用該屬性!", true)]
        public new bool MinimizeBox { get { return false; } set { } }

        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        [Obsolete("禁用該屬性!", true)]
        public new bool ShowIcon { get { return false; } set { } }

        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        [Obsolete("禁用該屬性!", true)]
        public new bool ShowInTaskbar { get { return false; } set { } }

        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        [Obsolete("禁用該屬性!", true)]
        public new FormStartPosition StartPosition { get { return FormStartPosition.Manual; } set { } }

        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        [Obsolete("禁用該屬性!", true)]
        public new bool TopMost { get { return false; } set { } }

        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        [Obsolete("禁用該屬性!", true)]
        public new FormWindowState WindowState { get { return FormWindowState.Normal; } set { } }

        #endregion

        /// <summary>
        /// 程式滑鼠消息篩選器
        /// </summary>
        private class AppMouseMessageHandler : IMessageFilter
        {
            readonly FloatLayerBase _layerForm;

            public AppMouseMessageHandler(FloatLayerBase layerForm)
            {
                _layerForm = layerForm;
            }

            public bool PreFilterMessage(ref Message m)
            {
                //如果在本窗體以外點擊滑鼠,隱藏本窗體
                //若想在點擊標題欄、滾動條等非客戶區也要讓本窗體消失,取消0xA1的註釋即可
                //本例是根據坐標判斷,亦可以改為根據句柄,但要考慮子孫控制項
                //之所以用API而不用Form.DesktopBounds是因為後者不可靠
                if ((m.Msg == 0x201/*|| m.Msg==0xA1*/)
                    && _layerForm.Visible && !NativeMethods.GetWindowRect(_layerForm.Handle).Contains(MousePosition))
                {
                    _layerForm.Hide();//之所以不Close是考慮應該由調用者負責銷毀
                }

                return false;
            }
        }


        /// <summary>
        /// API封裝類
        /// </summary>
        private static class NativeMethods
        {
            [DllImport("user32.dll")]
            [return: MarshalAs(UnmanagedType.Bool)]
            public static extern bool EnableWindow(IntPtr hWnd, bool bEnable);

            [DllImport("user32.dll", CharSet = CharSet.Auto)]
            public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

            [DllImport("user32.dll")]
            public static extern bool ReleaseCapture();

            [DllImport("user32.dll", SetLastError = true)]
            public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

            [DllImport("user32.dll", SetLastError = true)]
            private static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);

            [StructLayout(LayoutKind.Sequential)]
            private struct RECT
            {
                public int left;
                public int top;
                public int right;
                public int bottom;

                public static explicit operator Rectangle(RECT rect)
                {
                    return new Rectangle(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
                }
            }

            public static Rectangle GetWindowRect(IntPtr hwnd)
            {
                RECT rect;
                GetWindowRect(hwnd, out rect);
                return (Rectangle)rect;
            }

            //[DllImport("user32.dll", ExactSpelling = true)]
            //public static extern IntPtr GetAncestor(IntPtr hwnd, uint flags);
        }
    }

  

1  添加用戶控制項UserControl1繼承FloatLayerBase

 

2 調用代碼

 public FloatLayerBase CreateLayer(Type type, out bool isShow)
        {
            //考慮到初始化體驗爽滑,不用反射
            FloatLayerBase layer = null;
            if (type == typeof(UserControl1)) { layer = new UserControl1(); } }

            LayerFormOption opts = LayerOption;
            isShow = opts.IsShow;
            layer.BorderType = opts.BorderType;
            layer.Border3DStyle = opts.Border3DStyle;
            layer.BorderSingleStyle = opts.BorderSingleStyle;
            layer.BorderColor = opts.BorderColor;
            return layer;
        }

        public void PopupLayer(Type type, object sender)
        {
            Control c = sender as Control;
            ToolStripItem item = sender as ToolStripItem;
            Point pt = new Point(this.ClientRectangle.Width, this.ClientRectangle.Height);

            bool isShow;
            FloatLayerBase p = CreateLayer(type, out isShow);
            if (isShow)
            {
                if (c != null) { p.Show(c, pt); }
                else { p.Show(item, pt); }
            }
            else
            {
                var result = c != null ? p.ShowDialog(c, pt) : p.ShowDialog(item, pt);
                //txbResult.AppendText(result + "\r\n");
            }
        }

private void button1_Click(object sender, EventArgs e)
{
    PopupLayer(typeof(UserControl1), sender);
}

  


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 任務調度在我們日常開發過程中非常常見,比如:每天晚上0點自動執行某某操作;每周三晚上2點執行某某操作;......當然,我們處理這類問題的方法也有很多,比如:sql的自動任務;windows上創建任務計劃;寫windows服務等等。如果系統比較複雜,相互調用比較頻繁,任務非常多,幾百上千條甚至上萬條 ...
  • 索引: 商業開發實戰總結 一.API 列表 .FirstOrDefaultAsync() .FirstOrDefaultAsync<M>() 如: .FirstOrDefaultAsync<Agent>() , 用於 單表/多表連接 查詢. .FirstOrDefaultAsync<VM>() 如: ...
  • assign assign指令在前面已經使用了多次,它用於為該模板頁面創建或替換一個頂層變數, assign指令的用法有多種,包含創建或替換一個頂層變數,或者創建或替換多個變數等, 它的最簡單的語法如下: <#assign name=value [in namespacehash]>, 這個用法用於 ...
  • ajax post調用WebMethed報錯,返回的信息如下: {“Message”:“處理請求時出錯”,“StackTrace”:“”,“ExceptionType”:“”} 查了一下WebMethed里的方法沒有問題,網上找了好久也沒有什麼解決方案。 後來自己發現可能是返回的json文本太長了, ...
  • 寫在前面 之前有個項目是用asp.net webapi做的,pc和移動端共用api的服務介面,balabala,正好最近在看關於asp.net core方面的資料,各種依賴註入,中間件,處理管道等,而且把webapi和mvc融合到了一起,就想著把之前那個項目移到asp.net core上。 由於之前 ...
  • 1.1 ASP.NET MVC 簡介 ASP.NET是一種構建Web應用程式的框架,它將一般的MVC(Model-View-Controller)模式應用於ASP.NET框架。 1.1.1 MVC模式簡介 MVC將應用程式的用戶界面(User Interface, UI)分為三個主要部分: 模型:一 ...
  • C# -- 使用委托 delegate 執行非同步操作 委托是一種安全地封裝方法的類型,它與 C 和 C++ 中的函數指針類似。 與 C 中的函數指針不同,委托是面向對象的、類型安全的和保險的。 委托的類型由委托的名稱定義。 1. 使用委托非同步執行方法 2. 執行結果: ...
  • 上篇給大家從零開始搭建了一個我們的ASP.NET Core CMS系統的開發框架,具體為什麼那樣設計我也已經在第十篇文章中進行了說明。不過文章發佈後很多人都說了這樣的分層不是很合理,什麼資料庫實體應該跟倉儲放在一起形成領域對象,什麼ViewModel應該放在應用層結構倉儲層與UI層。其實我想說的是, ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...