XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFENewsApplication

【WinUI】新闻软件

公开
关注 0 Fork 0 Star 0
返回提交历史

XFEstudio/XFENewsApplication

更新解决方案和核心功能,优化 UI 结构

- 添加对 `.editorconfig` 的支持,更新解决方案文件。 - 引入 `XFENewsApplication.Core` 和 `XFENewsApplication.Test` 项目。 - 在 `App.xaml` 中移除注释并添加 `Thickness.xaml` 资源引用。 - 重构 `App.xaml.cs`,优化命名空间引用和构造函数。 - 更新 `MainWindow.xaml.cs` 中的主题变化处理逻辑。 - 在项目文件中添加 `XFEExtension.NetCore.WinUIHelper` 引用。 - 新增 `FileHelper.cs`,实现文件路径管理和快捷方式创建。 - 在 `Program.cs` 中实现爬虫测试方法,解析新闻数据。 - 设置测试项目的基本属性和依赖项。 - 在 `SystemProfile.cs` 中实现主题管理功能。 - 新增 `Thickness.xaml`,定义 UI 布局的厚度资源。 - 创建主界面 `AppShellPage` 和新闻展示页面 `NewsViewPage`。 - 实现设置页面,允许用户配置应用选项。 - 使用 `CommunityToolkit.Mvvm` 库简化视图模型的属性管理和命令处理。

0b340e5
XFE工作室室长 <mail@xfegzs.com>
提交于

代码差异

24 个文件 +640 -44
Added .editorconfig +4 -0
@@ -0,0 +1,4 @@
1 [*.cs]
2
3 # MVVMTK0045: Using [ObservableProperty] on fields is not AOT compatible for WinRT
4 dotnet_diagnostic.MVVMTK0045.severity = none
Modified LICENSE.txt +1 -1
@@ -1,6 +1,6 @@
1 1 MIT License
2 2
3 Copyright (c) [year] [fullname]
3 Copyright (c) [2025] [XFEstudio]
4 4
5 5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 6 of this software and associated documentation files (the "Software"), to deal
Added XFENewsApplication.Core/Utilities/Helpers/FileHelper.cs +36 -0
@@ -0,0 +1,36 @@
1 using IWshRuntimeLibrary;
2
3 namespace XFENewsApplication.Core.Utilities.Helpers;
4
5 public static class FileHelper
6 {
7 public static string[] RootPath { get; set; } = [@"C:\", @"D:\", @"E:\", @"F:\", @"G:\", @"H:\", @"I:\", @"J:\", @"K:\", @"L:\", @"M:\", @"N:\", @"O:\", @"P:\", @"Q:\", @"R:\", @"S:\", @"T:\", @"U:\", @"V:\", @"W:\", @"X:\", @"Y:\", @"Z:\",];
8 public static long GetDirectorySize(DirectoryInfo directoryInfo)
9 {
10 long size = 0;
11 FileInfo[] files = directoryInfo.GetFiles();
12 foreach (FileInfo file in files)
13 {
14 size += file.Length;
15 }
16 DirectoryInfo[] directories = directoryInfo.GetDirectories();
17 foreach (DirectoryInfo directory in directories)
18 {
19 size += GetDirectorySize(directory);
20 }
21 return size;
22 }
23
24 public static bool IsRootPath(string path) => RootPath.Any(rootPath => rootPath == path);
25
26 public static void CreateShortCut(string targetPath, string originalPath, string argument, string description = "快捷方式")
27 {
28 var wshShortcut = (IWshShortcut)new WshShell().CreateShortcut(targetPath);
29 wshShortcut.TargetPath = originalPath;
30 wshShortcut.WorkingDirectory = Path.GetDirectoryName(originalPath);
31 wshShortcut.WindowStyle = 1;
32 wshShortcut.Description = description;
33 wshShortcut.Arguments = argument;
34 wshShortcut.Save();
35 }
36 }
Added XFENewsApplication.Core/XFENewsApplication.Core.csproj +21 -0
@@ -0,0 +1,21 @@
1 <Project Sdk="Microsoft.NET.Sdk">
2
3 <PropertyGroup>
4 <TargetFramework>net8.0</TargetFramework>
5 <ImplicitUsings>enable</ImplicitUsings>
6 <Nullable>enable</Nullable>
7 </PropertyGroup>
8
9 <ItemGroup>
10 <COMReference Include="IWshRuntimeLibrary">
11 <WrapperTool>tlbimp</WrapperTool>
12 <VersionMinor>0</VersionMinor>
13 <VersionMajor>1</VersionMajor>
14 <Guid>f935dc20-1cf0-11d0-adb9-00c04fd58a0b</Guid>
15 <Lcid>0</Lcid>
16 <Isolated>false</Isolated>
17 <EmbedInteropTypes>true</EmbedInteropTypes>
18 </COMReference>
19 </ItemGroup>
20
21 </Project>
Added XFENewsApplication.Test/Program.cs +22 -0
@@ -0,0 +1,22 @@
1 using System.Text.Json;
2 using XFEExtension.NetCore.XFETransform.JsonConverter;
3
4 class Program
5 {
6 [SMTest]
7 public static async Task ClimbTest()
8 {
9 using var client = new HttpClient();
10 client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36 Edg/129.0.0.0");
11 QueryableJsonNode authJsonNode = await client.GetStringAsync("https://www.msn.cn/resolver/api/resolve/v3/config/?expType=AppConfig&expInstance=default&apptype=homePage&v=20250401.183&targetScope={%22audienceMode%22:%22adult%22,%22browser%22:{%22browserType%22:%22edgeChromium%22,%22version%22:%22135%22,%22ismobile%22:%22false%22},%22deviceFormFactor%22:%22desktop%22,%22domain%22:%22www.msn.cn%22,%22locale%22:{%22content%22:{%22language%22:%22zh%22,%22market%22:%22cn%22},%22display%22:{%22language%22:%22zh%22,%22market%22:%22cn%22}},%22os%22:%22windows%22,%22platform%22:%22web%22,%22pageType%22:%22hp%22,%22pageExperiments%22:[]}");
12 var result = await client.GetStringAsync($"https://assets.msn.com/service/news/feed/pages/weblayout?User=&activityId=&adoffsets=c1:-1,c2:-1&apikey={authJsonNode["configs"]["StripeWC/default"]["properties"]["apikey"]}&audienceMode=adult&cm=zh-cn&colstatus=c1:0,c2:0&column=c2&colwidth=300&contentType=article,video,slideshow,webcontent&it=edgeid&l3v=2&layout=c2&memory=8&newsSkip=0&newsTop=48&ocid=hponeservicefeed&pgc=11&private=1&scn=APP_ANON&timeOut=1000&vpSize=721x674&wposchema=byregion");
13 using var document = JsonDocument.Parse(result);
14 int i = 0;
15 foreach (var subNode in document.RootElement.GetProperty("sections").EnumerateArray().ElementAt(0).GetProperty("cards").EnumerateArray())
16 {
17 if (i++ == 0)
18 continue;
19 Console.WriteLine($"{subNode.GetProperty("title").GetString()}\n{subNode.GetProperty("abstract").GetString()}\n{subNode.GetProperty("url").GetString()}\n");
20 }
21 }
22 }
Added XFENewsApplication.Test/XFENewsApplication.Test.csproj +15 -0
@@ -0,0 +1,15 @@
1 <Project Sdk="Microsoft.NET.Sdk">
2
3 <PropertyGroup>
4 <OutputType>Exe</OutputType>
5 <TargetFramework>net8.0</TargetFramework>
6 <ImplicitUsings>enable</ImplicitUsings>
7 <Nullable>enable</Nullable>
8 </PropertyGroup>
9
10 <ItemGroup>
11 <PackageReference Include="XFEExtension.NetCore" Version="3.3.1" />
12 <PackageReference Include="XFEExtension.NetCore.XUnit" Version="2.0.4" />
13 </ItemGroup>
14
15 </Project>
Modified XFENewsApplication.sln +33 -0
@@ -4,6 +4,15 @@ VisualStudioVersion = 17.14.35821.62
4 4 MinimumVisualStudioVersion = 10.0.40219.1
5 5 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XFENewsApplication", "XFENewsApplication\XFENewsApplication.csproj", "{A8E05536-352A-43C6-853E-836AC45DDC16}"
6 6 EndProject
7 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
8 ProjectSection(SolutionItems) = preProject
9 .editorconfig = .editorconfig
10 EndProjectSection
11 EndProject
12 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XFENewsApplication.Core", "XFENewsApplication.Core\XFENewsApplication.Core.csproj", "{40D6FFA5-FAD0-4E3A-9385-610C21610289}"
13 EndProject
14 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XFENewsApplication.Test", "XFENewsApplication.Test\XFENewsApplication.Test.csproj", "{85F9634D-738C-4E73-BBAA-77A97F014F26}"
15 EndProject
7 16 Global
8 17 GlobalSection(SolutionConfigurationPlatforms) = preSolution
9 18 Debug|ARM64 = Debug|ARM64
@@ -32,6 +41,30 @@ Global
32 41 {A8E05536-352A-43C6-853E-836AC45DDC16}.Release|x86.ActiveCfg = Release|x86
33 42 {A8E05536-352A-43C6-853E-836AC45DDC16}.Release|x86.Build.0 = Release|x86
34 43 {A8E05536-352A-43C6-853E-836AC45DDC16}.Release|x86.Deploy.0 = Release|x86
44 {40D6FFA5-FAD0-4E3A-9385-610C21610289}.Debug|ARM64.ActiveCfg = Debug|Any CPU
45 {40D6FFA5-FAD0-4E3A-9385-610C21610289}.Debug|ARM64.Build.0 = Debug|Any CPU
46 {40D6FFA5-FAD0-4E3A-9385-610C21610289}.Debug|x64.ActiveCfg = Debug|Any CPU
47 {40D6FFA5-FAD0-4E3A-9385-610C21610289}.Debug|x64.Build.0 = Debug|Any CPU
48 {40D6FFA5-FAD0-4E3A-9385-610C21610289}.Debug|x86.ActiveCfg = Debug|Any CPU
49 {40D6FFA5-FAD0-4E3A-9385-610C21610289}.Debug|x86.Build.0 = Debug|Any CPU
50 {40D6FFA5-FAD0-4E3A-9385-610C21610289}.Release|ARM64.ActiveCfg = Release|Any CPU
51 {40D6FFA5-FAD0-4E3A-9385-610C21610289}.Release|ARM64.Build.0 = Release|Any CPU
52 {40D6FFA5-FAD0-4E3A-9385-610C21610289}.Release|x64.ActiveCfg = Release|Any CPU
53 {40D6FFA5-FAD0-4E3A-9385-610C21610289}.Release|x64.Build.0 = Release|Any CPU
54 {40D6FFA5-FAD0-4E3A-9385-610C21610289}.Release|x86.ActiveCfg = Release|Any CPU
55 {40D6FFA5-FAD0-4E3A-9385-610C21610289}.Release|x86.Build.0 = Release|Any CPU
56 {85F9634D-738C-4E73-BBAA-77A97F014F26}.Debug|ARM64.ActiveCfg = Debug|Any CPU
57 {85F9634D-738C-4E73-BBAA-77A97F014F26}.Debug|ARM64.Build.0 = Debug|Any CPU
58 {85F9634D-738C-4E73-BBAA-77A97F014F26}.Debug|x64.ActiveCfg = Debug|Any CPU
59 {85F9634D-738C-4E73-BBAA-77A97F014F26}.Debug|x64.Build.0 = Debug|Any CPU
60 {85F9634D-738C-4E73-BBAA-77A97F014F26}.Debug|x86.ActiveCfg = Debug|Any CPU
61 {85F9634D-738C-4E73-BBAA-77A97F014F26}.Debug|x86.Build.0 = Debug|Any CPU
62 {85F9634D-738C-4E73-BBAA-77A97F014F26}.Release|ARM64.ActiveCfg = Release|Any CPU
63 {85F9634D-738C-4E73-BBAA-77A97F014F26}.Release|ARM64.Build.0 = Release|Any CPU
64 {85F9634D-738C-4E73-BBAA-77A97F014F26}.Release|x64.ActiveCfg = Release|Any CPU
65 {85F9634D-738C-4E73-BBAA-77A97F014F26}.Release|x64.Build.0 = Release|Any CPU
66 {85F9634D-738C-4E73-BBAA-77A97F014F26}.Release|x86.ActiveCfg = Release|Any CPU
67 {85F9634D-738C-4E73-BBAA-77A97F014F26}.Release|x86.Build.0 = Release|Any CPU
35 68 EndGlobalSection
36 69 GlobalSection(SolutionProperties) = preSolution
37 70 HideSolutionNode = FALSE
Modified XFENewsApplication/App.xaml +1 -2
@@ -8,9 +8,8 @@
8 8 <ResourceDictionary>
9 9 <ResourceDictionary.MergedDictionaries>
10 10 <XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
11 <!-- Other merged dictionaries here -->
11 <ResourceDictionary Source="/Styles/Thickness.xaml" />
12 12 </ResourceDictionary.MergedDictionaries>
13 <!-- Other app resources here -->
14 13 </ResourceDictionary>
15 14 </Application.Resources>
16 15 </Application>
Modified XFENewsApplication/App.xaml.cs +34 -38
@@ -1,50 +1,46 @@
1 using System;
2 using System.Collections.Generic;
3 using System.IO;
4 using System.Linq;
5 using System.Runtime.InteropServices.WindowsRuntime;
6 using Microsoft.UI.Xaml;
7 using Microsoft.UI.Xaml.Controls;
8 using Microsoft.UI.Xaml.Controls.Primitives;
9 using Microsoft.UI.Xaml.Data;
10 using Microsoft.UI.Xaml.Input;
11 using Microsoft.UI.Xaml.Media;
12 using Microsoft.UI.Xaml.Navigation;
13 using Microsoft.UI.Xaml.Shapes;
14 using Windows.ApplicationModel;
15 using Windows.ApplicationModel.Activation;
16 using Windows.Foundation;
17 using Windows.Foundation.Collections;
1 using XFEExtension.NetCore.WinUIHelper.Interface.Services;
2 using XFEExtension.NetCore.WinUIHelper.Utilities;
3 using XFEExtension.NetCore.WinUIHelper.Utilities.Helper;
4 using XFENewsApplication.Profiles.CrossVersionProfiles;
18 5
19 // To learn more about WinUI, the WinUI project structure,
20 // and more about our project templates, see: http://aka.ms/winui-project-info.
6 namespace XFENewsApplication;
21 7
22 namespace XFENewsApplication
8 /// <summary>
9 /// Provides application-specific behavior to supplement the default Application class.
10 /// </summary>
11 public partial class App : Application
23 12 {
13 public static MainWindow MainWindow { get; set; } = new();
24 14 /// <summary>
25 /// Provides application-specific behavior to supplement the default Application class.
15 /// Initializes the singleton application object. This is the first line of authored code
16 /// executed, and as such is the logical equivalent of main() or WinMain().
26 17 /// </summary>
27 public partial class App : Application
18 public App()
28 19 {
29 /// <summary>
30 /// Initializes the singleton application object. This is the first line of authored code
31 /// executed, and as such is the logical equivalent of main() or WinMain().
32 /// </summary>
33 public App()
34 {
35 this.InitializeComponent();
36 }
20 this.InitializeComponent();
21 AppThemeHelper.MainWindow = MainWindow;
22 AppThemeHelper.Theme = SystemProfile.Theme;
23 PageManager.RegisterPage(typeof(AppShellPage));
24 PageManager.RegisterPage(typeof(NewsViewPage));
25 UnhandledException += App_UnhandledException;
26 }
37 27
38 /// <summary>
39 /// Invoked when the application is launched.
40 /// </summary>
41 /// <param name="args">Details about the launch request and process.</param>
42 protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
28 private void App_UnhandledException(object sender, Microsoft.UI.Xaml.UnhandledExceptionEventArgs e)
29 {
30 if (ServiceManager.GetService<IMessageService>() is IMessageService messageService)
43 31 {
44 m_window = new MainWindow();
45 m_window.Activate();
32 messageService.ShowMessage(e.Message, "发生错误", InfoBarSeverity.Error);
33 e.Handled = true;
46 34 }
35 }
47 36
48 private Window? m_window;
37 /// <summary>
38 /// Invoked when the application is launched.
39 /// </summary>
40 /// <param name="args">Details about the launch request and process.</param>
41 protected override void OnLaunched(LaunchActivatedEventArgs args)
42 {
43 MainWindow.Content = new AppShellPage();
44 MainWindow.Activate();
49 45 }
50 46 }
Modified XFENewsApplication/MainWindow.xaml.cs +2 -1
@@ -1,5 +1,6 @@
1 1 using Microsoft.UI.Xaml;
2 2 using Windows.UI.ViewManagement;
3 using XFEExtension.NetCore.WinUIHelper.Utilities.Helper;
3 4
4 5 namespace XFENewsApplication;
5 6
@@ -15,6 +16,6 @@ public sealed partial class MainWindow : Window
15 16 ExtendsContentIntoTitleBar = true;
16 17 AppWindow.SetIcon(Path.Combine(AppContext.BaseDirectory, "Assets/Icons/EditorIcon.ico"));
17 18 AppWindow.TitleBar.PreferredHeightOption = Microsoft.UI.Windowing.TitleBarHeightOption.Tall;
18 UISettings.ColorValuesChanged += (_, _) => DispatcherQueue.TryEnqueue(() => AppThemeHelper.ChangeTheme(SystemProfile.Theme));
19 UISettings.ColorValuesChanged += (_, _) => DispatcherQueue.TryEnqueue(() => AppThemeHelper.ChangeTheme(AppThemeHelper.Theme));
19 20 }
20 21 }
Added XFENewsApplication/Profiles/CrossVersionProfiles/SystemProfile.cs +15 -0
@@ -0,0 +1,15 @@
1 using XFEExtension.NetCore.AutoConfig;
2 using XFEExtension.NetCore.WinUIHelper.Utilities;
3 using XFEExtension.NetCore.WinUIHelper.Utilities.Helper;
4
5 namespace XFENewsApplication.Profiles.CrossVersionProfiles;
6
7 public partial class SystemProfile : XFEProfile
8 {
9 public SystemProfile() => ProfilePath = $@"{AppPathHelper.LocalProfile}\{nameof(SystemProfile)}";
10
11 [ProfileProperty]
12 private ElementTheme theme;
13
14 static partial void SetThemeProperty(ref ElementTheme value) => AppThemeHelper.ChangeTheme(value);
15 }
Added XFENewsApplication/Styles/Thickness.xaml +36 -0
@@ -0,0 +1,36 @@
1 <ResourceDictionary
2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
4
5 <Thickness x:Key="LargeTopMargin">0,36,0,0</Thickness>
6 <Thickness x:Key="LargeTopBottomMargin">0,36,0,36</Thickness>
7
8 <Thickness x:Key="MediumTopMargin">0,24,0,0</Thickness>
9 <Thickness x:Key="MediumTopBottomMargin">0,24,0,24</Thickness>
10 <Thickness x:Key="MediumLeftRightMargin">24,0,24,0</Thickness>
11 <Thickness x:Key="MediumBottomMargin">0,0,0,24</Thickness>
12
13 <Thickness x:Key="SmallLeftMargin">12,0,0,0</Thickness>
14 <Thickness x:Key="SmallLeftRightMargin">12,0,12,0</Thickness>
15 <Thickness x:Key="SmallTopMargin">0,12,0,0</Thickness>
16 <Thickness x:Key="SmallRightMargin">0,0,12,0</Thickness>
17 <Thickness x:Key="SmallTopBottomMargin">0,12,0,12</Thickness>
18
19 <Thickness x:Key="XSmallLeftMargin">8,0,0,0</Thickness>
20 <Thickness x:Key="XSmallTopMargin">0,8,0,0</Thickness>
21 <Thickness x:Key="XSmallLeftTopRightBottomMargin">8,8,8,8</Thickness>
22
23 <Thickness x:Key="XXSmallTopMargin">0,4,0,0</Thickness>
24 <Thickness x:Key="XXSmallLeftTopRightBottomMargin">4,4,4,4</Thickness>
25
26 <Thickness x:Key="NavigationViewContentGridBorderThickness">1,1,0,0</Thickness>
27 <CornerRadius x:Key="NavigationViewContentGridCornerRadius">8,0,0,0</CornerRadius>
28 <Thickness x:Key="NavigationViewContentMargin">0,48,0,0</Thickness>
29 <Thickness x:Key="NavigationViewHeaderMargin">56,34,0,0</Thickness>
30 <Thickness x:Key="NavigationViewPageContentMargin">56,24,56,0</Thickness>
31
32 <Thickness x:Key="MenuBarContentMargin">36,24,36,0</Thickness>
33
34 <Thickness x:Key="SettingsPageHyperlinkButtonMargin">-12,4,0,0</Thickness>
35
36 </ResourceDictionary>
Added XFENewsApplication/Utilities/AppPath.cs +8 -0
Added XFENewsApplication/Utilities/Converter/DateTimeConverter.cs +17 -0
Added XFENewsApplication/ViewModels/AppShellPageViewModel.cs +24 -0
Added XFENewsApplication/ViewModels/SettingPageViewModel.cs +17 -0
Added XFENewsApplication/ViewModels/ViewModelBase.cs +5 -0
Added XFENewsApplication/Views/AppShellPage.xaml +54 -0
Added XFENewsApplication/Views/AppShellPage.xaml.cs +115 -0
Added XFENewsApplication/Views/NewsViewPage.xaml +14 -0
Added XFENewsApplication/Views/NewsViewPage.xaml.cs +12 -0
Added XFENewsApplication/Views/SettingPage.xaml +104 -0
Added XFENewsApplication/Views/SettingPage.xaml.cs +22 -0
Modified XFENewsApplication/XFENewsApplication.csproj +28 -2