- [C#] Hướng dẫn viết ứng dụng theo dõi máy in bao nhiêu trang (Monitor Printer)
- [C#] Lấy thông tin cấu hình máy tính xuất ra text file winform
- [C#] Chia sẽ class Install, Uninstall, Start và Stop Services Winform
- [C#] Tìm kiếm tập tin file nhanh chóng trên Winform sử dụng thư viện FastSearchLibrary
- [C#] Giới thiệu thư viện Fluent FTP Awesome dùng để làm việc với FTP
- [C#] Sử dụng thư viện Mini Profiler Integrations ghi log thực hiện các câu lệnh SQL
- [DEVEXPRESS] Thiết kế Dropdown ButtonBarItem trên Form Ribbon
- [C#] Lưu trạng thái các control trên Winform vào Registry Windows
- [C#] Ứng dụng ví dụ Simple Observer Pattern tăng giảm số lượng trên winform
- [C#] Hướng dẫn lấy thời gian thực server time trên winform
- [DEVEXPRESS] Hướng dẫn bật tính năng Scroll Pixcel in Touch trên GridView
- [DEVEXPRESS] Hướng dẫn sử dụng TileBar viết ứng dụng duyệt hình ảnh Winform
- [DEVEXPRESS] Tô màu border TextEdit trên Winform
- [C#] Lấy dữ liệu từ Console Write hiển thị lên textbox Winform
- [C#] Hiển thị Progress bar trên Window Console
- [C#] Di chuyển control Runtime và lưu layout trên winform
- [SQLSERVER] Sử dụng hàm NULL IF
- [C#] Chia sẽ source code mã đi tuần bằng giao diện Winform
- [C#] Flash Window in Taskbar Winform
- Download và Giải nén tập tin File sử dụng Powershell
[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!