میکا یک ماده مات و پویا است که از تم و تصویر زمینه دسکتاپ، برای نقاشی پسزمینه پنجرههایی با عمر طولانی، مانند برنامهها و تنظیمات استفاده میکند. Mica به طور خاص برای عملکرد برنامه طراحی شدهاست؛ زیرا فقط یکبار از تصویر زمینه دسکتاپ نمونه برداری میکند تا تجسم آن را ایجاد کند. میکا بر خلاف متریال آکریلیک، بسیار بهینه است و از منابع کمتری استفاده میکند.
تصویر زیر، متریال میکا را در حالت تاریک نمایش میدهد.
میکا مادهای است که در پسزمینه برنامه شما، پشت همه محتوای دیگر ظاهر میشود. این یک مادهی مات است که از تم کاربر و کاغذ دیواری دسکتاپ استفاده میکند تا ظاهر بسیار شخصی سازی شدهی خود را ایجاد کند. همانطور که کاربر پنجره را در سراسر صفحه حرکت میدهد، مواد Mica به صورت پویا برای ایجاد یک تجسم غنی با استفاده از کاغذ دیواری، زیر برنامه سازگار میشود. علاوه بر این، این مواد به کاربران کمک میکند تا زمانیکه برنامه غیرفعال است، روی کار فعلی تمرکز کنند و به رنگ خنثی برگردند.
توصیه میکنیم از Mica بهعنوان لایه پایه برنامهتان استفاده کنید.
Mica به طور خودکار ظاهر خود را برای طیف گستردهای از دستگاهها و زمینهها تطبیق میدهد. Mica برای عملکرد، طراحی شدهاست؛ زیرا فقط یکبار تصویر زمینهی پس زمینه را برای ایجاد تجسم آن میگیرد. در حالت کنتراست بالا، کاربران همچنان رنگ پسزمینهی آشنای انتخابی خود را بجای میکا مشاهده میکنند.
علاوه بر این، Mica به عنوان یک رنگ بازگشتی ثابت ظاهر میشود (SolidBackgroundFillColorBase):
برای کاربران WinUI، استفاده از میکا بسیار سادهاست. آنها به کمک کلاس BackdropMaterial و پراپرتی ApplyToRootOrPageBackground بهراحتی میتوانند میکا را برای UIElement خود فعال کنند. اما برای استفاده از میکا در برنامههای WPF، ما باید به کمک توابع محلی ویندوز، میکا را فعال کنیم. توجه داشته باشید که توابع مورد استفاده بصورت UnDocument می باشد که به این معنی میباشد که بصورت رسمی مستند سازی نشده و هر لحظه امکان حذف و یا تغییر آن میباشد. همچنین به این نکته باید دقت نمود که میکا فقط بر روی نسخه ویندوز 11 و بالاتر فعال میشود و در ویندوز 10 و ... هیچ اتفاقی رخ نمیدهد.
روش کار به این صورت میباشد که باید Flag مربوطه را به HWND متصل کنیم. ابتدا یک پروژهی WPF را ایجاد کنید و سپس کلاسی را با نام NativeMethods ایجاد و کدهای زیر را در آن کپی کنید:
public static class NativeMethods { public enum DWMWINDOWATTRIBUTE : int { USE_IMMERSIVE_DARK_MODE = 20, MICA_EFFECT = 1029 } [StructLayout(LayoutKind.Sequential)] public struct MARGINS { public MARGINS(int left, int top, int right, int bottom) { this.Left = left; this.Top = top; this.Right = right; this.Bottom = bottom; } /// <summary>Width of left border that retains its size.</summary> public int Left; /// <summary>Width of right border that retains its size.</summary> public int Right; /// <summary>Height of top border that retains its size.</summary> public int Top; /// <summary>Height of bottom border that retains its size.</summary> public int Bottom; } [DllImport("dwmapi.dll")] public static extern int DwmSetWindowAttribute(IntPtr hwnd, DWMWINDOWATTRIBUTE attr, ref int attrValue, int attrSize); [DllImport("dwmapi.dll")] public static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS pMarInset); public static bool SetWindowAttributeValue(IntPtr hWnd, DWMWINDOWATTRIBUTE attribute, int attributeValue) { return SetWindowAttribute(hWnd, attribute, ref attributeValue); } public static bool SetWindowAttribute(IntPtr hWnd, DWMWINDOWATTRIBUTE attribute, ref int attributeValue) { var result = DwmSetWindowAttribute(hWnd, attribute, ref attributeValue, sizeof(int)); return result == 0; } public static bool WindowExtendIntoClientArea(IntPtr hWnd, MARGINS margins) { // Extend frame on the bottom of client area var result = DwmExtendFrameIntoClientArea(hWnd, ref margins); return result == 0; } }
حال به MainWindow.xaml.cs مراجعه کنید. برای اینکه براش واقعاً نشان داده شود، باید کروم داخلی WPF را با یک بازنویسی WindowChrome حذف کنیم:
(شما همچنین میتوانید از WindowStyle.None استفاده کنید، اما WindowChrome به شما امکان میدهد کنترلهای سیستمی را حفظ کنید که مفید خواهد بود.)
this.Background = Brushes.Transparent; var chrome = new WindowChrome { CornerRadius = default(CornerRadius), GlassFrameThickness = new Thickness(0, 0, 0, 1), UseAeroCaptionButtons = true }; WindowChrome.SetWindowChrome(this, chrome);
دقت کنید که شما این کدها را در xaml هم میتوانید بنویسید.
حالا باید متد فعال سازی میکا را بعد از InitializeComponent بنویسید.
UpdateWindowEffect(this, this.IsActive);
کد کامل:
public MainWindow() { this.Background = Brushes.Transparent; var chrome = new WindowChrome { CornerRadius = default(CornerRadius), GlassFrameThickness = new Thickness(0, 0, 0, 1), UseAeroCaptionButtons = true }; WindowChrome.SetWindowChrome(this, chrome); InitializeComponent(); UpdateWindowEffect(this); }
متد فعال سازی:
public void UpdateWindowEffect(Window window) { UpdateWindowEffect(new WindowInteropHelper(window).EnsureHandle()); } public void UpdateWindowEffect(IntPtr windowHandle) { EnableMicaEffect(windowHandle, true); } private void EnableMicaEffect(IntPtr windowHandle, bool isDarkTheme) { NativeMethods.WindowExtendIntoClientArea(windowHandle, new NativeMethods.MARGINS(-1, -1, -1, -1)); var trueValue = 0x01; var falseValue = 0x00; // Set dark mode before applying the material, otherwise you'll get an ugly flash when displaying the window. if (isDarkTheme) { NativeMethods.SetWindowAttributeValue(windowHandle, NativeMethods.DWMWINDOWATTRIBUTE.USE_IMMERSIVE_DARK_MODE, trueValue); } else { NativeMethods.SetWindowAttributeValue(windowHandle, NativeMethods.DWMWINDOWATTRIBUTE.USE_IMMERSIVE_DARK_MODE, falseValue); } NativeMethods.SetWindowAttributeValue(windowHandle, NativeMethods.DWMWINDOWATTRIBUTE.MICA_EFFECT, trueValue); }
در کدهای بالا، بصورت پیشفرض میکا بصورت دارک اجرا میشود. لذا با توجه به تم سیستم عامل ویندوز خود، باید میکا را فعال سازی کنید ( در فراخوانی متد EnableMicaEffect مقدار true به معنای فعال سازی بصورت تم تاریک میباشد. اگر ویندوز شما از تم روشن استفاده میکند باید این مقدار را false کنید.)
وقتی پرچم USE_IMMERSIVE_DARK_MODE تنظیم میشود، براش Mica را مجبور میکند تا در حالت تاریک رندر شود.