WPF-UI.Violeta
3.0.5.23
dotnet add package WPF-UI.Violeta --version 3.0.5.23
NuGet\Install-Package WPF-UI.Violeta -Version 3.0.5.23
<PackageReference Include="WPF-UI.Violeta" Version="3.0.5.23" />
paket add WPF-UI.Violeta --version 3.0.5.23
#r "nuget: WPF-UI.Violeta, 3.0.5.23"
// Install WPF-UI.Violeta as a Cake Addin #addin nuget:?package=WPF-UI.Violeta&version=3.0.5.23 // Install WPF-UI.Violeta as a Cake Tool #tool nuget:?package=WPF-UI.Violeta&version=3.0.5.23
WPF UI Violeta
WPF UI Violeta is based on WPF UI, and provides the Fluent experience in your known and loved WPF framework. Some new immersive controls like Toast
, Flyout
, ContentDialog
, MessageBox
and etc.
Some idea or codes are ported from ModernWpf and Fischless.
When I decided to create this project I was listening to the song Violeta
.
🚀 Getting started
Similar to WPF UI.
<Application
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:vio="http://schemas.lepo.co/wpfui/2022/xaml/violeta">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ui:ThemesDictionary Theme="Dark" />
<ui:ControlsDictionary />
<vio:ThemesDictionary Theme="Dark" />
<vio:ControlsDictionary />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
👋Examples
Toast
Toast
is an independent popup notification that automatically disappears after a specified time.Toast.Information("I am information message"); Toast.Error("I am error message"); Toast.Success("I am success message"); Toast.Warning("I am warning message"); Toast.Show(owner: null!, "I am any message", new ToastConfig());
Flyout
The
FlyoutService
enables you to attachFlyout
menus or tooltips to various controls such asButton
, providing a flexible and intuitive way to display additional content or options.<ui:Button Content="Show Flyout"> <ui:FlyoutService.Flyout> <ui:Flyout Placement="Bottom"> <StackPanel> <TextBlock HorizontalAlignment="Left" Text="Show the flyout message here" /> <Button Command="{Binding GotItCommand}" Content="Got it" /> </StackPanel> </ui:Flyout> </ui:FlyoutService.Flyout> </ui:Button>
ContentDialogHostService
The
ContentDialogHostService
simplifies the creation and management ofContentDialog
instances in your application.Wpf.Ui.Controls.ContentDialog dialog = new() { Title = "My sample dialog", Content = "Content of the dialog", CloseButtonText = "Close button", PrimaryButtonText = "Primary button", SecondaryButtonText = "Secondary button" }; // Setting the dialog container dialog.DialogHost = ContentDialogHostService.ContentPresenterForDialogs; // Showing the dialog await dialog.ShowAsync(CancellationToken.None);
ContentDialog
The new
ContentDialog
is easy to use with smooth transitions.global using ContentDialog = Wpf.Ui.Violeta.Controls.ContentDialog; global using ContentDialogButton = Wpf.Ui.Violeta.Controls.ContentDialogButton; ContentDialog dialog = new() { Title = "My sample dialog", Content = "Content of the dialog", CloseButtonText = "Close button", PrimaryButtonText = "Primary button", SecondaryButtonText = "Secondary button", DefaultButton = ContentDialogButton.Primary, }; _ = await dialog.ShowAsync();
MessageBox
To utilize Win32's classic
MessageBox
methods while supporting modern UI themes like Mica and dark mode.global using MessageBox = Wpf.Ui.Violeta.Controls.MessageBox; // Sync methods _ = MessageBox.Information("This is a information message"); _ = MessageBox.Warning("This is a warning message"); _ = MessageBox.Error("This is a error message"); MessageBoxResult result = MessageBox.Question("This is a question and do you want to click OK?"); // Async methods _ = await MessageBox.InformationAsync("This is a information message"); _ = await MessageBox.WarningAsync("This is a warning message"); _ = await MessageBox.ErrorAsync("This is a error message"); MessageBoxResult result = await MessageBox.QuestionAsync("This is a question and do you want to click OK?");
ToggleButtonGroup / RadioButtonGroup / MenuItemGroup
Turn the ToggleButton and RadioButton under the same Group into a radio button.
<StackPanel Orientation="Horizontal"> <StackPanel.Resources> <vio:ToggleButtonGroup x:Key="ToggleButtonGroup" /> </StackPanel.Resources> <ToggleButton vio:ToggleButtonGroup.Group="{DynamicResource ToggleButtonGroup}" Content="1st" IsChecked="True" /> <ToggleButton vio:ToggleButtonGroup.Group="{DynamicResource ToggleButtonGroup}" Content="2nd" /> </StackPanel>
<StackPanel Orientation="Horizontal"> <StackPanel.Resources> <vio:RadioButtonGroup x:Key="RadioButtonGroup" /> </StackPanel.Resources> <RadioButton vio:RadioButtonGroup.Group="{DynamicResource RadioButtonGroup}" Content="1st" IsChecked="True" /> <Grid> <RadioButton Margin="8,0,0,0" vio:RadioButtonGroup.Group="{DynamicResource RadioButtonGroup}" Content="2nd" /> </Grid> </StackPanel>
Splash
Show the Splash Screen in another UI thread.
public App() { Splash.ShowAsync("pack://application:,,,/Wpf.Ui.Test;component/wpfui.png"); InitializeComponent(); } public MainWindow() { InitializeComponent(); Splash.CloseOnLoaded(this, minimumMilliseconds: 1800); }
TreeListView
TreeListView is a better way to display hierarchical data.
<ui:TreeListView ItemsSource="{Binding StaffList}"> <ui:TreeListView.Columns> <GridViewColumnCollection> <ui:GridViewColumn Width="400" Header="Name"> <ui:GridViewColumn.CellTemplate> <DataTemplate> <ui:TreeRowExpander Content="{Binding Name}" /> </DataTemplate> </ui:GridViewColumn.CellTemplate> </ui:GridViewColumn> <ui:GridViewColumn Width="80" DisplayMemberBinding="{Binding Age}" Header="Age" /> <ui:GridViewColumn Width="80" DisplayMemberBinding="{Binding Sex}" Header="Sex" /> <ui:GridViewColumn Width="100" DisplayMemberBinding="{Binding Duty}" Header="Duty" /> <ui:GridViewColumn Width="250" Header="IsChecked"> <ui:GridViewColumn.CellTemplate> <DataTemplate> <ui:ToggleSwitch IsChecked="{Binding IsChecked}" /> </DataTemplate> </ui:GridViewColumn.CellTemplate> </ui:GridViewColumn> </GridViewColumnCollection> </ui:TreeListView.Columns> <ui:TreeListView.ItemTemplate> <HierarchicalDataTemplate ItemsSource="{Binding StaffList}" /> </ui:TreeListView.ItemTemplate> </ui:TreeListView>
public partial class ViewModel : ObservableObject { [ObservableProperty] private ObservableCollection<Staff> staffList = []; public void InitNode1Value() { Staff staff = new Staff() { Name = "Alice", Age = 30, Sex = "Male", Duty = "Manager", IsExpanded = true }; Staff staff2 = new Staff() { Name = "Alice1", Age = 21, Sex = "Male", Duty = "Normal", IsExpanded = true }; Staff staff3 = new Staff() { Name = "Alice11", Age = 21, Sex = "Male", Duty = "Normal" }; staff2.StaffList.Add(staff3); staff3 = new Staff() { Name = "Alice22", Age = 21, Sex = "Female", Duty = "Normal" }; staff2.StaffList.Add(staff3); staff.StaffList.Add(staff2); staff2 = new Staff() { Name = "Alice2", Age = 22, Sex = "Female", Duty = "Normal" }; staff.StaffList.Add(staff2); staff2 = new Staff() { Name = "Alice3", Age = 23, Sex = "Female", Duty = "Normal" }; staff.StaffList.Add(staff2); StaffList.Add(staff); staff = new Staff() { Name = "Bob", Age = 31, Sex = "Male", Duty = "CEO" }; staff2 = new Staff() { Name = "Bob1", Age = 24, Sex = "Female", Duty = "Normal" }; staff.StaffList.Add(staff2); staff2 = new Staff() { Name = "Bob2", Age = 25, Sex = "Female", Duty = "Normal" }; staff.StaffList.Add(staff2); staff2 = new Staff() { Name = "Bob3", Age = 26, Sex = "Male", Duty = "Normal" }; staff.StaffList.Add(staff2); StaffList.Add(staff); staff = new Staff() { Name = "Cyber", Age = 32, Sex = "Female", Duty = "Leader" }; staff2 = new Staff() { Name = "Cyber1", Age = 27, Sex = "Female", Duty = "Normal" }; staff.StaffList.Add(staff2); staff2 = new Staff() { Name = "Cyber2", Age = 28, Sex = "Female", Duty = "Normal" }; staff.StaffList.Add(staff2); StaffList.Add(staff); } } public partial class Staff : ObservableObject { [ObservableProperty] private string name = null!; [ObservableProperty] private int age; [ObservableProperty] private string sex = null!; [ObservableProperty] private string duty = null!; [ObservableProperty] private bool isChecked = true; [ObservableProperty] private bool isSelected = false; [ObservableProperty] private bool isExpanded = false; [ObservableProperty] private ObservableCollection<Staff> staffList = []; }
TreeModelListView
TreeModelListView is a fast tree list view used
IEnumerable
andITreeModel
to display data but CURD is not fully supported.<ui:TreeModelListView Model="{Binding TreeTestModel}"> <ui:GridView> <ui:GridView.Columns> <ui:GridViewColumn Width="400" Header="Column1"> <ui:GridViewColumn.CellTemplate> <DataTemplate> <ui:TreeModelRowExpander Content="{Binding Column1}" /> </DataTemplate> </ui:GridViewColumn.CellTemplate> </ui:GridViewColumn> <ui:GridViewColumn Width="250" DisplayMemberBinding="{Binding Column2, Mode=TwoWay}" Header="Column2" /> <ui:GridViewColumn Width="250" DisplayMemberBinding="{Binding Column3, Mode=TwoWay}" Header="Column3" /> <ui:GridViewColumn Width="250" Header="IsChecked"> <ui:GridViewColumn.CellTemplate> <DataTemplate> <ui:ToggleSwitch IsChecked="{Binding IsChecked}" /> </DataTemplate> </ui:GridViewColumn.CellTemplate> </ui:GridViewColumn> </ui:GridView.Columns> </ui:GridView> </ui:TreeModelListView>
public partial class ViewModel : ObservableObject { [ObservableProperty] private TreeCollection<TreeTestModel> treeTestModel = CreateTestModel(); public static TreeModelCollection<TreeTestModel> CreateTestModel() { return new TreeModelCollection<TreeTestModel>() { Children = new( [ new() { Column1 = "Test 1", Column2 = "Test 1", Column3 = "Test 1", Children = new( [ new() { Column1 = "Test 1.1", Column2 = "Test 1.1", Column3 = "Test 1.1", Children = new( [ new() { Column1 = "Test 1.2", Column2 = "Test 1.2", Column3 = "Test 1.2", }, ]), }, ]), }, new() { Column1 = "Test 2", Column2 = "Test 2", Column3 = "Test 2", } ]), }; } } [ObservableObject] public partial class TreeTestModel : TreeModelObject<TreeTestModel> { [ObservableProperty] private string? column1; [ObservableProperty] private string? column2; [ObservableProperty] private string? column3; [ObservableProperty] private bool isChecked = false; }
ImageView
Provides a scalable image control.
<vio:ImageView Source="/wpfui.png" />
ExceptionReport
Show a dialog to handle the
DispatcherUnhandledException
from Application.public partial class App : Application { public App() { InitializeComponent(); DispatcherUnhandledException += (object s, DispatcherUnhandledExceptionEventArgs e) => { e.Handled = true; ExceptionReport.Show(e.Exception); }; } }
BitmapIcon
Supports to show monochrome image that match the theme color.
<ui:BitmapIcon ShowAsMonochrome="False" UriSource="pack://application:,,,/Wpf.Ui.Test;component/Resources/Images/Tiara.png" /> <ui:BitmapIcon ShowAsMonochrome="True" UriSource="pack://application:,,,/Wpf.Ui.Test;component/Resources/Images/Tiara.png" />
📷 Screenshots
Under construction
Thanks
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net6.0-windows7.0 is compatible. net7.0-windows was computed. net7.0-windows7.0 is compatible. net8.0-windows was computed. net8.0-windows7.0 is compatible. |
.NET Framework | net462 is compatible. net463 was computed. net47 is compatible. net471 is compatible. net472 is compatible. net48 is compatible. net481 is compatible. |
-
.NETFramework 4.6.2
- System.Net.Http (>= 4.3.4)
- WPF-UI (>= 3.0.5)
-
.NETFramework 4.7
- System.Net.Http (>= 4.3.4)
- WPF-UI (>= 3.0.5)
-
.NETFramework 4.7.1
- System.Net.Http (>= 4.3.4)
- WPF-UI (>= 3.0.5)
-
.NETFramework 4.7.2
- System.Net.Http (>= 4.3.4)
- WPF-UI (>= 3.0.5)
-
.NETFramework 4.8
- System.Net.Http (>= 4.3.4)
- WPF-UI (>= 3.0.5)
-
.NETFramework 4.8.1
- System.Net.Http (>= 4.3.4)
- WPF-UI (>= 3.0.5)
-
net6.0-windows7.0
- WPF-UI (>= 3.0.5)
-
net7.0-windows7.0
- WPF-UI (>= 3.0.5)
-
net8.0-windows7.0
- WPF-UI (>= 3.0.5)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories (1)
Showing the top 1 popular GitHub repositories that depend on WPF-UI.Violeta:
Repository | Stars |
---|---|
babalae/better-genshin-impact
📦BetterGI · 更好的原神 - 自动拾取 | 自动剧情 | 全自动钓鱼(AI) | 全自动七圣召唤 | 自动伐木 | 自动刷本 | 自动采集 - UI Automation Testing Tools For Genshin Impact
|
Version | Downloads | Last updated |
---|---|---|
3.0.5.23 | 156 | 10/27/2024 |
3.0.5.22 | 86 | 10/27/2024 |
3.0.5.21 | 86 | 10/27/2024 |
3.0.5.20 | 138 | 10/16/2024 |
3.0.5.19 | 83 | 10/13/2024 |
3.0.5.18 | 212 | 10/9/2024 |
3.0.5.17 | 80 | 10/7/2024 |
3.0.5.16 | 178 | 9/30/2024 |
3.0.5.15 | 134 | 9/27/2024 |
3.0.5.14 | 113 | 9/23/2024 |
3.0.5.13 | 108 | 9/19/2024 |
3.0.5.12 | 385 | 9/10/2024 |
3.0.5.11 | 91 | 9/10/2024 |
3.0.5.10 | 136 | 9/10/2024 |
3.0.5.9 | 87 | 9/8/2024 |
3.0.5.8 | 79 | 9/8/2024 |
3.0.5.7 | 129 | 9/3/2024 |
3.0.5.6 | 116 | 8/26/2024 |
3.0.5.5 | 125 | 8/23/2024 |
3.0.5.4 | 129 | 8/22/2024 |
3.0.5.3 | 303 | 8/20/2024 |
3.0.5.2 | 185 | 8/15/2024 |
3.0.5.1 | 112 | 8/15/2024 |
3.0.5 | 113 | 8/13/2024 |