c# ping

Привет! Зарегистрируйте свой аккаунт сегодня, чтобы стать участником! После входа в систему вы сможете участвовать на этом сайте, добавляя свои собственные темы и сообщения. Преимущество регистрации, даёт возможность целиком и полностью пользоваться всеми сервисами форума!

Form Style своими руками на WinForms с помощью расширения

Роман Кощеев

...
Проверен
Best answers
0
Всем добра читающие гости форумчане.
Задался я тут вопросом таким можно ли легко и просто сменить дизайн формы. Есть у меня программа, написанная рабочая, всё хорошо.
Но дизайн на WinForms оставляет желать лучшего.
doc1.png

Как то "не айс"!

Попробовав через NuGet MetroFrameWork переплевался полностью. Так как нормальный дизайн отсутствует, и если Вы захотите скрыть кнопки навигации приготовьтесь к багам.
Потом попробовал MaterialSkin всё через тот же NuGet. Тут я просрался.
Ну во-первых там есть даже PersianMaterialSkin. Парень скомуниздил дизайн, добавил ООЧЕНЬ КОРЯВЫЙ ListView, переделал шрифт под не читаемый вовсе, и выложил под своим копирайтом. Ну типа плюс от этого GitHub, но глянув GitHub'a внутрь, и решив поменять dll под себя (ну шрифты там всякие, размер полей) блеванул пару раз, и понял что лучше с ноля самому писать. Дальше я пошёл Гуглить...

Гуглёжка привела меня к тому что танцы с бубном неизбежны, и придётся в кровь пальцы стереть чтобы получить нормальную форму. Не хочешь крови ? go WPF.

По-WPF'ил я немного методом научного тыка и понял, что учить надо, и так просто на WPF не перейти.
И красивенькая форма пусть снится ночами.

Но полазив по форуму я тут вычитал что можно и круглые углы сделать но вот только
C#:
this.FormBorderStyle.None;
Но изучив вопрос нашёл код который таскает форму за любой пиксель.

Сначала добавим библиотеку
C#:
using System.Runtime.InteropServices;
C#:
[DllImport("Gdi32.dll")]
        public static extern IntPtr CreateRoundRectRgn(int nLeftRect,
                                                          int nTopRect,
                                                          int nRightRect,
                                                          int nBottomRect,
                                                          int nWidthEllipse,
                                                          int nHeightEllipse);
 
        [DllImport("user32.dll")]
        public static extern int SetWindowRgn(IntPtr hWnd, IntPtr hRgn, bool bRedraw);
        private bool Drag;
        private int MouseX;
        private int MouseY;
 
        private const int WM_NCHITTEST = 0x84;
        private const int HTCLIENT = 0x1;
        private const int HTCAPTION = 0x2;
 
        private bool m_aeroEnabled;
 
        private const int CS_DROPSHADOW = 0x00020000;
        private const int WM_NCPAINT = 0x0085;
        private const int WM_ACTIVATEAPP = 0x001C;
 
        [System.Runtime.InteropServices.DllImport("dwmapi.dll")]
        public static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS pMarInset);
        [System.Runtime.InteropServices.DllImport("dwmapi.dll")]
        public static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);
        [System.Runtime.InteropServices.DllImport("dwmapi.dll")]
 
        public static extern int DwmIsCompositionEnabled(ref int pfEnabled);
 
 
 
        public struct MARGINS
        {
            public int leftWidth;
            public int rightWidth;
            public int topHeight;
            public int bottomHeight;
        }
        protected override CreateParams CreateParams
        {
            get
            {
                m_aeroEnabled = CheckAeroEnabled();
                CreateParams cp = base.CreateParams;
                if (!m_aeroEnabled)
                    cp.ClassStyle |= CS_DROPSHADOW; return cp;
            }
        }
        private bool CheckAeroEnabled()
        {
            if (Environment.OSVersion.Version.Major >= 6)
            {
                int enabled = 0; DwmIsCompositionEnabled(ref enabled);
                return (enabled == 1) ? true : false;
            }
            return false;
        }
        protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
                case WM_NCPAINT:
                    if (m_aeroEnabled)
                    {
                        var v = 2;
                        DwmSetWindowAttribute(this.Handle, 2, ref v, 4);
                        MARGINS margins = new MARGINS()
                        {
                            bottomHeight = 1,
                            leftWidth = 0,
                            rightWidth = 0,
                            topHeight = 0
                        }; DwmExtendFrameIntoClientArea(this.Handle, ref margins);
                    }
                    break;
                default: break;
            }
            base.WndProc(ref m);
            if (m.Msg == WM_NCHITTEST && (int)m.Result == HTCLIENT) m.Result = (IntPtr)HTCAPTION;
        }
        private void PanelMove_MouseDown(object sender, MouseEventArgs e)
        {
            Drag = true;
            MouseX = Cursor.Position.X - this.Left;
            MouseY = Cursor.Position.Y - this.Top;
          
        }
        private void PanelMove_MouseMove(object sender, MouseEventArgs e)
        {
            if (Drag)
            {
                this.Top = Cursor.Position.Y - MouseY;
                this.Left = Cursor.Position.X - MouseX;
              
            }
        }
        private void PanelMove_MouseUp(object sender, MouseEventArgs e) { Drag = false; }

Попробовав на пустом проекте мне эта идея приглянулась.
Единственное что у формы теперь нет кнопок навигации, и никакой окантовки.

Ну да пофиг подумал я, и начал панелями создавать цветные формы.
Ващее огонь подумал я сделав одну форму. Нарадоваться не мог. Сделал вторую, думаю ништяк, но чёт я заколебался.
Впереди ещё 5 форм.
Каждой пририсовывать панель, это вроде не долго, но пока всё выставишь проходит 30 минут.

Ну и решил : "Создам-ка я своё расширение"
Не так давно почитал за расширения, и принялся писать.

Как в итоге получилось совсем немного.
Создал в отдельном статическом классе.

C#:
public static class FormComponent
    {
        //Элементы тоже статичные чтобы к ним обращаться
        public static Label label = new Label();
        public static Panel panel = new Panel();
        public static Panel panel2 = new Panel();
        public static Button close = new Button();
 
        public static void AddFormPanel(this Form form, string FormNameLabel)
        {
 
            Color HotTrack = ColorTranslator.FromHtml("#0066CC");
            Color White = ColorTranslator.FromHtml("#FFFFFF");
 
            form.FormBorderStyle = FormBorderStyle.None;
            form.BackColor = Color.FromKnownColor(KnownColor.ControlLightLight);
 
            panel2.Dock = DockStyle.Top;
            panel2.Height = 45;
            panel2.BackColor = Color.FromKnownColor(KnownColor.MenuHighlight);
 
            label.Text = FormNameLabel;
            label.ForeColor = Color.FromKnownColor(KnownColor.ControlLightLight);
            label.Font = new Font("Cambria", 14.25f, FontStyle.Italic);
            label.AutoSize = true;
            label.Location = new Point(3, 3);
 
            panel2.Controls.Add(label);
            form.Controls.Add(panel2);
 
            panel.Dock = DockStyle.Top;
            panel.Height = 25;
            panel.BackColor = HotTrack;
 
            close.Size = new Size(25, 25);
            close.Name = "bClose";
            close.Text = "X";
            close.FlatStyle = FlatStyle.Flat;
            close.FlatAppearance.BorderSize = 0;
            close.Location = new Point(form.Size.Width - close.Width - 3, -2);
            close.ForeColor = Color.FromKnownColor(KnownColor.ControlLightLight);
            close.Font = new Font("Comic Sans", 9.75f, FontStyle.Bold);
 
            panel.Controls.Add(close);
            form.Controls.Add(panel);
 
 
        }
 
 
    }

Код самый простой, и даёт на деле получить красивую картинку.
На основной форме пишем


C#:
public Form()
        {
            InitializeComponent();
            this.AddFormPanel("Новое задание");
            FormComponent.panel.MouseDown += new MouseEventHandler(PanelMove_MouseDown);
            FormComponent.panel.MouseMove += new MouseEventHandler(PanelMove_MouseMove);
            FormComponent.panel.MouseUp += new MouseEventHandler(PanelMove_MouseUp);
            FormComponent.panel2.MouseDown += new MouseEventHandler(PanelMove_MouseDown);
            FormComponent.panel2.MouseMove += new MouseEventHandler(PanelMove_MouseMove);
            FormComponent.panel2.MouseUp += new MouseEventHandler(PanelMove_MouseUp);
            FormComponent.close.Click += Close_Click;
        }
 
        private void Close_Click(object sender, EventArgs e)
        {
            this.Close();
        }
C#:
FormComponent.panel.MouseDown += new MouseEventHandler(PanelMove_MouseDown);
Даст возможность двигать не только за пиксель формы, но и за панель которую мы добавили.

А на выходе всего этого мы получаем
doc2.png




upd1. Для того чтобы края формы были закруглены в событие загрузки формы нужно добавить
C#:
IntPtr hRgn = CreateRoundRectRgn(0, 0, ШиринаФормы, ВысотаФормы, 10, 10); //10 это какой скос будет
            SetWindowRgn(this.Handle, hRgn, true);
upd2.Для того чтобы при перетаскивании была форма как на видео нужно добавить
C#:
this.Opacity = *
у меня стоит так
C#:
private void PanelMove_MouseMove(object sender, MouseEventArgs e)
        {
            if (Drag)
            {
                this.Top = Cursor.Position.Y - MouseY;
                this.Left = Cursor.Position.X - MouseX;
                this.Opacity = 0.5;
            }
        }
        private void PanelMove_MouseUp(object sender, MouseEventArgs e) { Drag = false; this.Opacity = 1; }
P.S. Возможно я для кого то наркоман, а возможно кому то это пригодится. Вот лично мне это нужно было.
Менять, добавлять изменять можно как душе угодно.
Тестовый проект приложил

Пробник приложил
 

Вложения

Сверху