{"id":16243922,"url":"https://github.com/emako/wpfui.violeta","last_synced_at":"2025-03-19T17:33:03.419Z","repository":{"id":252917160,"uuid":"841919482","full_name":"emako/wpfui.violeta","owner":"emako","description":"WPF UI Violeta is based on WPF UI, and provides the Fluent experience in your known and loved WPF framework.","archived":false,"fork":false,"pushed_at":"2025-03-13T12:29:27.000Z","size":3554,"stargazers_count":27,"open_issues_count":5,"forks_count":5,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-13T13:25:19.141Z","etag":null,"topics":["csharp","dotnet","fluent","mica","theme","ui","windows-10","windows-11","wpf","wpf-controls","wpf-ui","xaml"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/emako.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-08-13T10:02:56.000Z","updated_at":"2025-03-13T12:29:31.000Z","dependencies_parsed_at":"2024-09-18T09:34:22.640Z","dependency_job_id":"d20881b0-f49e-4914-a689-188f481b35e8","html_url":"https://github.com/emako/wpfui.violeta","commit_stats":null,"previous_names":["emako/wpfui.violeta"],"tags_count":29,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emako%2Fwpfui.violeta","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emako%2Fwpfui.violeta/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emako%2Fwpfui.violeta/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emako%2Fwpfui.violeta/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/emako","download_url":"https://codeload.github.com/emako/wpfui.violeta/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244010927,"owners_count":20383333,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csharp","dotnet","fluent","mica","theme","ui","windows-10","windows-11","wpf","wpf-controls","wpf-ui","xaml"],"created_at":"2024-10-10T14:16:54.117Z","updated_at":"2025-03-19T17:33:03.405Z","avatar_url":"https://github.com/emako.png","language":"C#","readme":"![WPF UI Banner Dark](https://user-images.githubusercontent.com/13592821/174165081-9c62d188-ecb6-4200-abd8-419afbaf32c2.png#gh-dark-mode-only)\n\n![WPF UI Banner Light](https://user-images.githubusercontent.com/13592821/174165388-921c4745-90ed-4396-9a4b-9c86478f7447.png#gh-light-mode-only)\n\n# WPF UI Violeta\n\n[![GitHub license](https://img.shields.io/github/license/emako/wpfui.violeta)](https://github.com/emako/wpfui.violeta/blob/master/LICENSE) [![NuGet](https://img.shields.io/nuget/v/WPF-UI.Violeta.svg)](https://nuget.org/packages/WPF-UI.Violeta) [![VS 2022 Downloads](https://img.shields.io/visual-studio-marketplace/i/lepo.WPF-UI?label=vs-2022)](https://marketplace.visualstudio.com/items?itemName=lepo.WPF-UI) [![Actions](https://github.com/emako/wpfui.violeta/actions/workflows/library.nuget.yml/badge.svg)](https://github.com/emako/wpfui.violeta/actions/workflows/library.nuget.yml) [![Platform](https://img.shields.io/badge/platform-Windows-blue?logo=windowsxp\u0026color=1E9BFA)](https://dotnet.microsoft.com/zh-cn/download/dotnet/latest/runtime)\n\nWPF UI Violeta is based on [WPF UI](https://github.com/lepoco/wpfui), and provides the Fluent experience in your known and loved WPF framework. Some new immersive controls like `Toast`, `Flyout`, `ContentDialog`, `MessageBox` and etc.\n\nSome idea or codes are ported from [ModernWpf](https://github.com/Kinnara/ModernWpf) and [Fischless](https://github.com/GenshinMatrix/Fischless).\n\nWhen I decided to create this project I was listening to the song `Violeta`.\n\n### 🚀 Getting started\n\nSimilar to WPF UI.\n\n```xaml\n\u003cApplication\n    xmlns:ui=\"http://schemas.lepo.co/wpfui/2022/xaml\"\n    xmlns:vio=\"http://schemas.lepo.co/wpfui/2022/xaml/violeta\"\u003e\n    \u003cApplication.Resources\u003e\n        \u003cResourceDictionary\u003e\n            \u003cResourceDictionary.MergedDictionaries\u003e\n                \u003cui:ThemesDictionary Theme=\"Dark\" /\u003e\n                \u003cui:ControlsDictionary /\u003e\n                \u003cvio:ThemesDictionary Theme=\"Dark\" /\u003e\n                \u003cvio:ControlsDictionary /\u003e\n            \u003c/ResourceDictionary.MergedDictionaries\u003e\n        \u003c/ResourceDictionary\u003e\n    \u003c/Application.Resources\u003e\n\u003c/Application\u003e\n```\n\n### 👋Examples\n\n[Wpf.Ui.Test](https://github.com/emako/wpfui.violeta/tree/master/src/Wpf.Ui.Test)\n\n- **Toast**\n\n  \u003e `Toast` is an independent popup notification that automatically disappears after a specified time.\n\n  ```c#\n  Toast.Information(\"I am information message\");\n  Toast.Error(\"I am error message\");\n  Toast.Success(\"I am success message\");\n  Toast.Warning(\"I am warning message\");\n  Toast.Show(owner: null!, \"I am any message\",  new ToastConfig());\n  ```\n\n- **Flyout**\n  \n  \u003e The `FlyoutService` enables you to attach `Flyout` menus or tooltips to various controls such as `Button`, providing a flexible and intuitive way to display additional content or options.\n  \n  ```xaml\n  \u003cui:Button Content=\"Show Flyout\"\u003e\n      \u003cui:FlyoutService.Flyout\u003e\n          \u003cui:Flyout Placement=\"Bottom\"\u003e\n              \u003cStackPanel\u003e\n                  \u003cTextBlock\n                      HorizontalAlignment=\"Left\"\n                      Text=\"Show the flyout message here\" /\u003e\n                   \u003cButton\n                     Command=\"{Binding GotItCommand}\"\n                     Content=\"Got it\" /\u003e\n              \u003c/StackPanel\u003e\n          \u003c/ui:Flyout\u003e\n      \u003c/ui:FlyoutService.Flyout\u003e\n  \u003c/ui:Button\u003e\n  ```\n  \n- **ContentDialogHostService**\n\n  \u003e The `ContentDialogHostService` simplifies the creation and management of `ContentDialog` instances in your application.\n\n  ```c#\n  Wpf.Ui.Controls.ContentDialog dialog = new()\n  {\n      Title = \"My sample dialog\",\n      Content = \"Content of the dialog\",\n      CloseButtonText = \"Close button\",\n      PrimaryButtonText = \"Primary button\",\n      SecondaryButtonText = \"Secondary button\"\n  };\n  \n  // Setting the dialog container\n  dialog.DialogHost = ContentDialogHostService.ContentPresenterForDialogs;\n  \n  // Showing the dialog\n  await dialog.ShowAsync(CancellationToken.None);\n  ```\n  \n- **ContentDialog**\n\n  \u003e The new `ContentDialog` is easy to use with smooth transitions.\n\n  ```c#\n  global using ContentDialog = Wpf.Ui.Violeta.Controls.ContentDialog;\n  global using ContentDialogButton = Wpf.Ui.Violeta.Controls.ContentDialogButton;\n  \n  ContentDialog dialog = new()\n  {\n      Title = \"My sample dialog\",\n      Content = \"Content of the dialog\",\n      CloseButtonText = \"Close button\",\n      PrimaryButtonText = \"Primary button\",\n      SecondaryButtonText = \"Secondary button\",\n      DefaultButton = ContentDialogButton.Primary,\n  };\n  \n  _ = await dialog.ShowAsync();\n  ```\n  \n\n​\tIf you want to inherit `Wpf.Ui.Violeta.Controls.ContentDialog` to implement a custom dialog just using `Style=\"{StaticResource DefaultVioletaContentDialogStyle}\"`.\n\n- **MessageBox**\n\n  \u003e To utilize Win32's classic `MessageBox` methods while supporting modern UI themes like Mica and dark mode.\n\n  ```c#\n  global using MessageBox = Wpf.Ui.Violeta.Controls.MessageBox;\n  \n  // Sync methods\n  _ = MessageBox.Information(\"This is a information message\");\n  _ = MessageBox.Warning(\"This is a warning message\");\n  _ = MessageBox.Error(\"This is a error message\");\n  MessageBoxResult result =  MessageBox.Question(\"This is a question and do you want to click OK?\");\n  \n  // Async methods\n  _ = await MessageBox.InformationAsync(\"This is a information message\");\n  _ = await MessageBox.WarningAsync(\"This is a warning message\");\n  _ = await MessageBox.ErrorAsync(\"This is a error message\");\n  MessageBoxResult result = await MessageBox.QuestionAsync(\"This is a question and do you want to click OK?\");\n  ```\n\n- **PendingBox**\n\n  \u003e Keep displaying 'Loading' until released.\n\n  ```c#\n  // Default style.\n  using IPendingHandler pending = PendingBox.Show();\n  \n  // Show with title and cancel button.\n  using IPendingHandler pending = PendingBox.Show(\"Doing something\", \"I'm a title\", isShowCancel: true);\n  ```\n\n\n- **ToggleButtonGroup** / **RadioButtonGroup** / **MenuItemGroup**\n\n  \u003e Turn the ToggleButton and RadioButton under the same Group into a radio button.\n\n  ```xaml\n  \u003cStackPanel Orientation=\"Horizontal\"\u003e\n      \u003cStackPanel.Resources\u003e\n          \u003cvio:ToggleButtonGroup x:Key=\"ToggleButtonGroup\" /\u003e\n      \u003c/StackPanel.Resources\u003e\n      \u003cToggleButton\n          vio:ToggleButtonGroup.Group=\"{DynamicResource ToggleButtonGroup}\"\n          Content=\"1st\"\n          IsChecked=\"True\" /\u003e\n      \u003cToggleButton\n          vio:ToggleButtonGroup.Group=\"{DynamicResource ToggleButtonGroup}\"\n          Content=\"2nd\" /\u003e\n  \u003c/StackPanel\u003e\n  ```\n  ```xaml\n  \u003cStackPanel Orientation=\"Horizontal\"\u003e\n      \u003cStackPanel.Resources\u003e\n          \u003cvio:RadioButtonGroup x:Key=\"RadioButtonGroup\" /\u003e\n      \u003c/StackPanel.Resources\u003e\n      \u003cRadioButton\n                   vio:RadioButtonGroup.Group=\"{DynamicResource RadioButtonGroup}\"\n                   Content=\"1st\"\n                   IsChecked=\"True\" /\u003e\n      \u003cGrid\u003e\n          \u003cRadioButton\n                       Margin=\"8,0,0,0\"\n                       vio:RadioButtonGroup.Group=\"{DynamicResource RadioButtonGroup}\"\n                       Content=\"2nd\" /\u003e\n      \u003c/Grid\u003e\n  \u003c/StackPanel\u003e\n  ```\n  \n- **Splash**\n\n  \u003e Show the Splash Screen in another UI thread.\n\n  ```c#\n  public App()\n  {\n      Splash.ShowAsync(\"pack://application:,,,/Wpf.Ui.Test;component/wpfui.png\");\n      InitializeComponent();\n  }\n  \n  public MainWindow()\n  {\n      InitializeComponent();\n      Splash.CloseOnLoaded(this, minimumMilliseconds: 1800);\n  }\n  ```\n\n- **TreeListView**\n\n  \u003e TreeListView is a better way to display hierarchical data.\n\n  ```xaml\n  \u003cui:TreeListView ItemsSource=\"{Binding StaffList}\"\u003e\n      \u003cui:TreeListView.Columns\u003e\n          \u003cGridViewColumnCollection\u003e\n              \u003cui:GridViewColumn Width=\"400\" Header=\"Name\"\u003e\n                  \u003cui:GridViewColumn.CellTemplate\u003e\n                      \u003cDataTemplate\u003e\n                          \u003cui:TreeRowExpander Content=\"{Binding Name}\" /\u003e\n                      \u003c/DataTemplate\u003e\n                  \u003c/ui:GridViewColumn.CellTemplate\u003e\n              \u003c/ui:GridViewColumn\u003e\n              \u003cui:GridViewColumn\n                                 Width=\"80\"\n                                 DisplayMemberBinding=\"{Binding Age}\"\n                                 Header=\"Age\" /\u003e\n              \u003cui:GridViewColumn\n                                 Width=\"80\"\n                                 DisplayMemberBinding=\"{Binding Sex}\"\n                                 Header=\"Sex\" /\u003e\n              \u003cui:GridViewColumn\n                                 Width=\"100\"\n                                 DisplayMemberBinding=\"{Binding Duty}\"\n                                 Header=\"Duty\" /\u003e\n              \u003cui:GridViewColumn Width=\"250\" Header=\"IsChecked\"\u003e\n                  \u003cui:GridViewColumn.CellTemplate\u003e\n                      \u003cDataTemplate\u003e\n                          \u003cui:ToggleSwitch IsChecked=\"{Binding IsChecked}\" /\u003e\n                      \u003c/DataTemplate\u003e\n                  \u003c/ui:GridViewColumn.CellTemplate\u003e\n              \u003c/ui:GridViewColumn\u003e\n          \u003c/GridViewColumnCollection\u003e\n      \u003c/ui:TreeListView.Columns\u003e\n      \u003cui:TreeListView.ItemTemplate\u003e\n          \u003cHierarchicalDataTemplate ItemsSource=\"{Binding StaffList}\" /\u003e\n      \u003c/ui:TreeListView.ItemTemplate\u003e\n  \u003c/ui:TreeListView\u003e\n  ```\n\n  ```c#\n  public partial class ViewModel : ObservableObject\n  {\n      [ObservableProperty]\n      private ObservableCollection\u003cStaff\u003e staffList = [];\n      \n      public void InitNode1Value()\n      {\n          Staff staff = new Staff()\n          {\n              Name = \"Alice\",\n              Age = 30,\n              Sex = \"Male\",\n              Duty = \"Manager\",\n              IsExpanded = true\n          };\n          Staff staff2 = new Staff()\n          {\n              Name = \"Alice1\",\n              Age = 21,\n              Sex = \"Male\",\n              Duty = \"Normal\",\n              IsExpanded = true\n          };\n          Staff staff3 = new Staff()\n          {\n              Name = \"Alice11\",\n              Age = 21,\n              Sex = \"Male\",\n              Duty = \"Normal\"\n          };\n          staff2.StaffList.Add(staff3);\n          staff3 = new Staff()\n          {\n              Name = \"Alice22\",\n              Age = 21,\n              Sex = \"Female\",\n              Duty = \"Normal\"\n          };\n          staff2.StaffList.Add(staff3);\n          staff.StaffList.Add(staff2);\n          staff2 = new Staff()\n          {\n              Name = \"Alice2\",\n              Age = 22,\n              Sex = \"Female\",\n              Duty = \"Normal\"\n          };\n          staff.StaffList.Add(staff2);\n          staff2 = new Staff()\n          {\n              Name = \"Alice3\",\n              Age = 23,\n              Sex = \"Female\",\n              Duty = \"Normal\"\n          };\n          staff.StaffList.Add(staff2);\n          StaffList.Add(staff);\n  \n          staff = new Staff()\n          {\n              Name = \"Bob\",\n              Age = 31,\n              Sex = \"Male\",\n              Duty = \"CEO\"\n          };\n          staff2 = new Staff()\n          {\n              Name = \"Bob1\",\n              Age = 24,\n              Sex = \"Female\",\n              Duty = \"Normal\"\n          };\n          staff.StaffList.Add(staff2);\n          staff2 = new Staff()\n          {\n              Name = \"Bob2\",\n              Age = 25,\n              Sex = \"Female\",\n              Duty = \"Normal\"\n          };\n          staff.StaffList.Add(staff2);\n          staff2 = new Staff()\n          {\n              Name = \"Bob3\",\n              Age = 26,\n              Sex = \"Male\",\n              Duty = \"Normal\"\n          };\n          staff.StaffList.Add(staff2);\n          StaffList.Add(staff);\n  \n          staff = new Staff()\n          {\n              Name = \"Cyber\",\n              Age = 32,\n              Sex = \"Female\",\n              Duty = \"Leader\"\n          };\n          staff2 = new Staff()\n          {\n              Name = \"Cyber1\",\n              Age = 27,\n              Sex = \"Female\",\n              Duty = \"Normal\"\n          };\n          staff.StaffList.Add(staff2);\n          staff2 = new Staff()\n          {\n              Name = \"Cyber2\",\n              Age = 28,\n              Sex = \"Female\",\n              Duty = \"Normal\"\n          };\n          staff.StaffList.Add(staff2);\n          StaffList.Add(staff);\n      }\n  }\n  \n  public partial class Staff : ObservableObject\n  {\n      [ObservableProperty]\n      private string name = null!;\n  \n      [ObservableProperty]\n      private int age;\n  \n      [ObservableProperty]\n      private string sex = null!;\n  \n      [ObservableProperty]\n      private string duty = null!;\n  \n      [ObservableProperty]\n      private bool isChecked = true;\n  \n      [ObservableProperty]\n      private bool isSelected = false;\n  \n      [ObservableProperty]\n      private bool isExpanded = false;\n  \n      [ObservableProperty]\n      private ObservableCollection\u003cStaff\u003e staffList = [];\n  }\n  ```\n  \n- **TreeModelListView**\n\n  \u003e TreeModelListView is a fast tree list view used `IEnumerable` and `ITreeModel` to display data but CURD is not fully supported.\n\n  ```xaml\n  \u003cui:TreeModelListView Model=\"{Binding TreeTestModel}\"\u003e\n   \u003cui:GridView\u003e\n       \u003cui:GridView.Columns\u003e\n           \u003cui:GridViewColumn Width=\"400\" Header=\"Column1\"\u003e\n               \u003cui:GridViewColumn.CellTemplate\u003e\n                   \u003cDataTemplate\u003e\n                       \u003cui:TreeModelRowExpander Content=\"{Binding Column1}\" /\u003e\n                   \u003c/DataTemplate\u003e\n               \u003c/ui:GridViewColumn.CellTemplate\u003e\n           \u003c/ui:GridViewColumn\u003e\n           \u003cui:GridViewColumn\n               Width=\"250\"\n               DisplayMemberBinding=\"{Binding Column2, Mode=TwoWay}\"\n               Header=\"Column2\" /\u003e\n           \u003cui:GridViewColumn\n               Width=\"250\"\n               DisplayMemberBinding=\"{Binding Column3, Mode=TwoWay}\"\n               Header=\"Column3\" /\u003e\n           \u003cui:GridViewColumn Width=\"250\" Header=\"IsChecked\"\u003e\n               \u003cui:GridViewColumn.CellTemplate\u003e\n                   \u003cDataTemplate\u003e\n                       \u003cui:ToggleSwitch IsChecked=\"{Binding IsChecked}\" /\u003e\n                   \u003c/DataTemplate\u003e\n               \u003c/ui:GridViewColumn.CellTemplate\u003e\n           \u003c/ui:GridViewColumn\u003e\n       \u003c/ui:GridView.Columns\u003e\n   \u003c/ui:GridView\u003e\n  \u003c/ui:TreeModelListView\u003e\n  ```\n\n  ```c#\n  public partial class ViewModel : ObservableObject\n  {\n      [ObservableProperty]\n      private TreeCollection\u003cTreeTestModel\u003e treeTestModel = CreateTestModel();\n      \n      public static TreeModelCollection\u003cTreeTestModel\u003e CreateTestModel()\n      {\n          return new TreeModelCollection\u003cTreeTestModel\u003e()\n          {\n              Children = new(\n              [\n                  new()\n                  {\n                      Column1 = \"Test 1\",\n                      Column2 = \"Test 1\",\n                      Column3 = \"Test 1\",\n                      Children = new(\n                      [\n                          new()\n                          {\n                              Column1 = \"Test 1.1\",\n                              Column2 = \"Test 1.1\",\n                              Column3 = \"Test 1.1\",\n                              Children = new(\n                              [\n                                  new()\n                                  {\n                                      Column1 = \"Test 1.2\",\n                                      Column2 = \"Test 1.2\",\n                                      Column3 = \"Test 1.2\",\n                                  },\n                              ]),\n                          },\n                      ]),\n                  },\n                  new()\n                  {\n                      Column1 = \"Test 2\",\n                      Column2 = \"Test 2\",\n                      Column3 = \"Test 2\",\n                  }\n              ]),\n          };\n      }\n  }\n  \n  [ObservableObject]\n  public partial class TreeTestModel : TreeModelObject\u003cTreeTestModel\u003e\n  {\n      [ObservableProperty]\n      private string? column1;\n  \n      [ObservableProperty]\n      private string? column2;\n  \n      [ObservableProperty]\n      private string? column3;\n  \n      [ObservableProperty]\n      private bool isChecked = false;\n  }\n  ```\n\n- **ImageView**\n\n  \u003e Provides a scalable image control.\n\n  ```xaml\n  \u003cvio:ImageView Source=\"/wpfui.png\" /\u003e\n  ```\n\n- **ExceptionReport**\n\n  \u003e Show a dialog to handle the `DispatcherUnhandledException` from Application.\n\n   ```c#\n  public partial class App : Application\n  {\n      public App()\n      {\n          InitializeComponent();\n  \n          DispatcherUnhandledException += (object s, DispatcherUnhandledExceptionEventArgs e) =\u003e\n          {\n              e.Handled = true;\n              ExceptionReport.Show(e.Exception);\n          };\n      }\n  }\n   ```\n\n- **BitmapIcon**\n\n  \u003e Supports to show monochrome image that match the theme color.\n\n   ```xaml\n  \u003cui:BitmapIcon\n                 ShowAsMonochrome=\"False\"\n                 UriSource=\"pack://application:,,,/Wpf.Ui.Test;component/Resources/Images/Tiara.png\" /\u003e\n  \u003cui:BitmapIcon\n                 ShowAsMonochrome=\"True\"\n                 UriSource=\"pack://application:,,,/Wpf.Ui.Test;component/Resources/Images/Tiara.png\" /\u003e\n   ```\n\n\n\n### 📷 Screenshots\n\nUnder construction\n\n### Thanks\n\n- [🔗 WPF-UI](https://github.com/lepoco/wpfui)\n- [🔗 Fischless](https://github.com/GenshinMatrix/Fischless)\n- [🔗 ModernWpf](https://github.com/Kinnara/ModernWpf)\n- [🔗 TreeListView](https://www.codeproject.com/Articles/30721/WPF-TreeListView-Control)\n- [🔗 CachedImage](https://github.com/floydpink/CachedImage)\n- [🔗 WpfAutoGrid.Core](https://github.com/budul100/WpfAutoGrid.Core)\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femako%2Fwpfui.violeta","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Femako%2Fwpfui.violeta","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femako%2Fwpfui.violeta/lists"}