优化
This commit is contained in:
23
NeoUI/NeoUITest/App.xaml
Normal file
23
NeoUI/NeoUITest/App.xaml
Normal file
@@ -0,0 +1,23 @@
|
||||
<Application
|
||||
StartupUri="MainWindow.xaml"
|
||||
x:Class="NeoUITest.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:enu="https://github.com/ShrlAlgo/NeoUI"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<Application.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<!--<enu:ThemesDictionary Mode="Dark" Palette="Blue"/>
|
||||
<enu:ControlsDictionary/>-->
|
||||
<ResourceDictionary Source="pack://application:,,,/NeoUI;component/Themes/ColorPalette/LightBlue.xaml"/>
|
||||
<ResourceDictionary Source="pack://application:,,,/NeoUI;component/Themes/Light.xaml" />
|
||||
<!--<ResourceDictionary Source="pack://application:,,,/NeoUI;component/Themes/ColorPalette/DarkBlue.xaml"/>
|
||||
<ResourceDictionary Source="pack://application:,,,/NeuWPF;component/Themes/Dark.xaml" />-->
|
||||
<ResourceDictionary Source="pack://application:,,,/NeoUI;component/Themes/Styles.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
</ResourceDictionary>
|
||||
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
67
NeoUI/NeoUITest/App.xaml.cs
Normal file
67
NeoUI/NeoUITest/App.xaml.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
|
||||
using NeoUI;
|
||||
|
||||
namespace NeoUITest
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for App.xaml
|
||||
/// </summary>
|
||||
public partial class App : Application
|
||||
{
|
||||
protected override void OnStartup(StartupEventArgs e)
|
||||
{
|
||||
base.OnStartup(e);
|
||||
//Splash.ShowAsync("pack://application:,,,/NeoUITest;component/Resources/Images/ImageTest.png");
|
||||
//MainWindow = new MainWindow();
|
||||
//Splash.CloseOnLoaded(MainWindow);
|
||||
//MainWindow.Show();
|
||||
|
||||
}
|
||||
//protected override void OnStartup(StartupEventArgs e)
|
||||
//{
|
||||
// base.OnStartup(e);
|
||||
// // 在应用启动时,调用方法打印所有已加载的资源字典
|
||||
// Debug.WriteLine("==========================================================");
|
||||
// Debug.WriteLine(" Dumping All Loaded Application Resource Dictionaries... ");
|
||||
// Debug.WriteLine("==========================================================");
|
||||
// // 从最顶层的 Application.Resources 开始遍历
|
||||
// DumpResourceDictionaries(Application.Current.Resources, 0);
|
||||
// Debug.WriteLine("====================== End of Dump =======================");
|
||||
//}
|
||||
/// <summary>
|
||||
/// 递归打印资源字典及其合并的子字典。
|
||||
/// </summary>
|
||||
/// <param name="dictionary">要检查的资源字典。</param>
|
||||
/// <param name="indentationLevel">缩进级别,用于格式化输出。</param>
|
||||
private void DumpResourceDictionaries(ResourceDictionary dictionary, int indentationLevel)
|
||||
{
|
||||
// 创建缩进字符串,使输出更具可读性
|
||||
var indent = new string(' ', indentationLevel * 4);
|
||||
|
||||
// 打印当前字典的来源(Source URI)
|
||||
// App.xaml 中直接定义的根 ResourceDictionary 没有 Source,所以需要判断
|
||||
if (dictionary.Source != null)
|
||||
{
|
||||
Debug.WriteLine($"{indent}-> Source: {dictionary.Source}");
|
||||
}
|
||||
else
|
||||
{
|
||||
// 这是根字典或一个内联定义的字典
|
||||
Debug.WriteLine($"{indent}[Root or Inline Dictionary]");
|
||||
}
|
||||
|
||||
// 递归遍历所有合并的字典
|
||||
foreach (var mergedDict in dictionary.MergedDictionaries)
|
||||
{
|
||||
DumpResourceDictionaries(mergedDict, indentationLevel + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
169
NeoUI/NeoUITest/ColorPaletteControl.xaml
Normal file
169
NeoUI/NeoUITest/ColorPaletteControl.xaml
Normal file
@@ -0,0 +1,169 @@
|
||||
<UserControl
|
||||
Height="Auto"
|
||||
Width="Auto"
|
||||
x:Class="NeoUITest.ColorPaletteControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:local="clr-namespace:NeoUITest"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<UserControl.Resources>
|
||||
<DataTemplate x:Key="ColorItemTemplate">
|
||||
<Border
|
||||
Background="{Binding Value}"
|
||||
BorderBrush="#CCC"
|
||||
BorderThickness="1"
|
||||
CornerRadius="8"
|
||||
Margin="4">
|
||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
|
||||
<Ellipse
|
||||
Fill="{Binding Value}"
|
||||
Height="32"
|
||||
Margin="8,0"
|
||||
Stroke="#888"
|
||||
StrokeThickness="1"
|
||||
Width="32" />
|
||||
<StackPanel>
|
||||
<TextBlock
|
||||
FontWeight="SemiBold"
|
||||
Text="{Binding Key}"
|
||||
TextWrapping="WrapWithOverflow" />
|
||||
<TextBlock FontSize="12" Text="{Binding Value}" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
<DataTemplate x:Key="BrushItemTemplate">
|
||||
<Border
|
||||
Background="{Binding Value}"
|
||||
BorderBrush="#CCC"
|
||||
BorderThickness="1"
|
||||
CornerRadius="8"
|
||||
Margin="4">
|
||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
|
||||
<Ellipse
|
||||
Fill="{Binding Value}"
|
||||
Height="32"
|
||||
Margin="8,0"
|
||||
Stroke="#888"
|
||||
StrokeThickness="1"
|
||||
Width="32" />
|
||||
<StackPanel>
|
||||
<TextBlock FontWeight="SemiBold" Text="{Binding Key}" />
|
||||
<TextBlock FontSize="12" Text="{Binding Value.Color}" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
<!-- 新增颜色分组 -->
|
||||
<CollectionViewSource Source="{Binding ColorResources}" x:Key="ColorGroups">
|
||||
<CollectionViewSource.GroupDescriptions>
|
||||
<PropertyGroupDescription PropertyName="Prefix" />
|
||||
</CollectionViewSource.GroupDescriptions>
|
||||
</CollectionViewSource>
|
||||
<CollectionViewSource Source="{Binding BrushResources}" x:Key="BrushGroups">
|
||||
<CollectionViewSource.GroupDescriptions>
|
||||
<PropertyGroupDescription PropertyName="Prefix" />
|
||||
</CollectionViewSource.GroupDescriptions>
|
||||
</CollectionViewSource>
|
||||
</UserControl.Resources>
|
||||
<StackPanel
|
||||
Background="Transparent"
|
||||
Margin="16"
|
||||
Orientation="Vertical">
|
||||
<StackPanel Visibility="Collapsed">
|
||||
<TextBlock
|
||||
FontSize="14"
|
||||
FontWeight="Bold"
|
||||
Margin="0,0,0,8"
|
||||
Text="颜色资源" />
|
||||
<!-- 用 ListView 支持分组 -->
|
||||
<ListView
|
||||
Height="300"
|
||||
ItemTemplate="{StaticResource ColorItemTemplate}"
|
||||
ItemsSource="{Binding Source={StaticResource ColorGroups}}"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Auto"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Auto"
|
||||
Style="{x:Null}"
|
||||
Visibility="Collapsed">
|
||||
<ListView.ItemContainerStyle>
|
||||
<Style TargetType="ListViewItem">
|
||||
<Setter Property="Padding" Value="0" />
|
||||
<Setter Property="Margin" Value="0" />
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||
<Setter Property="VerticalContentAlignment" Value="Stretch" />
|
||||
<Setter Property="Focusable" Value="False" />
|
||||
<Setter Property="IsHitTestVisible" Value="False" />
|
||||
</Style>
|
||||
</ListView.ItemContainerStyle>
|
||||
<ListView.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<WrapPanel
|
||||
ItemHeight="60"
|
||||
ItemWidth="320"
|
||||
Orientation="Horizontal" />
|
||||
</ItemsPanelTemplate>
|
||||
</ListView.ItemsPanel>
|
||||
<ListView.GroupStyle>
|
||||
<GroupStyle>
|
||||
<GroupStyle.HeaderTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock
|
||||
FontSize="16"
|
||||
FontWeight="Bold"
|
||||
Margin="0,8,0,4"
|
||||
Text="{Binding Name}" />
|
||||
</DataTemplate>
|
||||
</GroupStyle.HeaderTemplate>
|
||||
</GroupStyle>
|
||||
</ListView.GroupStyle>
|
||||
</ListView>
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock
|
||||
FontSize="14"
|
||||
FontWeight="Bold"
|
||||
Margin="16,12,0,8"
|
||||
Text="画刷资源"
|
||||
TextWrapping="WrapWithOverflow" />
|
||||
<ListView
|
||||
Height="300"
|
||||
ItemTemplate="{StaticResource BrushItemTemplate}"
|
||||
ItemsSource="{Binding Source={StaticResource BrushGroups}}"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Visible"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Visible"
|
||||
Style="{x:Null}">
|
||||
<ListView.ItemContainerStyle>
|
||||
<Style TargetType="ListViewItem">
|
||||
<Setter Property="Padding" Value="0" />
|
||||
<Setter Property="Margin" Value="0" />
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||
<Setter Property="VerticalContentAlignment" Value="Stretch" />
|
||||
<Setter Property="Focusable" Value="False" />
|
||||
<Setter Property="IsHitTestVisible" Value="False" />
|
||||
</Style>
|
||||
</ListView.ItemContainerStyle>
|
||||
<ListView.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<WrapPanel
|
||||
ItemHeight="60"
|
||||
ItemWidth="320"
|
||||
Orientation="Horizontal" />
|
||||
</ItemsPanelTemplate>
|
||||
</ListView.ItemsPanel>
|
||||
<ListView.GroupStyle>
|
||||
<GroupStyle>
|
||||
<GroupStyle.HeaderTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock
|
||||
FontSize="16"
|
||||
FontWeight="Bold"
|
||||
Margin="0,8,0,4"
|
||||
Text="{Binding Name}" />
|
||||
</DataTemplate>
|
||||
</GroupStyle.HeaderTemplate>
|
||||
</GroupStyle>
|
||||
</ListView.GroupStyle>
|
||||
</ListView>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
|
||||
87
NeoUI/NeoUITest/ColorPaletteControl.xaml.cs
Normal file
87
NeoUI/NeoUITest/ColorPaletteControl.xaml.cs
Normal file
@@ -0,0 +1,87 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace NeoUITest
|
||||
{
|
||||
public partial class ColorPaletteControl : UserControl
|
||||
{
|
||||
public List<ResourceItem> ColorResources { get; set; }
|
||||
public List<ResourceItem> BrushResources { get; set; }
|
||||
|
||||
public static readonly DependencyProperty SourceUriProperty =
|
||||
DependencyProperty.Register("SourceUri", typeof(string), typeof(ColorPaletteControl), new PropertyMetadata(null, OnSourceUriChanged));
|
||||
|
||||
public string SourceUri
|
||||
{
|
||||
get { return (string)GetValue(SourceUriProperty); }
|
||||
set { SetValue(SourceUriProperty, value); }
|
||||
}
|
||||
|
||||
private static void OnSourceUriChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
ColorPaletteControl control = (ColorPaletteControl)d;
|
||||
string uriString = (string)e.NewValue;
|
||||
|
||||
if (!string.IsNullOrEmpty(uriString))
|
||||
{
|
||||
control.LoadResources(new Uri(uriString, UriKind.RelativeOrAbsolute));
|
||||
}
|
||||
}
|
||||
private void LoadResources(Uri uri)
|
||||
{
|
||||
var resourceDictionary = new ResourceDictionary
|
||||
{
|
||||
Source = uri
|
||||
};
|
||||
|
||||
ColorResources.Clear();
|
||||
BrushResources.Clear();
|
||||
|
||||
foreach (DictionaryEntry entry in resourceDictionary)
|
||||
{
|
||||
string key = entry.Key.ToString();
|
||||
// 用正则分割驼峰或 Pascal 命名,取第一个单词
|
||||
var match = Regex.Match(key, @"^[A-Z][a-z]*");
|
||||
string prefix = match.Success ? match.Value : key;
|
||||
if (entry.Value is Color color)
|
||||
{
|
||||
ColorResources.Add(new ResourceItem { Key = entry.Key.ToString(), Prefix = prefix, Value = new SolidColorBrush(color) });
|
||||
}
|
||||
else if (entry.Value is SolidColorBrush brush)
|
||||
{
|
||||
BrushResources.Add(new ResourceItem { Key = key, Value = brush, Prefix = prefix });
|
||||
}
|
||||
}
|
||||
ColorResources = ColorResources.OrderBy(c => c.Key).ToList();
|
||||
BrushResources = BrushResources.OrderBy(c => c.Key).ToList();
|
||||
DataContext = this;
|
||||
}
|
||||
public ColorPaletteControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
ColorResources = new List<ResourceItem>();
|
||||
BrushResources = new List<ResourceItem>();
|
||||
}
|
||||
|
||||
public IEnumerable<IGrouping<string, ResourceItem>> GroupedBrushResources
|
||||
{
|
||||
get
|
||||
{
|
||||
return BrushResources.GroupBy(b => b.Prefix);
|
||||
}
|
||||
}
|
||||
|
||||
public class ResourceItem
|
||||
{
|
||||
public string Key { get; set; }
|
||||
public SolidColorBrush Value { get; set; }
|
||||
public string Prefix { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
17
NeoUI/NeoUITest/ColorPaletteWindow.xaml
Normal file
17
NeoUI/NeoUITest/ColorPaletteWindow.xaml
Normal file
@@ -0,0 +1,17 @@
|
||||
<n:NeoWindow
|
||||
Height="450"
|
||||
Icon="/Resources/Images/ImageTest.png"
|
||||
Title="ColorPaletteWindow"
|
||||
Width="800"
|
||||
mc:Ignorable="d"
|
||||
x:Class="NeoUITest.ColorPaletteWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:NeoUITest"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:n="https://github.com/ShrlAlgo/NeoUI"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<Grid>
|
||||
<local:ColorPaletteControl SourceUri="pack://application:,,,/NeoUI;component/Themes/Light.xaml" />
|
||||
</Grid>
|
||||
</n:NeoWindow>
|
||||
28
NeoUI/NeoUITest/ColorPaletteWindow.xaml.cs
Normal file
28
NeoUI/NeoUITest/ColorPaletteWindow.xaml.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace NeoUITest
|
||||
{
|
||||
/// <summary>
|
||||
/// ColorPaletteWindow.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class ColorPaletteWindow
|
||||
{
|
||||
public ColorPaletteWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
72
NeoUI/NeoUITest/ControlTestWindow.xaml
Normal file
72
NeoUI/NeoUITest/ControlTestWindow.xaml
Normal file
@@ -0,0 +1,72 @@
|
||||
<neu:NeoWindow
|
||||
Height="600"
|
||||
Icon="/Resources/Images/ImageTest.png"
|
||||
Title="Custom Control Test"
|
||||
Width="800"
|
||||
d:Height="1200"
|
||||
d:SizeToContent="WidthAndHeight"
|
||||
mc:Ignorable="d"
|
||||
x:Class="NeoUITest.ControlTestWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:neu="https://github.com/ShrlAlgo/NeoUI"
|
||||
xmlns:sys="clr-namespace:System;assembly=netfx.force.conflicts"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<!-- 主窗口背景色,这是拟态风格的基础 -->
|
||||
<neu:NeoWindow.Resources>
|
||||
<!--<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/NeuWPFTest;component/ButtonStyles.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>-->
|
||||
</neu:NeoWindow.Resources>
|
||||
<!--<lu:WindowAssist.TitleBar>
|
||||
<Menu>
|
||||
<MenuItem Header="Help">
|
||||
<MenuItem Header="About" />
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
</lu:WindowAssist.TitleBar>-->
|
||||
<Grid>
|
||||
<neu:StackPanel Background="{DynamicResource BackgroundLayoutBrush}" Spacing="10">
|
||||
<neu:PropertyField
|
||||
Grid.Row="0"
|
||||
Margin="6,0"
|
||||
PropertyName="属性"
|
||||
PropertyValue="123" />
|
||||
<neu:PropertyField
|
||||
Grid.Row="1"
|
||||
Margin="6,0"
|
||||
PropertyName="属性x"
|
||||
PropertyValue="154" />
|
||||
<UniformGrid
|
||||
Grid.Row="6"
|
||||
HorizontalAlignment="Center"
|
||||
Margin="20">
|
||||
<Button
|
||||
Content="Button"
|
||||
Style="{StaticResource NeuButtonStyle}"
|
||||
ToolTip="测试"
|
||||
ToolTipService.Placement="Left" />
|
||||
<Button
|
||||
Content="Button"
|
||||
Style="{StaticResource NeuButtonStyle}"
|
||||
ToolTip="测试"
|
||||
ToolTipService.Placement="Top" />
|
||||
<Button
|
||||
Content="Button"
|
||||
Style="{StaticResource NeuButtonStyle}"
|
||||
ToolTip="测试"
|
||||
ToolTipService.Placement="Right" />
|
||||
<Button
|
||||
Content="Button"
|
||||
Style="{StaticResource NeuButtonStyle}"
|
||||
ToolTip="测试"
|
||||
ToolTipService.InitialShowDelay="0"
|
||||
ToolTipService.Placement="Bottom" />
|
||||
<TextBox Style="{StaticResource NeuTextBox}" Text="TextBox" />
|
||||
</UniformGrid>
|
||||
</neu:StackPanel>
|
||||
</Grid>
|
||||
</neu:NeoWindow>
|
||||
16
NeoUI/NeoUITest/ControlTestWindow.xaml.cs
Normal file
16
NeoUI/NeoUITest/ControlTestWindow.xaml.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Windows;
|
||||
|
||||
namespace NeoUITest
|
||||
{
|
||||
/// <summary>
|
||||
/// ControlTestWindow.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class ControlTestWindow
|
||||
{
|
||||
public ControlTestWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
89
NeoUI/NeoUITest/DataModel/DataGridItem.cs
Normal file
89
NeoUI/NeoUITest/DataModel/DataGridItem.cs
Normal file
@@ -0,0 +1,89 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
|
||||
|
||||
namespace NeoUITest.DataModel
|
||||
{
|
||||
public enum Gender
|
||||
{
|
||||
Male,
|
||||
Female,
|
||||
Other
|
||||
}
|
||||
public class DataGridItem
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; } = "";
|
||||
|
||||
public int Age { get; set; }
|
||||
public bool Mark { get; set; }
|
||||
public Gender Gender { get; set; }
|
||||
}
|
||||
|
||||
public class DataGridDemo
|
||||
{
|
||||
public DataGridDemo()
|
||||
{
|
||||
ShowSelectedItemsCommand = new RelayCommand(() =>
|
||||
{
|
||||
if (SelectedDataGridItems != null && SelectedDataGridItems.Count > 0)
|
||||
{
|
||||
string names = string.Join(", ", SelectedDataGridItems.ConvertAll(item => item.Name));
|
||||
System.Windows.MessageBox.Show($"Selected Items: {names}");
|
||||
}
|
||||
else
|
||||
{
|
||||
System.Windows.MessageBox.Show("No items selected.");
|
||||
}
|
||||
});
|
||||
}
|
||||
public ICommand ShowSelectedItemsCommand { get; }
|
||||
|
||||
public List<DataGridItem> SelectedDataGridItems { get; set; }
|
||||
public DataGridItem SelectedDataGridItem { get; set; }
|
||||
|
||||
public ObservableCollection<DataGridItem> DataCollection { get; set; } =
|
||||
[
|
||||
new DataGridItem
|
||||
{
|
||||
Id = 0,
|
||||
Name = "Symin",
|
||||
Age = 24,
|
||||
Mark = true,
|
||||
Gender = Gender.Other,
|
||||
},
|
||||
|
||||
new DataGridItem
|
||||
{
|
||||
Id = 1,
|
||||
Name = "Mike",
|
||||
Age = 23,
|
||||
Mark = false,
|
||||
Gender = Gender.Male,
|
||||
},
|
||||
|
||||
new DataGridItem
|
||||
{
|
||||
Id = 2,
|
||||
Name = "Alice",
|
||||
Age = 25,
|
||||
Mark = true,
|
||||
Gender = Gender.Female,
|
||||
},
|
||||
|
||||
new DataGridItem
|
||||
{
|
||||
Id = 3,
|
||||
Name = "Bob",
|
||||
Age = 18,
|
||||
Mark = true,
|
||||
Gender = Gender.Male,
|
||||
}
|
||||
|
||||
];
|
||||
}
|
||||
}
|
||||
11
NeoUI/NeoUITest/DataModel/TreeItemData.cs
Normal file
11
NeoUI/NeoUITest/DataModel/TreeItemData.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NeoUITest.DataModel
|
||||
{
|
||||
public class TreeItemData
|
||||
{
|
||||
public string Content { get; set; } = "123";
|
||||
|
||||
public List<TreeItemData> Children { get; set; } = [];
|
||||
}
|
||||
}
|
||||
131
NeoUI/NeoUITest/IconsWindow.xaml
Normal file
131
NeoUI/NeoUITest/IconsWindow.xaml
Normal file
@@ -0,0 +1,131 @@
|
||||
<n:NeoWindow
|
||||
Height="450"
|
||||
Title="图标预览"
|
||||
Width="820"
|
||||
d:DataContext="{d:DesignInstance Type=local:IconsWindow}"
|
||||
mc:Ignorable="d"
|
||||
x:Class="NeoUITest.IconsWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:NeoUITest"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:n="https://github.com/ShrlAlgo/NeoUI"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<Grid Margin="10">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- 第一行: 搜索框 -->
|
||||
<Border
|
||||
BorderBrush="LightGray"
|
||||
BorderThickness="0,0,0,1"
|
||||
Grid.Row="0"
|
||||
Padding="10">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TextBox
|
||||
FontSize="14"
|
||||
Grid.Column="1"
|
||||
Padding="5"
|
||||
Text="{Binding SearchText, UpdateSourceTrigger=PropertyChanged}"
|
||||
VerticalContentAlignment="Center">
|
||||
<n:InputAssist.Suffix>
|
||||
<n:IconElement
|
||||
FontSize="18"
|
||||
Foreground="Gray"
|
||||
Margin="0,0,10,0"
|
||||
Symbol="Search"
|
||||
VerticalAlignment="Center" />
|
||||
</n:InputAssist.Suffix>
|
||||
</TextBox>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!-- 第二行: 选中图标信息和复制代码 -->
|
||||
<Border
|
||||
BorderBrush="LightGray"
|
||||
BorderThickness="0,0,0,1"
|
||||
Grid.Row="1"
|
||||
Padding="10">
|
||||
<n:FlexibleRowPanel LayoutMode="Auto">
|
||||
<TextBlock Foreground="{DynamicResource TextPrimaryBrush}"
|
||||
FontWeight="Bold"
|
||||
Text="选中图标:"
|
||||
VerticalAlignment="Center" />
|
||||
<!-- 确保绑定是 OneWay,因为我们只从后台更新UI -->
|
||||
<TextBox
|
||||
FontWeight="Bold"
|
||||
Foreground="{DynamicResource PrimaryNormalBrush}"
|
||||
IsReadOnly="True"
|
||||
Margin="10,0"
|
||||
Padding="5"
|
||||
Text="{Binding SelectedSymbolName, Mode=OneWay, FallbackValue='请选择一个图标...'}"
|
||||
VerticalAlignment="Center"
|
||||
n:FlexibleRowPanel.IsFill="True" />
|
||||
<Button
|
||||
Click="CopyCode_Click"
|
||||
Content="复制代码"
|
||||
Padding="10,5"
|
||||
VerticalAlignment="Center" />
|
||||
<n:ColorPicker
|
||||
Margin="10,0,0,0"
|
||||
VerticalAlignment="Center"
|
||||
x:Name="ColorPicker" />
|
||||
</n:FlexibleRowPanel>
|
||||
</Border>
|
||||
|
||||
<!-- 第三行: 图标浏览器 -->
|
||||
<ListBox
|
||||
Grid.Row="2"
|
||||
ItemsSource="{Binding SymbolCollectionView}"
|
||||
Name="IconItemsControl"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
|
||||
SelectionChanged="IconItemsControl_SelectionChanged">
|
||||
<ListBox.Foreground>
|
||||
<SolidColorBrush Color="{Binding ElementName=ColorPicker, Path=SelectedColor}" />
|
||||
</ListBox.Foreground>
|
||||
<ListBox.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<WrapPanel ItemHeight="80" ItemWidth="80" />
|
||||
</ItemsPanelTemplate>
|
||||
</ListBox.ItemsPanel>
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel HorizontalAlignment="Center">
|
||||
<n:IconElement
|
||||
FontSize="32"
|
||||
Foreground="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBox}, Path=Foreground}"
|
||||
Symbol="{Binding}"
|
||||
ToolTip="{Binding}" />
|
||||
<TextBlock
|
||||
FontSize="12"
|
||||
HorizontalAlignment="Center"
|
||||
Margin="0,5,0,0"
|
||||
Text="{Binding}"
|
||||
TextWrapping="Wrap"
|
||||
ToolTip="{Binding}"
|
||||
VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
<!--<ListBox.ItemContainerStyle>
|
||||
<Style TargetType="ListBoxItem">
|
||||
<Setter Property="HorizontalContentAlignment" Value="Center" />
|
||||
<Setter Property="VerticalContentAlignment" Value="Center" />
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsSelected" Value="True">
|
||||
<Setter Property="Background" Value="#CCE8FF" />
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</ListBox.ItemContainerStyle>-->
|
||||
</ListBox>
|
||||
</Grid>
|
||||
</n:NeoWindow>
|
||||
139
NeoUI/NeoUITest/IconsWindow.xaml.cs
Normal file
139
NeoUI/NeoUITest/IconsWindow.xaml.cs
Normal file
@@ -0,0 +1,139 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
using Microsoft.Win32;
|
||||
|
||||
using NeoUI.Assets;
|
||||
|
||||
namespace NeoUITest;
|
||||
/// <summary>
|
||||
/// IconsWindow.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class IconsWindow : INotifyPropertyChanged
|
||||
{
|
||||
// 1. 一个私有的、包含所有图标的原始数据集合
|
||||
private readonly ObservableCollection<MaterialSymbol> _allSymbols = new ObservableCollection<MaterialSymbol>();
|
||||
|
||||
// 2. 一个公开的 ICollectionView,UI 将绑定到这个视图
|
||||
public ICollectionView SymbolCollectionView { get; }
|
||||
|
||||
private string _selectedSymbolName;
|
||||
public string SelectedSymbolName
|
||||
{
|
||||
get => _selectedSymbolName;
|
||||
set { _selectedSymbolName = value; OnPropertyChanged(nameof(SelectedSymbolName)); }
|
||||
}
|
||||
|
||||
private string _searchText = string.Empty;
|
||||
// 3. 绑定到搜索框的属性
|
||||
public string SearchText
|
||||
{
|
||||
get => _searchText;
|
||||
set
|
||||
{
|
||||
if (_searchText == value) return;
|
||||
_searchText = value;
|
||||
OnPropertyChanged(nameof(SearchText));
|
||||
|
||||
// 关键点: 当搜索文本改变时,刷新视图以重新应用筛选
|
||||
SymbolCollectionView.Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
public IconsWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
// 从枚举加载所有图标到原始集合
|
||||
LoadSymbols();
|
||||
|
||||
// 4. 初始化视图
|
||||
SymbolCollectionView = CollectionViewSource.GetDefaultView(_allSymbols);
|
||||
|
||||
// 5. 为视图指定筛选逻辑
|
||||
SymbolCollectionView.Filter = FilterSymbols;
|
||||
|
||||
this.DataContext = this;
|
||||
}
|
||||
|
||||
private void LoadSymbols()
|
||||
{
|
||||
var symbols = Enum.GetValues(typeof(MaterialSymbol)).Cast<MaterialSymbol>();
|
||||
_allSymbols.Clear();
|
||||
foreach (var symbol in symbols)
|
||||
{
|
||||
_allSymbols.Add(symbol);
|
||||
}
|
||||
}
|
||||
|
||||
// 6. 筛选方法的具体实现
|
||||
private bool FilterSymbols(object item)
|
||||
{
|
||||
// 如果搜索框为空,则不过滤,显示所有项
|
||||
if (string.IsNullOrEmpty(SearchText))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// 如果项是 MaterialSymbol 类型
|
||||
if (item is MaterialSymbol symbol)
|
||||
{
|
||||
// 检查枚举的名称(不区分大小写)是否包含搜索文本
|
||||
return symbol.ToString().IndexOf(SearchText, StringComparison.OrdinalIgnoreCase) >= 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// *** 选择修复: 直接从事件参数 e 中获取选中的项 ***
|
||||
private void IconItemsControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
// 检查 e.AddedItems 是否有内容。AddedItems 包含了新选中的项。
|
||||
if (e.AddedItems.Count > 0 && e.AddedItems[0] is MaterialSymbol selectedSymbol)
|
||||
{
|
||||
string xamlCode = $"<n:IconElement Symbol=\"{selectedSymbol}\" Foreground=\"{ColorPicker.SelectedColor}\"/>";
|
||||
SelectedSymbolName = xamlCode;
|
||||
|
||||
}
|
||||
// 如果列表被清空或选择被取消,e.AddedItems 为空
|
||||
else if (IconItemsControl.SelectedItem == null)
|
||||
{
|
||||
SelectedSymbolName = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
private void CopyCode_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(SelectedSymbolName))
|
||||
{
|
||||
//string xamlCode = $"<local:SymbolIcon Symbol=\"{SelectedSymbolName}\" />";
|
||||
|
||||
Clipboard.SetText(SelectedSymbolName);
|
||||
//MessageBox.Show($"代码已复制到剪贴板!\n\n{SelectedSymbolName}", "成功", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("请先选择一个图标。", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
protected void OnPropertyChanged(string propertyName)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
}
|
||||
1305
NeoUI/NeoUITest/MainWindow.xaml
Normal file
1305
NeoUI/NeoUITest/MainWindow.xaml
Normal file
File diff suppressed because it is too large
Load Diff
467
NeoUI/NeoUITest/MainWindow.xaml.cs
Normal file
467
NeoUI/NeoUITest/MainWindow.xaml.cs
Normal file
@@ -0,0 +1,467 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Input;
|
||||
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
|
||||
using NeoUI.Appearance;
|
||||
using NeoUI.Controls;
|
||||
|
||||
namespace NeoUITest;
|
||||
|
||||
/// <summary>
|
||||
/// MainWindow.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
[ObservableObject]
|
||||
public partial class MainWindow
|
||||
{
|
||||
#region 数据集合
|
||||
public ObservableCollection<TreeNodeItem> HierarchicalData { get; set; }
|
||||
public ObservableCollection<PersonItem> DataItems { get; set; }
|
||||
public ObservableCollection<PersonItem> SelectedDataItems { get; set; }
|
||||
public ObservableCollection<TreeNodeItem> Nodes { get; set; }
|
||||
public ObservableCollection<object> SelectedNodes { get; set; }
|
||||
public ObservableCollection<TreeNodeItem> StaffList { get; set; } = [];
|
||||
public ObservableCollection<Area> SelectedObservableAreas { get; set; } = [];
|
||||
#endregion
|
||||
|
||||
#region 属性
|
||||
[ObservableProperty]
|
||||
private TreeNodeItem selectedItem;
|
||||
|
||||
[ObservableProperty]
|
||||
private Area area;
|
||||
|
||||
[ObservableProperty]
|
||||
public partial List<Area> SelectedListAreas { get; set; } = [];
|
||||
|
||||
[ObservableProperty]
|
||||
private string password;
|
||||
|
||||
[ObservableProperty]
|
||||
private string input;
|
||||
#endregion
|
||||
|
||||
#region 命令
|
||||
public ICommand ShowSelectedItemsCommand { get; set; }
|
||||
public ICommand ToggleDetailsCommand { get; set; }
|
||||
|
||||
[RelayCommand]
|
||||
private void AddArea() { }
|
||||
#endregion
|
||||
|
||||
#region 静态数据
|
||||
public Area[] Areas { get; } = Enumerable.Range(0, 47)
|
||||
.Select(i => new Area(i, GetJapaneseRegionName(i)))
|
||||
.ToArray();
|
||||
|
||||
public IEnumerable<RadioItem> Items { get; set; }
|
||||
|
||||
public struct RadioItem
|
||||
{
|
||||
public string Label;
|
||||
public string Value;
|
||||
}
|
||||
#endregion
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeData();
|
||||
InitializeCommands();
|
||||
DataContext = this;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
#region 初始化方法
|
||||
private void InitializeData()
|
||||
{
|
||||
// 初始化层级数据
|
||||
HierarchicalData = new ObservableCollection<TreeNodeItem>
|
||||
{
|
||||
new("Phase 1: Project Planning", "Alice", "Completed")
|
||||
{
|
||||
Children =
|
||||
{
|
||||
new("Define project scope", "Alice", "Completed"),
|
||||
new("Create project timeline", "Bob", "Completed")
|
||||
}
|
||||
},
|
||||
new("Phase 2: Development", "Charlie", "In Progress")
|
||||
{
|
||||
Children =
|
||||
{
|
||||
new("Backend development", "David", "In Progress")
|
||||
{
|
||||
Children =
|
||||
{
|
||||
new("Setup database", "David", "Completed"),
|
||||
new("Develop APIs", "Eve", "In Progress")
|
||||
}
|
||||
},
|
||||
new("Frontend development", "Frank", "Not Started")
|
||||
}
|
||||
},
|
||||
new("Phase 3: Deployment", "Grace", "Not Started")
|
||||
};
|
||||
|
||||
// 初始化人员数据
|
||||
DataItems = new ObservableCollection<PersonItem>
|
||||
{
|
||||
new("John Doe", 30),
|
||||
new("Jane Smith", 25),
|
||||
new("Sam Williams", 42),
|
||||
new("Peter Jones", 55)
|
||||
};
|
||||
|
||||
// 初始化地区数据
|
||||
Nodes = new ObservableCollection<TreeNodeItem>
|
||||
{
|
||||
new("亚洲") { Children = { new("中国"), new("日本"), new("韩国") } },
|
||||
new("欧洲") { Children = { new("德国"), new("法国") } },
|
||||
new("北美洲")
|
||||
};
|
||||
|
||||
// 初始化员工数据
|
||||
InitializeStaffData();
|
||||
|
||||
// 初始化单选项
|
||||
Items = new[]
|
||||
{
|
||||
new RadioItem { Label = "Apple", Value = "Apple" },
|
||||
new RadioItem { Label = "Pear", Value = "Pear" },
|
||||
new RadioItem { Label = "Orange", Value = "Orange" }
|
||||
};
|
||||
|
||||
// 初始化选中集合
|
||||
SelectedDataItems = new ObservableCollection<PersonItem>();
|
||||
SelectedNodes = new ObservableCollection<object> { Nodes[0].Children[0] }; // 默认选中"中国"
|
||||
}
|
||||
|
||||
private void InitializeStaffData()
|
||||
{
|
||||
var alice = new TreeNodeItem("Alice", 30, "Male", "Manager") { IsExpanded = true };
|
||||
alice.Children.Add(new TreeNodeItem("Alice1", 21, "Male", "Normal")
|
||||
{
|
||||
IsExpanded = true,
|
||||
Children =
|
||||
{
|
||||
new("Alice11", 21, "Male", "Normal"),
|
||||
new("Alice22", 21, "Female", "Normal")
|
||||
}
|
||||
});
|
||||
alice.Children.Add(new TreeNodeItem("Alice2", 22, "Female", "Normal"));
|
||||
alice.Children.Add(new TreeNodeItem("Alice3", 23, "Female", "Normal"));
|
||||
|
||||
var bob = new TreeNodeItem("Bob", 31, "Male", "CEO");
|
||||
bob.Children.Add(new TreeNodeItem("Bob1", 24, "Female", "Normal"));
|
||||
bob.Children.Add(new TreeNodeItem("Bob2", 25, "Female", "Normal"));
|
||||
bob.Children.Add(new TreeNodeItem("Bob3", 26, "Male", "Normal"));
|
||||
|
||||
var cyber = new TreeNodeItem("Cyber", 32, "Female", "Leader");
|
||||
cyber.Children.Add(new TreeNodeItem("Cyber1", 27, "Female", "Normal"));
|
||||
cyber.Children.Add(new TreeNodeItem("Cyber2", 28, "Female", "Normal"));
|
||||
|
||||
StaffList = new ObservableCollection<TreeNodeItem> { alice, bob, cyber };
|
||||
}
|
||||
|
||||
private void InitializeCommands()
|
||||
{
|
||||
ShowSelectedItemsCommand = new RelayCommand(ShowSelectedItems);
|
||||
ToggleDetailsCommand = new RelayCommand<PersonItem>(ToggleDetails);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 命令实现
|
||||
private void ShowSelectedItems()
|
||||
{
|
||||
string message = $"当前选中了 {SelectedDataItems.Count} 项:\n";
|
||||
message += string.Join("\n", SelectedDataItems.Select(item => item.Name));
|
||||
MessageBox.Show(message);
|
||||
}
|
||||
|
||||
private void ToggleDetails(PersonItem product)
|
||||
{
|
||||
if (product != null)
|
||||
{
|
||||
product.IsDetailsVisible = !product.IsDetailsVisible;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 静态方法
|
||||
private static string GetJapaneseRegionName(int index)
|
||||
{
|
||||
string[] names =
|
||||
{
|
||||
"北海道", "青森県", "岩手県", "宮城県", "秋田県", "山形県", "福島県", "茨城県", "栃木県", "群馬県",
|
||||
"埼玉県", "千葉県", "東京都", "神奈川県", "新潟県", "富山県", "石川県", "福井県", "山梨県", "長野県",
|
||||
"岐阜県", "静岡県", "愛知県", "三重県", "滋賀県", "京都府", "大阪府", "兵庫県", "奈良県", "和歌山県",
|
||||
"鳥取県", "島根県", "岡山県", "広島県", "山口県", "徳島県", "香川県", "愛媛県", "高知県", "福岡県",
|
||||
"佐賀県", "長崎県", "熊本県", "大分県", "宮崎県", "鹿児島県", "沖縄県"
|
||||
};
|
||||
return index < names.Length ? names[index] : $"Region{index}";
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 事件处理
|
||||
private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (!_loaded) return;
|
||||
TextMessage.Text = "选项变化" + e.OriginalSource;
|
||||
}
|
||||
|
||||
private bool _loaded = false;
|
||||
private void Window_Loaded(object sender, RoutedEventArgs e) { _loaded = true; }
|
||||
|
||||
private void Switch_OnClick(object sender, RoutedEventArgs e) { ThemeManager.SwitchThemeMode(); }
|
||||
|
||||
private void Test_OnClick(object sender, RoutedEventArgs e) { new ControlTestWindow().Show(); }
|
||||
|
||||
private void Breadcrumb_Navigate(object sender, RoutedPropertyChangedEventArgs<string> e)
|
||||
{ MessageBox.Show(e.NewValue); }
|
||||
|
||||
#region 通知按钮事件
|
||||
private void LeftTopButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
NotificationManager.Show("发生错误", "无法连接到服务器,请检查您的网络连接。",
|
||||
NotificationType.Error, NotificationPlacement.TopLeft, durationSeconds: 5);
|
||||
}
|
||||
|
||||
private void RightTopButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
NotificationManager.Show("操作成功", "您的设置已保存,并已成功应用到系统中。", NotificationType.Success);
|
||||
}
|
||||
|
||||
private void LeftBottomButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
NotificationManager.Show("警告", "您的磁盘空间即将用尽,请及时清理文件。",
|
||||
NotificationType.Warning, NotificationPlacement.BottomLeft);
|
||||
}
|
||||
|
||||
private void RightBottomButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
NotificationManager.Show("系统提示", "这是一条普通的信息提示,用于通知用户。",
|
||||
NotificationType.Info, NotificationPlacement.BottomRight);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Toast 事件
|
||||
private void Info_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Toast.Screen.ShowInfo("这是一条桌面通知,显示在屏幕。");
|
||||
}
|
||||
|
||||
private void Success_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Toast.For(this).ShowSuccess("操作成功!已在当前窗口内显示。");
|
||||
}
|
||||
|
||||
private void Warning_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Toast.Screen.ShowWarning("这是一条桌面通知,请及时续订。");
|
||||
}
|
||||
|
||||
private void Error_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Toast.For(this).ShowError("加载失败,请检查您的网络连接。");
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Modal 事件
|
||||
private void ShowBasicModal_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
bool? result = Modal.Confirm(this, "Basic Dialog", "This is a basic modal dialog.");
|
||||
if (result == true)
|
||||
{
|
||||
MessageBox.Show("User clicked OK!");
|
||||
}
|
||||
}
|
||||
|
||||
private async void ShowAsyncModal_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
bool? result = Modal.Confirm(this, "Async Dialog", "This dialog will close after a 2-second task.",
|
||||
async () =>
|
||||
{
|
||||
await Task.Delay(2000);
|
||||
return true;
|
||||
});
|
||||
|
||||
if (result == true)
|
||||
{
|
||||
MessageBox.Show("Async task completed and user clicked OK!");
|
||||
}
|
||||
}
|
||||
|
||||
private void ShowInfoModal_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Modal.Info(this, "Information", "This is an information dialog.");
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 主题相关事件
|
||||
private void Icon_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
IconsWindow iconsWindow = new IconsWindow
|
||||
{
|
||||
Owner = this,
|
||||
WindowStartupLocation = WindowStartupLocation.CenterOwner
|
||||
};
|
||||
iconsWindow.ShowDialog();
|
||||
}
|
||||
|
||||
private bool _themeAnimating;
|
||||
|
||||
private async void ThemeToggle_OnCheckedChanged(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (_themeAnimating) return;
|
||||
if (sender is not ToggleButton tb) return;
|
||||
|
||||
var targetMode = tb.IsChecked == true ? ThemeMode.Dark : ThemeMode.Light;
|
||||
|
||||
try
|
||||
{
|
||||
_themeAnimating = true;
|
||||
await ThemeManager.ApplyThemeAsync(targetMode, animate: true, animationDurationMs: 2000);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine("[ThemeToggle] " + ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_themeAnimating = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void ColorPalette_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var palette = new ColorPaletteWindow
|
||||
{
|
||||
Owner = this,
|
||||
WindowStartupLocation = WindowStartupLocation.CenterOwner
|
||||
};
|
||||
palette.ShowDialog();
|
||||
}
|
||||
|
||||
private void PrimaryColorSelectComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (sender is ComboBox box)
|
||||
{
|
||||
ThemePalette palette = box.SelectedIndex switch
|
||||
{
|
||||
0 => ThemePalette.Blue,
|
||||
1 => ThemePalette.Green,
|
||||
2 => ThemePalette.Purple,
|
||||
_ => ThemePalette.Blue
|
||||
};
|
||||
ThemeManager.ApplyThemePalette(palette);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
}
|
||||
|
||||
#region 数据模型
|
||||
/// <summary>
|
||||
/// 统一的树形节点数据模型,替代 Item、NodeViewModel、Staff、TaskItem
|
||||
/// </summary>
|
||||
public partial class TreeNodeItem : ObservableObject
|
||||
{
|
||||
[ObservableProperty]
|
||||
private string name = string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
private int age;
|
||||
|
||||
[ObservableProperty]
|
||||
private string sex = string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
private string duty = string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
private string status = string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
private string owner = string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool isDetailsVisible = false;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool isChecked = true;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool isSelected = false;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool isExpanded = false;
|
||||
|
||||
public ObservableCollection<TreeNodeItem> Children { get; set; } = new();
|
||||
|
||||
public TreeNodeItem() { }
|
||||
|
||||
public TreeNodeItem(string name) : this()
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
|
||||
public TreeNodeItem(string name, string owner, string status) : this(name)
|
||||
{
|
||||
Owner = owner;
|
||||
Status = status;
|
||||
}
|
||||
|
||||
public TreeNodeItem(string name, int age, string sex, string duty) : this(name)
|
||||
{
|
||||
Age = age;
|
||||
Sex = sex;
|
||||
Duty = duty;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 简化的人员数据模型
|
||||
/// </summary>
|
||||
public partial class PersonItem : ObservableObject
|
||||
{
|
||||
[ObservableProperty]
|
||||
private string name = string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
private int age;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool isDetailsVisible = false;
|
||||
|
||||
public PersonItem() { }
|
||||
|
||||
public PersonItem(string name, int age)
|
||||
{
|
||||
Name = name;
|
||||
Age = age;
|
||||
}
|
||||
}
|
||||
|
||||
public class Area
|
||||
{
|
||||
public Area(int Id, string Name)
|
||||
{
|
||||
this.Id = Id;
|
||||
this.Name = Name;
|
||||
}
|
||||
|
||||
public int Id { get; }
|
||||
public string Name { get; }
|
||||
|
||||
public override string ToString() => Name;
|
||||
}
|
||||
#endregion
|
||||
34
NeoUI/NeoUITest/NeoUITest.csproj
Normal file
34
NeoUI/NeoUITest/NeoUITest.csproj
Normal file
@@ -0,0 +1,34 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net462</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<LangVersion>preview</LangVersion>
|
||||
<UseWPF>true</UseWPF>
|
||||
<!-- <Version>1.1.1</Version>-->
|
||||
<!--<ApplicationIcon>Resources\Images\image.Png</ApplicationIcon>-->
|
||||
<!-- <PackageVersion>1.1.1</PackageVersion>-->
|
||||
<!-- <UseWindowsForms>true</UseWindowsForms>-->
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="Resources\Images\image.png" />
|
||||
<None Remove="Resources\Images\ImageTest.png" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="Resources\Images\image.png" />
|
||||
<Content Include="Resources\Images\ImageTest.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
|
||||
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.135"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\NeoUI\NeoUI.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
10
NeoUI/NeoUITest/Properties/AssemblyInfo.cs
Normal file
10
NeoUI/NeoUITest/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using System.Windows;
|
||||
|
||||
[assembly: ThemeInfo(
|
||||
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
|
||||
//(used if a resource is not found in the page,
|
||||
// or application resource dictionaries)
|
||||
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
|
||||
//(used if a resource is not found in the page,
|
||||
// app, or any theme specific resource dictionaries)
|
||||
)]
|
||||
BIN
NeoUI/NeoUITest/Resources/Images/ImageTest.png
Normal file
BIN
NeoUI/NeoUITest/Resources/Images/ImageTest.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 32 KiB |
BIN
NeoUI/NeoUITest/Resources/Images/image.png
Normal file
BIN
NeoUI/NeoUITest/Resources/Images/image.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.7 MiB |
BIN
NeoUI/NeoUITest/Resources/Images/image.webp
Normal file
BIN
NeoUI/NeoUITest/Resources/Images/image.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 318 KiB |
75
NeoUI/NeoUITest/ViewModel.cs
Normal file
75
NeoUI/NeoUITest/ViewModel.cs
Normal file
@@ -0,0 +1,75 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NeoUITest
|
||||
{
|
||||
public class MainViewModel : INotifyPropertyChanged
|
||||
{
|
||||
private readonly List<string> _fullDataSource; // 模拟的后端数据源
|
||||
|
||||
private IEnumerable<string> _pagedItems;
|
||||
|
||||
public IEnumerable<string> PagedItems
|
||||
{
|
||||
get => _pagedItems;
|
||||
private set
|
||||
{
|
||||
_pagedItems = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private int _currentPage = 1;
|
||||
|
||||
public int CurrentPage
|
||||
{
|
||||
get => _currentPage;
|
||||
set
|
||||
{
|
||||
_currentPage = value;
|
||||
OnPropertyChanged();
|
||||
UpdatePagedItems();
|
||||
}
|
||||
}
|
||||
|
||||
private int _pageSize = 10;
|
||||
|
||||
public int PageSize
|
||||
{
|
||||
get => _pageSize;
|
||||
set
|
||||
{
|
||||
_pageSize = value;
|
||||
OnPropertyChanged();
|
||||
UpdatePagedItems();
|
||||
}
|
||||
}
|
||||
|
||||
public long TotalItems { get; private set; }
|
||||
|
||||
public MainViewModel()
|
||||
{
|
||||
_fullDataSource = new List<string>(Enumerable.Range(1, 1052).Select(i => $"条目 {i}"));
|
||||
TotalItems = _fullDataSource.Count;
|
||||
OnPropertyChanged(nameof(TotalItems));
|
||||
|
||||
UpdatePagedItems(); // 加载第一页
|
||||
}
|
||||
|
||||
private void UpdatePagedItems()
|
||||
{
|
||||
var skip = (CurrentPage - 1) * PageSize;
|
||||
PagedItems = _fullDataSource.Skip(skip).Take(PageSize).ToList();
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||
{ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user