feat: move to menu.

This commit is contained in:
rabbitism
2023-06-30 20:34:36 +08:00
parent 35582385ef
commit 518a825af3
24 changed files with 308 additions and 173 deletions

View File

@@ -11,12 +11,11 @@ public class MenuDataTemplateSelector: IDataTemplate
public Control? Build(object? param)
{
if (param is NavigationMenuItemViewModel vm)
if (param is MenuItemViewModel vm)
{
if (vm.IsSeparator) return SeparatorTemplate?.Build(vm);
else return MenuTemplate?.Build(vm);
}
return null;
}

View File

@@ -0,0 +1,29 @@
using System;
using Avalonia.Controls;
using Avalonia.Controls.Templates;
using Ursa.Demo.Pages;
namespace Ursa.Demo.Converters;
public class ViewLocator: IDataTemplate
{
public Control? Build(object? param)
{
if (param is null) return null;
var name = param.GetType().Name!.Replace("ViewModel", "");
var type = Type.GetType("Ursa.Demo.Pages."+name);
if (type != null)
{
return (Control)Activator.CreateInstance(type)!;
}
else
{
return new TextBlock { Text = "Not Found: " + name };
}
}
public bool Match(object? data)
{
return true;
}
}

View File

@@ -0,0 +1,15 @@
namespace Ursa.Demo;
public static class MenuKeys
{
public const string MenuKeyBadge = "Badge";
public const string MenuKeyBanner = "Banner";
public const string MenuKeyButtonGroup = "ButtonGroup";
public const string MenuKeyDivider = "Divider";
public const string MenuKeyIpBox = "IPv4Box";
public const string MenuKeyLoading = "Loading";
public const string MenuKeyNavigation = "Navigation";
public const string MenuKeyPagination = "Pagination";
public const string MenuKeyTagInput = "TagInput";
public const string MenuKeyTimeline = "Timeline";
}

View File

@@ -9,7 +9,7 @@
d:DesignHeight="450"
d:DesignWidth="800"
x:CompileBindings="True"
x:DataType="vm:ButtonGroupViewModel"
x:DataType="vm:ButtonGroupDemoViewModel"
mc:Ignorable="d">
<StackPanel Margin="20" Spacing="20">

View File

@@ -10,6 +10,6 @@ public partial class ButtonGroupDemo : UserControl
public ButtonGroupDemo()
{
InitializeComponent();
this.DataContext = new ButtonGroupViewModel();
this.DataContext = new ButtonGroupDemoViewModel();
}
}

View File

@@ -42,7 +42,7 @@
<u:NavigationMenu.ItemTemplate>
<converters:MenuDataTemplateSelector>
<converters:MenuDataTemplateSelector.MenuTemplate>
<DataTemplate DataType="vm:NavigationMenuItemViewModel">
<DataTemplate DataType="vm:MenuItemViewModel">
<u:NavigationMenuItem Header="{Binding MenuHeader}" ItemsSource="{Binding Children}">
<u:NavigationMenuItem.Icon>
<PathIcon
@@ -54,7 +54,7 @@
</DataTemplate>
</converters:MenuDataTemplateSelector.MenuTemplate>
<converters:MenuDataTemplateSelector.SeparatorTemplate>
<DataTemplate DataType="vm:NavigationMenuItemViewModel">
<DataTemplate DataType="vm:MenuItemViewModel">
<u:NavigationMenuSeparator Header="{Binding MenuHeader}" />
</DataTemplate>
</converters:MenuDataTemplateSelector.SeparatorTemplate>

View File

@@ -9,7 +9,6 @@
</PropertyGroup>
<ItemGroup>
<Folder Include="Models\" />
<AvaloniaResource Include="Assets\**" />
<None Remove=".gitignore" />
</ItemGroup>

View File

@@ -0,0 +1,6 @@
namespace Ursa.Demo.ViewModels;
public class BadgeDemoViewModel: ViewModelBase
{
}

View File

@@ -0,0 +1,6 @@
namespace Ursa.Demo.ViewModels;
public class BannerDemoViewModel: ViewModelBase
{
}

View File

@@ -2,9 +2,9 @@ using System.Collections.ObjectModel;
namespace Ursa.Demo.ViewModels;
public class ButtonGroupViewModel: ViewModelBase
public class ButtonGroupDemoViewModel: ViewModelBase
{
public ObservableCollection<string> Items { get; set; } = new ObservableCollection<string>()
public ObservableCollection<string> Items { get; set; } = new ()
{
"Ding", "Otter", "Husky", "Mr. 17", "Cass"
};

View File

@@ -0,0 +1,6 @@
namespace Ursa.Demo.ViewModels;
public class DividerDemoViewModel: ViewModelBase
{
}

View File

@@ -0,0 +1,6 @@
namespace Ursa.Demo.ViewModels;
public class IPv4BoxDemoViewModel: ViewModelBase
{
}

View File

@@ -0,0 +1,6 @@
namespace Ursa.Demo.ViewModels;
public class LoadingDemoViewModel: ViewModelBase
{
}

View File

@@ -1,6 +1,40 @@
namespace Ursa.Demo.ViewModels;

using CommunityToolkit.Mvvm.Messaging;
namespace Ursa.Demo.ViewModels;
public class MainWindowViewModel : ViewModelBase
{
public string Greeting => "Welcome to Avalonia!";
public MenuViewModel Menus { get; set; } = new MenuViewModel();
private object? _content;
public object? Content
{
get => _content;
set => SetProperty(ref _content, value);
}
public MainWindowViewModel()
{
WeakReferenceMessenger.Default.Register<MainWindowViewModel, string>(this, OnNavigation);
}
private void OnNavigation(MainWindowViewModel vm, string s)
{
Content = s switch
{
MenuKeys.MenuKeyBadge => new BadgeDemoViewModel(),
MenuKeys.MenuKeyBanner => new BannerDemoViewModel(),
MenuKeys.MenuKeyButtonGroup => new ButtonGroupDemoViewModel(),
MenuKeys.MenuKeyDivider => new DividerDemoViewModel(),
MenuKeys.MenuKeyIpBox => new IPv4BoxDemoViewModel(),
MenuKeys.MenuKeyLoading => new LoadingDemoViewModel(),
MenuKeys.MenuKeyNavigation => new NavigationMenuDemoViewModel(),
MenuKeys.MenuKeyPagination => new PaginationDemoViewModel(),
MenuKeys.MenuKeyTagInput => new TagInputDemoViewModel(),
MenuKeys.MenuKeyTimeline => new TimelineDemoViewModel(),
};
}
}

View File

@@ -0,0 +1,29 @@
using System.Collections.ObjectModel;
using System.Windows.Input;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
namespace Ursa.Demo.ViewModels;
public class MenuItemViewModel: ViewModelBase
{
public string MenuHeader { get; set; }
public string MenuIconName { get; set; }
public string Key { get; set; }
public bool IsSeparator { get; set; }
public ObservableCollection<MenuItemViewModel> Children { get; set; } = new();
public ICommand ActivateCommand { get; set; }
public MenuItemViewModel()
{
ActivateCommand = new RelayCommand(OnActivate);
}
private void OnActivate()
{
if (IsSeparator) return;
WeakReferenceMessenger.Default.Send<string>(Key);
}
}

View File

@@ -0,0 +1,26 @@
using System.Collections.ObjectModel;
namespace Ursa.Demo.ViewModels;
public class MenuViewModel: ViewModelBase
{
public ObservableCollection<MenuItemViewModel> MenuItems { get; set; }
public MenuViewModel()
{
MenuItems = new ObservableCollection<MenuItemViewModel>()
{
new() { MenuHeader = "Controls", IsSeparator = true },
new() { MenuHeader = "Badge", Key = MenuKeys.MenuKeyBadge },
new() { MenuHeader = "Banner", Key = MenuKeys.MenuKeyBanner },
new() { MenuHeader = "ButtonGroup", Key = MenuKeys.MenuKeyButtonGroup },
new() { MenuHeader = "Divider", Key = MenuKeys.MenuKeyDivider },
new() { MenuHeader = "IPv4Box", Key = MenuKeys.MenuKeyIpBox },
new() { MenuHeader = "Loading", Key = MenuKeys.MenuKeyLoading },
new() { MenuHeader = "Navigation", Key = MenuKeys.MenuKeyNavigation },
new() { MenuHeader = "Pagination", Key = MenuKeys.MenuKeyPagination },
new() { MenuHeader = "TagInput", Key = MenuKeys.MenuKeyTagInput },
new() { MenuHeader = "Timeline", Key = MenuKeys.MenuKeyTimeline },
};
}
}

View File

@@ -5,18 +5,18 @@ namespace Ursa.Demo.ViewModels;
public class NavigationMenuDemoViewModel: ObservableObject
{
public ObservableCollection<NavigationMenuItemViewModel> MenuItems { get; set; } = new()
public ObservableCollection<MenuItemViewModel> MenuItems { get; set; } = new()
{
new NavigationMenuItemViewModel()
new MenuItemViewModel()
{
MenuHeader = "任务管理",
MenuIconName = "User",
Children = new ObservableCollection<NavigationMenuItemViewModel>()
Children = new ObservableCollection<MenuItemViewModel>()
{
new (){
MenuHeader = "公告管理" ,
MenuIconName = "Star",
Children = new ObservableCollection<NavigationMenuItemViewModel>()
Children = new ObservableCollection<MenuItemViewModel>()
{
new () {MenuHeader = "公告设置"},
new () {MenuHeader = "公告处理"}
@@ -24,16 +24,16 @@ public class NavigationMenuDemoViewModel: ObservableObject
new (){MenuHeader = "任务查询"}
}
},
new NavigationMenuItemViewModel()
new MenuItemViewModel()
{
MenuHeader = "附加功能",
IsSeparator = true,
},
new NavigationMenuItemViewModel()
new MenuItemViewModel()
{
MenuHeader = "任务平台",
MenuIconName = "Gear",
Children = new ObservableCollection<NavigationMenuItemViewModel>()
Children = new ObservableCollection<MenuItemViewModel>()
{
new (){MenuHeader = "任务管理"},
new (){MenuHeader = "用户任务查询"}
@@ -42,11 +42,3 @@ public class NavigationMenuDemoViewModel: ObservableObject
};
}
public class NavigationMenuItemViewModel: ObservableObject
{
public string MenuHeader { get; set; }
public string MenuIconName { get; set; }
public bool IsSeparator { get; set; }
public ObservableCollection<NavigationMenuItemViewModel> Children { get; set; } = new();
}

View File

@@ -5,7 +5,7 @@ using CommunityToolkit.Mvvm.ComponentModel;
namespace Ursa.Demo.ViewModels;
public class PaginationDemoViewModel: ObservableObject
public class PaginationDemoViewModel: ViewModelBase
{
public AvaloniaList<int> PageSizes { get; set; } = new() { 10, 20, 50, 100 };
}

View File

@@ -0,0 +1,6 @@
namespace Ursa.Demo.ViewModels;
public class TagInputDemoViewModel: ViewModelBase
{
}

View File

@@ -4,7 +4,7 @@ using Ursa.Controls;
namespace Ursa.Demo.ViewModels;
public class TimelineDemoViewModel: ObservableObject
public class TimelineDemoViewModel: ViewModelBase
{
public TimelineItemViewModel[] Items { get; } =
{
@@ -46,62 +46,6 @@ public class TimelineDemoViewModel: ObservableObject
Description = "Item 5",
Content = "Content 5"
},
new()
{
Time = DateTime.Now,
TimeFormat = "HH:mm:ss",
Description = "Item 6",
Content = "Content 6"
},
new()
{
Time = DateTime.Now,
TimeFormat = "HH:mm:ss",
Description = "Item 7",
Content = "Content 71231"
},
new()
{
Time = DateTime.Now,
TimeFormat = "HH:mm:ss",
Description = "Item 8",
Content = "Content 8123123"
},
new()
{
Time = DateTime.Now,
TimeFormat = "HH:mm:ss",
Description = "Item 9",
Content = "Content 9123123"
},
new()
{
Time = DateTime.Now,
TimeFormat = "HH:mm:ss",
Description = "Item 10",
Content = "Content 1231231231231231231230"
},
new()
{
Time = DateTime.Now,
TimeFormat = "HH:mm:ss",
Description = "Item 11",
Content = "Content 11231231"
},
new()
{
Time = DateTime.Now,
TimeFormat = "HH:mm:ss",
Description = "Item 12",
Content = "Content 12123123123123"
},
new()
{
Time = DateTime.Now,
TimeFormat = "HH:mm:ss",
Description = "Item 13",
Content = "Last"
}
};
}

View File

@@ -2,13 +2,17 @@
x:Class="Ursa.Demo.Views.MainWindow"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:converters="clr-namespace:Ursa.Demo.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:pages="clr-namespace:Ursa.Demo.Pages"
xmlns:u="https://irihi.tech/ursa"
xmlns:vm="using:Ursa.Demo.ViewModels"
Title="Ursa.Demo"
d:DesignHeight="450"
d:DesignWidth="800"
x:CompileBindings="True"
x:DataType="vm:MainWindowViewModel"
Icon="/Assets/Ursa.ico"
mc:Ignorable="d">
@@ -16,44 +20,67 @@
<vm:MainWindowViewModel />
</Design.DataContext>
<Grid RowDefinitions="Auto, *">
<Grid ColumnDefinitions="Auto, *" RowDefinitions="Auto, *">
<Border
Grid.RowSpan="2"
Padding="8,4"
VerticalAlignment="Stretch"
Theme="{DynamicResource CardBorder}">
<u:NavigationMenu ItemsSource="{Binding Menus.MenuItems}" ShowCollapseButton="True">
<u:NavigationMenu.Header>
<TextBlock
Classes="H4"
Text="Ursa"
Theme="{DynamicResource TitleTextBlock}" />
</u:NavigationMenu.Header>
<u:NavigationMenu.Icon>
<Image
Width="48"
Height="48"
RenderOptions.BitmapInterpolationMode="HighQuality"
Source="../Assets/Ursa.ico" />
</u:NavigationMenu.Icon>
<u:NavigationMenu.ItemTemplate>
<converters:MenuDataTemplateSelector>
<converters:MenuDataTemplateSelector.MenuTemplate>
<DataTemplate DataType="vm:MenuItemViewModel">
<u:NavigationMenuItem
Command="{Binding ActivateCommand}"
Header="{Binding MenuHeader}"
ItemsSource="{Binding Children}">
<u:NavigationMenuItem.Icon>
<Ellipse
Width="10"
Height="10"
Fill="LightGray" />
</u:NavigationMenuItem.Icon>
</u:NavigationMenuItem>
</DataTemplate>
</converters:MenuDataTemplateSelector.MenuTemplate>
<converters:MenuDataTemplateSelector.SeparatorTemplate>
<DataTemplate DataType="vm:MenuItemViewModel">
<u:NavigationMenuSeparator Header="{Binding MenuHeader}" />
</DataTemplate>
</converters:MenuDataTemplateSelector.SeparatorTemplate>
</converters:MenuDataTemplateSelector>
</u:NavigationMenu.ItemTemplate>
</u:NavigationMenu>
</Border>
<ToggleButton
Grid.Row="0"
Grid.Column="1"
HorizontalAlignment="Right"
Content="Update Theme"
IsCheckedChanged="ToggleButton_OnIsCheckedChanged" />
<TabControl Grid.Row="1" TabStripPlacement="Left">
<TabItem Header="Badge">
<pages:BadgeDemo />
</TabItem>
<TabItem Header="Banner">
<pages:BannerDemo />
</TabItem>
<TabItem Header="ButtonGroup">
<pages:ButtonGroupDemo />
</TabItem>
<TabItem Header="Divider">
<pages:DividerDemo />
</TabItem>
<TabItem Header="IPv4Box">
<pages:IPv4BoxDemo />
</TabItem>
<TabItem Header="Loading">
<pages:LoadingDemo />
</TabItem>
<TabItem Header="Navigation">
<pages:NavigationMenuDemo />
</TabItem>
<TabItem Header="Pagination">
<pages:PaginationDemo />
</TabItem>
<TabItem Header="TagInput">
<pages:TagInputDemo />
</TabItem>
<TabItem Header="Timeline">
<pages:TimelineDemo />
</TabItem>
</TabControl>
<ContentControl
Grid.Row="1"
Grid.Column="1"
Content="{Binding Content}">
<ContentControl.ContentTemplate>
<converters:ViewLocator />
</ContentControl.ContentTemplate>
</ContentControl>
</Grid>
</Window>