- [C#] Hướng dẫn fix lỗi Visual Studio 2022 not Support Target Net Framework 4.5.2
- [C#] Giới thiệu thư viện Sunny UI thiết kế giao diện trên Winform
- [DATABASE] Hướng dẫn thêm và cập nhật Extended Property Column trong Table Sqlserver
- [DEVEXPRESS] Hướng dẫn sử dụng Vertical Gridview để hiển thị thông tin sản phẩm
- [C#] Hướng dẫn sử dụng Json Schema để Validate chuỗi string có phải json
- [C#] Hướng dẫn sử dụng công cụ Clean Code trên Visual Studio
- [C#] Hướng dẫn Drag and Drop File vào RichTextBox
- [C#] Hướng dẫn tạo hiệu ứng Karaoke Text Effect Winform
- [C#] Sử dụng thư viện ZedGraph vẽ biểu đồ Line, Bar, Pie trên Winform
- [DATABASE] Hướng dẫn sort sắp xếp địa chỉ IP trên sqlserver sử dụng hàm PARSENAME
- [C#] Theo dõi sử kiện process Start hay Stop trên Winform
- [ASP.NET] Chia sẻ source code chụp hình sử dụng camera trên website
- [C#] Chạy ứng dụng trên Virtual Desktop (màn hình ảo) Winform
- [C#] Mã hóa và giải mã Data Protection API trên winform
- [C#] Hướng dẫn tạo Gradient Background trên Winform
- [DATABASE] Hướng dẫn convert Epoch to DateTime trong sqlserver
- [DATABASE] Hướng dẫn sử dụng STRING_AGG và CONCAT_WS trong sqlserver 2017
- [C#] Hướng dẫn Copy With All Property in Class Object
- [DEVEXPRESS] Hướng dẫn load Json DataSource vào GridView
- [C#] Hướng dẫn tạo chữ ký trên winform Signature Pad
[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!