- [C#] Hướng dẫn giải nén file *.rar với tiến trình progress bar winform
- [C#] Chia sẻ source code make Crazy Error Message Effect Bomb Windows
- [C#] Lập trình ứng dụng theo mô hình MVP Model-View-Presenter Pattern Winform
- [C#] Giới thiệu và những thứ hay ho từ thư viện System.Reactive của Microsoft
- [C#] Hướng dẫn tạo ứng dụng Chat với GPT sử dụng Open AI API
- [DEVEXPRESS] Tạo month picker trên DateEdit Winform C#
- [DATABASE] Cách sử dụng và lưu ý khi sử dụng khóa ngoại (Foreign Key) trong Sqlserver
- [C#] Garbage Collector (GC) là gì? Cách giải phóng bộ nhớ trên ứng dụng Winform khi các đối tượng không còn sử dụng
- [C#] Cách tính độ tương phản màu sắc Contrast Color mà con người có thể nhìn thấy được
- [C#] Hướng dẫn mã hóa mật khẩu tài khoản ứng dụng đúng chuẩn Men
- [C#] Sử dụng Open AI Chat GPT viết ứng dụng Count down timer có hiệu ứng trên winform
- [DATABASE] Chia sẻ dữ liệu Pantone Color sql và json api
- [SQLSERVER] Tạo mã sản phẩm tự động như: SP0001, SP0002, SP0003... sử dụng Trigger
- [C#] Hướng dẫn kiểm tra phiên bản NET Framework cài đặt ở máy tính
- [C#] Hướng dẫn đọc file excel đơn giản sử dụng thư viện Epplus
- [C#] ConcurrentBag là gì và cách sử dụng nó trong lập trình bất đồng bộ
- [C#] AutoResetEvent là gì và cách sử dụng
- [DEVEXPRESS] Chia sẻ source code cách tạo biểu đồ sơ đồ tổ chức công ty Org Chart trên Winform C#
- [C#] Hướng dẫn tạo Auto Number trên Datagridview winform
- [DATABASE] Hướng dẫn tạo Procedure String Split in Mysql
[DEVEXPRESS] Hướng dẫn switch tab trong Fluent Design Form
Xin chào các bạn, bài viết hôm nay mình sẻ chia sẽ đến các bạn source code cách Switch Tab trên giao diện Fluent Design Form của Devexpress C#.
[DEVEXPRESS] SWITCH TAB FLUENT DESIGN FORM C#
Lý do mình viết bài Switch Tab này là do trong giao diện Fluent Design Form, Devexpress không có hỗ trợ chức năng MDI containers Form trên giao diện này.
Nên khi các bạn mở tab đều là đưa từng Usercontrol vào FluentDesignFormContainer.
Nên khi chúng ta muốn di chuyển qua lại giữa các tab đã mở lên sẽ vào lại từng menu trên HamburgerMenu để mở lại.
Dưới đây là giao diện mình thiết kế Switch Tab trên c#:
Khi mở một tab form, mình sẽ chụp màn hình lại của từng userControl khi add vào.
Và mình sẽ kết hợp FlyoutPanel và Gridcontrol ở chế độ LayoutView để hiển thị thumbnail tab như hình bên dưới.
Ở source code demo này mình có sử dụng TrackerProcess, để sử dụng Splash Screen Loading và Overlay winform.
Các bạn download code cuối bài để tham khảo và sử dụng.
Source code c# MainForm.cs:
using DevExpress.LookAndFeel;
using DevExpress.Mvvm;
using DevExpress.Skins;
using DevExpress.Utils.Drawing;
using DevExpress.Utils.Taskbar;
using DevExpress.Utils.Taskbar.Core;
using DevExpress.XtraBars;
using DevExpress.XtraBars.Navigation;
using DevExpress.XtraPrinting.Drawing;
using DevExpress.XtraSplashScreen;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Windows.Media.Imaging;
namespace FluentWinform
{
public partial class MainForm : DevExpress.XtraBars.FluentDesignSystem.FluentDesignForm
{
public List<TabOpened> dicFormOpened = new List<TabOpened>();
public string currentFormOpened = "";
public MainForm()
{
AppProvider.MainForm = this;
StartUpProcess.OnStart("Starting...");
InitializeComponent();
//Thread.Sleep(1000);
StartUpProcess.OnComplete();
//Thread.Sleep(1000);
}
protected override void OnShown(EventArgs e)
{
base.OnShown(e);
}
private void accordionControlElement2_Click(object sender, EventArgs e)
{
OpenForm(uc_employees.Instance);
}
private void accordionControlElement3_Click(object sender, EventArgs e)
{
OpenForm(uc_customers.Instance);
}
private void Form1_Load(object sender, EventArgs e)
{
accordionControlElement2_Click(null, null);
accordionControl1.SelectedElement = elementEmployee;
}
public void OpenForm(UserControl userControl)
{
//formIsActive = userControl.Tag?.ToString();
if (!dicFormOpened.Exists(x => x.name == currentFormOpened))
{ foreach(Control item in div_container.Controls)
{
if (!string.IsNullOrEmpty(currentFormOpened) && item.Tag?.ToString() == currentFormOpened)
{
var image = GetImageFromControl(this);
var tabOpened = new TabOpened();
tabOpened.name = item.Tag.ToString();
tabOpened.UserControl = item;
tabOpened.image = image;
dicFormOpened.Add(tabOpened); ;
break;
}
}
}
if (!div_container.Controls.Contains(userControl))
{
OverlayLoading.handle = OverlayLoading.ShowProgressPanel(this);
Thread.Sleep(200);
div_container.Controls.Add(userControl);
userControl.Dock = DockStyle.Fill;
userControl.BringToFront();
OverlayLoading.CloseProgressPanel(OverlayLoading.handle);
}
else
{
userControl.BringToFront();
}
currentFormOpened = userControl.Tag?.ToString();
}
public class TabOpened{
public string name { set; get; }
public Control UserControl { set; get; }
public Image image { set; get; }
}
protected SkinElement GetSeparatorSkinElement(UserLookAndFeel lookAndFeel)
{
SkinElement elem = AccordionControlSkins.GetSkin(lookAndFeel.ActiveLookAndFeel)[AccordionControlSkins.SkinSeparator];
if (elem != null) return elem;
return CommonSkins.GetSkin(lookAndFeel.ActiveLookAndFeel)[CommonSkins.SkinLabelLine];
}
protected void DrawSeparator(GraphicsCache cache, AccordionElementBaseViewInfo elementInfo)
{
SkinElement skinElem = GetSeparatorSkinElement(elementInfo.ControlInfo.LookAndFeel);
Rectangle rect = new Rectangle(elementInfo.HeaderBounds.X, elementInfo.HeaderBounds.Bottom - skinElem.Size.MinSize.Height, elementInfo.HeaderBounds.Width, skinElem.Size.MinSize.Height);
SkinElementInfo skinElemInfo = new SkinElementInfo(skinElem, rect);
ObjectPainter.DrawObject(cache, SkinElementPainter.Default, skinElemInfo);
}
private void accordionControl1_CustomDrawElement(object sender, DevExpress.XtraBars.Navigation.CustomDrawElementEventArgs e)
{
int selectionWidth = 3;
SkinElement elem = HamburgerMenuSkins.GetSkin(UserLookAndFeel.Default)[HamburgerMenuSkins.SkinItem];
int _tag = Convert.ToInt32(e.ObjectInfo.Element.Tag);
if(_tag<0) return;
e.Handled = true;
e.DrawHeaderBackground();
e.DrawImage();
e.DrawText();
if (Equals(accordionControl1.SelectedElement, e.ObjectInfo.Element))
e.Cache.FillRectangle(Color.Orange, new Rectangle(e.ObjectInfo.HeaderBounds.Location, new Size(ScaleHelper.ScaleHorizontal(selectionWidth), e.ObjectInfo.HeaderBounds.Height)));
//e.Cache.FillRectangle(elem.GetForeColor(ObjectState.Pressed), new Rectangle(e.ObjectInfo.HeaderBounds.Location, new Size(ScaleHelper.ScaleHorizontal(selectionWidth), e.ObjectInfo.HeaderBounds.Height)));
float x = e.ObjectInfo.HeaderBounds.Width - e.ObjectInfo.HeaderBounds.X - e.ObjectInfo.TextBounds.X;
float y = e.ObjectInfo.TextBounds.Y;
Font fn = accordionControl1.Appearance.Item.Normal.Font;
if (_tag == 2)
{
int elementTag = e.ObjectInfo.Element.Tag is int ? (int)e.ObjectInfo.Element.Tag : -1;
ObjectState state = Equals(elementTag, _tag) ? ObjectState.Pressed : ObjectState.Hot;
var bounds = new Rectangle((int)x - 6, (int)y, 20, 20);
var myBrush = new SolidBrush(Color.DarkOrange);
using (GraphicsPath path = RoundedRect(bounds, 5))
{
e.Cache.FillPath(myBrush, path);
}
e.Cache.DrawString(dicFormOpened.Count.ToString(), fn, e.Cache.GetSolidBrush(elem.GetForeColor(state)), x, y);
}
if(_tag == 4)
{
DrawSeparator(e.Cache, e.ObjectInfo);
}
}
public Bitmap GetImageFromControl(Control control)
{
Size ctrlSize = control.Size;
Rectangle rect = new Rectangle(new Point(0, 0), ctrlSize);
using (Bitmap bitmap = new Bitmap(ctrlSize.Width, ctrlSize.Height))
{
Bitmap captureBitmap = new Bitmap(1024, 768, PixelFormat.Format32bppArgb);
Rectangle captureRectangle = Screen.AllScreens[0].Bounds;
Graphics captureGraphics = Graphics.FromImage(captureBitmap);
captureGraphics.CopyFromScreen(captureRectangle.Left, captureRectangle.Top, 0, 0, captureRectangle.Size);
return captureBitmap;
}
}
public static GraphicsPath RoundedRect(Rectangle bounds, int radius)
{
int diameter = radius * 2;
Size size = new Size(diameter, diameter);
Rectangle arc = new Rectangle(bounds.Location, size);
GraphicsPath path = new GraphicsPath();
if (radius == 0)
{
path.AddRectangle(bounds);
return path;
}
path.AddArc(arc, 180, 90);
arc.X = bounds.Right - diameter;
path.AddArc(arc, 270, 90);
arc.Y = bounds.Bottom - diameter;
path.AddArc(arc, 0, 90);
arc.X = bounds.Left;
path.AddArc(arc, 90, 90);
path.CloseFigure();
return path;
}
private void accordionControlElement2_Click_1(object sender, EventArgs e)
{
OpenForm(uc_log.Instance);
}
private void accordionControlElement20_Click(object sender, EventArgs e)
{
OpenForm(uc_systems.Instance);
}
private void elementSwitchTab_Click(object sender, EventArgs e)
{
if (dicFormOpened.Count > 0)
{
gridControl1.DataSource = null;
gridControl1.RefreshDataSource();
gridControl1.DataSource = dicFormOpened;
flyoutPanel1.Options.AnchorType = DevExpress.Utils.Win.PopupToolWindowAnchor.Center;
flyoutPanel1.Width = this.Width;
flyoutPanel1.Height = this.Height / 2;
flyoutPanel1.Hiding += FlyoutPanel1_Hiding;
OverlayFormShow.Instance.ShowFormOverlay(this);
flyoutPanel1.ShowPopup();
}
}
private void FlyoutPanel1_Hiding(object sender, DevExpress.Utils.FlyoutPanelEventArgs e)
{
OverlayFormShow.Instance.CloseProgressPanel();
}
private void flyoutPanel1_ButtonClick(object sender, DevExpress.Utils.FlyoutPanelButtonClickEventArgs e)
{
if (e.Button.Tag.ToString().Equals("close"))
{
flyoutPanel1.HidePopup();
}
}
private void layoutView1_CardClick(object sender, DevExpress.XtraGrid.Views.Layout.Events.CardClickEventArgs e)
{
var tabSelected = layoutView1.GetRow(e.RowHandle) as TabOpened;
OpenForm(tabSelected.UserControl as UserControl);
OverlayFormShow.Instance.CloseProgressPanel();
flyoutPanel1.HidePopup();
}
}
}
Thanks for watching!