• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

なろうブックマーク分析用ツールのPrism+WinUI3サンプル実装


Commit MetaInfo

Revisión2534e928761185d4b51ac10a0e0085616db97401 (tree)
Tiempo2022-08-25 03:27:07
Autoryoshy <yoshy.org.bitbucket@gz.j...>
Commiteryoshy

Log Message

Merge branch 'feature/sorting_bookmark_datagrid'

Cambiar Resumen

Diferencia incremental

--- a/TestNarou3.Adaptor/Boundary/Gateway/ViewModel/Child/IBookmarkDetailListRowViewModel.cs
+++ b/TestNarou3.Adaptor/Boundary/Gateway/ViewModel/Child/IBookmarkDetailListRowViewModel.cs
@@ -14,6 +14,7 @@ namespace TestNarou3.Adaptor.Boundary.Gateway.ViewModel.Child
1414 ReadOnlyReactiveProperty<int> Time { get; }
1515 ReadOnlyReactiveProperty<string> IsStop { get; }
1616 ReadOnlyReactiveProperty<int> GlobalPoint { get; }
17+ ReadOnlyReactiveProperty<int> PointPerMin { get; }
1718 ReadOnlyReactiveProperty<int> DailyPoint { get; }
1819 ReadOnlyReactiveProperty<int> WeeklyPoint { get; }
1920 ReadOnlyReactiveProperty<int> MonthlyPoint { get; }
--- a/TestNarou3.Adaptor/Boundary/Gateway/ViewModel/IBookmarkCategoryViewModel.cs
+++ b/TestNarou3.Adaptor/Boundary/Gateway/ViewModel/IBookmarkCategoryViewModel.cs
@@ -1,4 +1,5 @@
1-using ObservableCollections;
1+using CleanAuLait.ObservableCollectionsMod;
2+using ObservableCollections;
23 using Reactive.Bindings;
34 using TestNarou3.Adaptor.Boundary.Controller;
45 using TestNarou3.Adaptor.Boundary.Gateway.ViewModel.Child;
--- a/TestNarou3.Adaptor/Boundary/Gateway/ViewModel/IBookmarkDetailListViewModel.cs
+++ b/TestNarou3.Adaptor/Boundary/Gateway/ViewModel/IBookmarkDetailListViewModel.cs
@@ -1,7 +1,5 @@
1-using ObservableCollections;
1+using CleanAuLait.ObservableCollectionsMod;
22 using Reactive.Bindings;
3-using System;
4-using System.ComponentModel;
53 using TestNarou3.Adaptor.Boundary.Gateway.ViewModel.Child;
64 using TestNarou3.Domain.Model.Entity;
75 using TestNarou3.Domain.Model.Entity.Child;
@@ -23,5 +21,8 @@ namespace TestNarou3.Adaptor.Boundary.Gateway.ViewModel
2321 BookmarkDetailList Source { get; }
2422
2523 void SynchronizeWith(BookmarkDetailList list);
24+
25+ void SortByValueColumn<TValueColumn>(string tag, Func<BookmarkDetailListRow, TValueColumn> selector, bool asceding);
26+ void SortByViewColumn<TViewColumn>(string tag, Func<IBookmarkDetailListRowViewModel, TViewColumn> selector, bool asceding);
2627 }
2728 }
--- a/TestNarou3.Adaptor/Gateway/ViewModel/BookmarkCategoryViewModel.cs
+++ b/TestNarou3.Adaptor/Gateway/ViewModel/BookmarkCategoryViewModel.cs
@@ -1,6 +1,6 @@
11 using CleanAuLait.Core.Log;
2+using CleanAuLait.ObservableCollectionsMod;
23 using NLog;
3-using ObservableCollections;
44 using Prism.Navigation;
55 using Reactive.Bindings;
66 using Reactive.Bindings.Extensions;
@@ -93,25 +93,19 @@ namespace TestNarou3.Adaptor.Gateway.ViewModel
9393
9494 #endregion
9595
96- #region IDestructible
96+ #region IDestructible, IDisposable
9797
9898 public void Destroy()
9999 {
100100 this.Dispose();
101101 }
102102
103- #endregion
104-
105- #region IDisposable
106-
107103 protected virtual void Dispose(bool disposing)
108104 {
109105 if (!disposedValue)
110106 {
111107 if (disposing)
112108 {
113- DisposeSynchronizedView();
114-
115109 this.disposables.Dispose();
116110
117111 logger.Trace("BookmarkCategoryViewModel disposed.");
@@ -121,20 +115,8 @@ namespace TestNarou3.Adaptor.Gateway.ViewModel
121115 }
122116 }
123117
124- private void DisposeSynchronizedView()
125- {
126- foreach (var row in this.Rows)
127- {
128- if (row is IDisposable disposable)
129- {
130- disposable.Dispose();
131- }
132- }
133- }
134-
135118 public void Dispose()
136119 {
137- // このコードを変更しないでください。クリーンアップ コードを 'Dispose(bool disposing)' メソッドに記述します
138120 Dispose(disposing: true);
139121 GC.SuppressFinalize(this);
140122 }
--- a/TestNarou3.Adaptor/Gateway/ViewModel/BookmarkDetailListViewModel.cs
+++ b/TestNarou3.Adaptor/Gateway/ViewModel/BookmarkDetailListViewModel.cs
@@ -1,6 +1,6 @@
11 using CleanAuLait.Core.Log;
2+using CleanAuLait.ObservableCollectionsMod;
23 using NLog;
3-using ObservableCollections;
44 using Prism.Navigation;
55 using Reactive.Bindings;
66 using Reactive.Bindings.Extensions;
@@ -27,7 +27,10 @@ namespace TestNarou3.Adaptor.Gateway.ViewModel
2727
2828 public ReactiveProperty<IBookmarkDetailListRowViewModel> SelectedItem { get; }
2929
30- public INotifyCollectionChangedListSynchronizedSingleView<BookmarkDetailListRow, IBookmarkDetailListRowViewModel> Rows { get; private set; } = null;
30+ public INotifyCollectionChangedListSynchronizedSingleView<
31+ BookmarkDetailListRow, IBookmarkDetailListRowViewModel> Rows { get; private set; } = null;
32+ private ISortableSynchronizedCoupleView<
33+ BookmarkDetailListRow, string, IBookmarkDetailListRowViewModel> SortableRows { get; set; }
3134
3235 public ReactiveCommand CommandOpenBookmark { get; }
3336
@@ -85,8 +88,12 @@ namespace TestNarou3.Adaptor.Gateway.ViewModel
8588 {
8689 if (this.Source == null)
8790 {
88- this.Rows = source.Rows
89- .ToSynchronizedCoupleView(r => this.vmTranslator.Translate(r, this))
91+ this.SortableRows = source.Rows
92+ .ToSortableSynchronizedCoupleView(
93+ r => r.NCode, r => this.vmTranslator.Translate(r, this),
94+ new DetailListViewComparer<string>(r => r.Title.Value));
95+
96+ this.Rows = this.SortableRows
9097 .ToSynchronizedSingleView()
9198 .WithINotifyCollectionChangedList()
9299 .AddTo(disposables);
@@ -103,18 +110,50 @@ namespace TestNarou3.Adaptor.Gateway.ViewModel
103110 }
104111 }
105112
106- #endregion
113+ public void SortByViewColumn<TViewColumn>(
114+ string tag, Func<IBookmarkDetailListRowViewModel, TViewColumn> selector, bool ascending)
115+ {
116+ logger.Trace("Sort: {0}, ascending = {1}", tag, ascending);
117+ this.SortableRows.Sort(this.SortableRows.CreateViewComparer(selector, ascending));
118+ }
107119
108- #region IDestructible
120+ public void SortByValueColumn<TValueColumn>(
121+ string tag, Func<BookmarkDetailListRow, TValueColumn> selector, bool ascending)
122+ {
123+ logger.Trace("Sort: {0}, ascending = {1}", tag, ascending);
124+ this.SortableRows.Sort(this.SortableRows.CreateValueComparer(selector, ascending));
125+ }
109126
110- public void Destroy()
127+ private class DetailListViewComparer<TViewColumn>
128+ : SortableSynchronizedCoupleViewViewComparer<
129+ string, BookmarkDetailListRow, IBookmarkDetailListRowViewModel, TViewColumn>
111130 {
112- this.Dispose();
131+ public DetailListViewComparer(
132+ Func<IBookmarkDetailListRowViewModel, TViewColumn> selector, bool ascending = true
133+ ) : base(selector, ascending)
134+ {
135+ }
136+ }
137+
138+ private class DetailListValueComparer<TValueColumn>
139+ : SortableSynchronizedCoupleViewValueComparer<
140+ string, BookmarkDetailListRow, IBookmarkDetailListRowViewModel, TValueColumn>
141+ {
142+ public DetailListValueComparer(
143+ Func<BookmarkDetailListRow, TValueColumn> selector, bool ascending = true
144+ ) : base(selector, ascending)
145+ {
146+ }
113147 }
114148
115149 #endregion
116150
117- #region IDisposable
151+ #region IDestructible, IDisposable
152+
153+ public void Destroy()
154+ {
155+ this.Dispose();
156+ }
118157
119158 protected virtual void Dispose(bool disposing)
120159 {
@@ -122,8 +161,6 @@ namespace TestNarou3.Adaptor.Gateway.ViewModel
122161 {
123162 if (disposing)
124163 {
125- DisposeSynchronizedView();
126-
127164 this.disposables.Dispose();
128165
129166 logger.Trace("BookmarkDetailListViewModel disposed.");
@@ -133,25 +170,12 @@ namespace TestNarou3.Adaptor.Gateway.ViewModel
133170 }
134171 }
135172
136- private void DisposeSynchronizedView()
137- {
138- foreach (var row in this.Rows)
139- {
140- if (row is IDisposable disposable)
141- {
142- disposable.Dispose();
143- }
144- }
145- }
146-
147173 public void Dispose()
148174 {
149- // このコードを変更しないでください。クリーンアップ コードを 'Dispose(bool disposing)' メソッドに記述します
150175 Dispose(disposing: true);
151176 GC.SuppressFinalize(this);
152177 }
153178
154179 #endregion
155-
156180 }
157181 }
--- a/TestNarou3.Adaptor/Gateway/ViewModel/Child/BookmarkCategoryRowViewModel.cs
+++ b/TestNarou3.Adaptor/Gateway/ViewModel/Child/BookmarkCategoryRowViewModel.cs
@@ -1,4 +1,5 @@
11 using Microsoft.UI.Xaml.Media.Imaging;
2+using NLog;
23 using Reactive.Bindings;
34 using System.Reactive.Disposables;
45 using TestNarou3.Adaptor.Boundary.Gateway.ViewModel;
@@ -17,6 +18,8 @@ namespace TestNarou3.Adaptor.Gateway.ViewModel.Child
1718 BookmarkCategoryRow Source
1819 ) : IBookmarkCategoryRowViewModel, IDisposable
1920 {
21+ private static readonly ILogger logger = LogManager.GetCurrentClassLogger();
22+
2023 private readonly CompositeDisposable disposables = new();
2124 private bool disposedValue;
2225
@@ -39,6 +42,7 @@ namespace TestNarou3.Adaptor.Gateway.ViewModel.Child
3942 if (disposing)
4043 {
4144 this.disposables.Dispose();
45+ logger.Trace("BookmarkCategoryRowViewModel[{0}] disposed.", this.Index);
4246 }
4347
4448 disposedValue = true;
--- a/TestNarou3.Adaptor/Gateway/ViewModel/Child/BookmarkDetailListRowViewModel.cs
+++ b/TestNarou3.Adaptor/Gateway/ViewModel/Child/BookmarkDetailListRowViewModel.cs
@@ -56,6 +56,7 @@ namespace TestNarou3.Adaptor.Gateway.ViewModel.Child
5656 if (disposing)
5757 {
5858 this.disposables.Dispose();
59+ logger.Trace("BookmarkDetailListRowViewModel[{0}] disposed.", this.NCode);
5960 }
6061
6162 disposedValue = true;
--- a/TestNarou3.Adaptor/Gateway/ViewModel/LoginFormViewModel.cs
+++ b/TestNarou3.Adaptor/Gateway/ViewModel/LoginFormViewModel.cs
@@ -38,17 +38,13 @@ namespace TestNarou3.Adaptor.Gateway.ViewModel
3838 this.CommandLogin = new ReactiveCommand().WithSubscribe(OnLogin).AddTo(disposables);
3939 }
4040
41- #region IDestructible
41+ #region IDestructible, IDisposable
4242
4343 public void Destroy()
4444 {
4545 this.Dispose();
4646 }
4747
48- #endregion
49-
50- #region IDisposable
51-
5248 protected virtual void Dispose(bool disposing)
5349 {
5450 if (!disposedValue)
@@ -89,7 +85,6 @@ namespace TestNarou3.Adaptor.Gateway.ViewModel
8985 }
9086
9187 this.wc.NavigateBookmarkView();
92- this.wc.NavigateBookmarkListView(1);
9388 }
9489
9590 #endregion
--- a/TestNarou3.Adaptor/Gateway/ViewModel/MainWindowViewModel.cs
+++ b/TestNarou3.Adaptor/Gateway/ViewModel/MainWindowViewModel.cs
@@ -42,17 +42,13 @@ namespace TestNarou3.Adaptor.Gateway.ViewModel
4242 this.Dispose();
4343 }
4444
45- #region IDestructible
45+ #region IDestructible, IDisposable
4646
4747 public void Destroy()
4848 {
4949 this.Dispose();
5050 }
5151
52- #endregion
53-
54- #region IDisposable
55-
5652 protected virtual void Dispose(bool disposing)
5753 {
5854 if (!disposedValue)
--- a/TestNarou3.Domain/Boundary/Repository/INarouRepository.cs
+++ b/TestNarou3.Domain/Boundary/Repository/INarouRepository.cs
@@ -3,7 +3,7 @@ using TestNarou3.Domain.Model.API;
33
44 namespace TestNarou3.Domain.Boundary.Repository
55 {
6- public interface INarouRepository : IDestructible
6+ public interface INarouRepository : IDisposable
77 {
88 string Login(string id, string password);
99 void Logout(string dataToken);
--- a/TestNarou3.Domain/Model/Entity/BookmarkCategory.cs
+++ b/TestNarou3.Domain/Model/Entity/BookmarkCategory.cs
@@ -1,4 +1,5 @@
1-using ObservableCollections;
1+using NLog;
2+using ObservableCollections;
23 using System;
34 using System.Collections.Generic;
45 using TestNarou3.Domain.Model.Entity.Child;
@@ -9,6 +10,8 @@ namespace TestNarou3.Domain.Model.Entity
910 ObservableList<BookmarkCategoryRow> Rows
1011 ) : IDisposable
1112 {
13+ private static readonly ILogger logger = LogManager.GetCurrentClassLogger();
14+
1215 private bool disposedValue;
1316
1417 public BookmarkCategory() : this(
@@ -42,6 +45,8 @@ namespace TestNarou3.Domain.Model.Entity
4245 {
4346 row.Dispose();
4447 }
48+
49+ logger.Trace("BookmarkCategory disposed.");
4550 }
4651
4752 disposedValue = true;
--- a/TestNarou3.Domain/Model/Entity/BookmarkDetailList.cs
+++ b/TestNarou3.Domain/Model/Entity/BookmarkDetailList.cs
@@ -1,4 +1,5 @@
1-using ObservableCollections;
1+using NLog;
2+using ObservableCollections;
23 using System;
34 using System.Collections.Generic;
45 using TestNarou3.Domain.Model.Entity.Child;
@@ -9,6 +10,8 @@ namespace TestNarou3.Domain.Model.Entity
910 ObservableList<BookmarkDetailListRow> Rows
1011 ) : IDisposable
1112 {
13+ private static readonly ILogger logger = LogManager.GetCurrentClassLogger();
14+
1215 private bool disposedValue;
1316
1417 public BookmarkDetailList() : this(
@@ -20,16 +23,7 @@ namespace TestNarou3.Domain.Model.Entity
2023 public void Refresh(IEnumerable<BookmarkDetailListRow> rows)
2124 {
2225 this.Rows.Clear();
23-
24- // due to the communication toolkit datagrid does not support range operations,
25- // we have to add the data row by row.
26-
27- //this.Rows.AddRange(rows);
28-
29- foreach (var row in rows)
30- {
31- this.Rows.Add(row);
32- }
26+ this.Rows.AddRange(rows);
3327 }
3428
3529 protected virtual void Dispose(bool disposing)
@@ -42,6 +36,8 @@ namespace TestNarou3.Domain.Model.Entity
4236 {
4337 row.Dispose();
4438 }
39+
40+ logger.Trace("BookmarkDetailList disposed.");
4541 }
4642
4743 disposedValue = true;
--- a/TestNarou3.Domain/Model/Entity/Child/BookmarkCategoryRow.cs
+++ b/TestNarou3.Domain/Model/Entity/Child/BookmarkCategoryRow.cs
@@ -1,4 +1,5 @@
1-using Reactive.Bindings;
1+using NLog;
2+using Reactive.Bindings;
23 using Reactive.Bindings.Extensions;
34 using System;
45 using System.Reactive.Disposables;
@@ -11,6 +12,8 @@ namespace TestNarou3.Domain.Model.Entity.Child
1112 ReactivePropertySlim<int> Count
1213 ) : IDisposable
1314 {
15+ private static readonly ILogger logger = LogManager.GetCurrentClassLogger();
16+
1417 private readonly CompositeDisposable disposables = new();
1518 private bool disposedValue;
1619
@@ -31,6 +34,7 @@ namespace TestNarou3.Domain.Model.Entity.Child
3134 if (disposing)
3235 {
3336 this.disposables.Dispose();
37+ logger.Trace("BookmarkCategoryRow[{0}] disposed.", Index);
3438 }
3539
3640 disposedValue = true;
--- a/TestNarou3.Domain/Model/Entity/Child/BookmarkDetailListRow.cs
+++ b/TestNarou3.Domain/Model/Entity/Child/BookmarkDetailListRow.cs
@@ -1,4 +1,5 @@
1-using Reactive.Bindings;
1+using NLog;
2+using Reactive.Bindings;
23 using Reactive.Bindings.Extensions;
34 using System;
45 using System.Reactive.Disposables;
@@ -40,6 +41,8 @@ namespace TestNarou3.Domain.Model.Entity.Child
4041 ReactivePropertySlim<string> NovelUpdatedAt
4142 ) : IDisposable
4243 {
44+ private static readonly ILogger logger = LogManager.GetCurrentClassLogger();
45+
4346 private readonly CompositeDisposable disposables = new();
4447 private bool disposedValue;
4548
@@ -117,6 +120,7 @@ namespace TestNarou3.Domain.Model.Entity.Child
117120 if (disposing)
118121 {
119122 this.disposables.Dispose();
123+ logger.Trace("BookmarkDetailListRow[{0}] disposed.", NCode);
120124 }
121125
122126 disposedValue = true;
--- a/TestNarou3.Domain/Service/NarouService.cs
+++ b/TestNarou3.Domain/Service/NarouService.cs
@@ -11,7 +11,7 @@ using TestNarou3.Domain.Translator;
1111
1212 namespace TestNarou3.Domain.Service
1313 {
14- internal class NarouService : INarouService, IDestructible
14+ internal class NarouService : INarouService, IDisposable
1515 {
1616 private static readonly ILogger logger = LogManager.GetCurrentClassLogger();
1717
@@ -25,6 +25,8 @@ namespace TestNarou3.Domain.Service
2525 private readonly IBookmarkCategoryRowTranslator vmCategoryRowTranslator;
2626 private readonly IBookmarkDetailListRowTranslator vmDetailRowTranslator;
2727
28+ private bool disposedValue;
29+
2830 public NarouService(
2931 INarouRepository repo,
3032 IBookmarkCategoryRowTranslator vmCategoryRowTranslator,
@@ -85,12 +87,32 @@ namespace TestNarou3.Domain.Service
8587 return this.DetailList;
8688 }
8789
88- public void Destroy()
90+ #region IDisposable
91+
92+ protected virtual void Dispose(bool disposing)
8993 {
90- this.Categeory?.Dispose();
91- this.DetailList?.Dispose();
94+ if (!disposedValue)
95+ {
96+ if (disposing)
97+ {
98+ this.Categeory?.Dispose();
99+ this.DetailList?.Dispose();
100+
101+ this.repo?.Dispose();
102+
103+ logger.Trace("NarouService disposed.");
104+ }
92105
93- this.repo?.Destroy();
106+ disposedValue = true;
107+ }
94108 }
109+
110+ public void Dispose()
111+ {
112+ Dispose(disposing: true);
113+ GC.SuppressFinalize(this);
114+ }
115+
116+ #endregion
95117 }
96118 }
--- a/TestNarou3.Infra/TestNarou3.90Infra.csproj
+++ b/TestNarou3.Infra/TestNarou3.90Infra.csproj
@@ -16,7 +16,7 @@
1616 </ItemGroup>
1717
1818 <ItemGroup>
19+ <ProjectReference Include="..\..\CleanAuLait.ObservableCollectionsMod\CleanAuLait.ObservableCollectionsMod.csproj" />
1920 <ProjectReference Include="..\..\CleanAuLait.Prism.WinUI3\CleanAuLait.Prism.WinUI3.csproj" />
20- <ProjectReference Include="..\..\ObservableCollectionsMod\src\ObservableCollections\ObservableCollections.csproj" />
2121 </ItemGroup>
2222 </Project>
--- a/TestNarou3.OuterEdge/Repository/API/HttpClientHelper.cs
+++ b/TestNarou3.OuterEdge/Repository/API/HttpClientHelper.cs
@@ -11,7 +11,7 @@ using System.Threading.Tasks;
1111
1212 namespace TestNarou3.OuterEdge.Repository.API
1313 {
14- internal class HttpClientHelper : IDestructible
14+ internal class HttpClientHelper : IDisposable
1515 {
1616 private static readonly ILogger logger = LogManager.GetCurrentClassLogger();
1717
@@ -26,6 +26,8 @@ namespace TestNarou3.OuterEdge.Repository.API
2626 private readonly HttpClientHandler httpClientHandler;
2727 private readonly HttpClient httpClient;
2828
29+ private bool disposedValue;
30+
2931 public HttpClientHelper()
3032 {
3133 cookies = new();
@@ -66,6 +68,30 @@ namespace TestNarou3.OuterEdge.Repository.API
6668 }
6769 }
6870
71+ #region IDisposable
72+
73+ protected virtual void Dispose(bool disposing)
74+ {
75+ if (!disposedValue)
76+ {
77+ if (disposing)
78+ {
79+ httpClient.Dispose();
80+ logger.Trace("HttpClientHelper disposed.");
81+ }
82+
83+ disposedValue = true;
84+ }
85+ }
86+
87+ public void Dispose()
88+ {
89+ Dispose(disposing: true);
90+ GC.SuppressFinalize(this);
91+ }
92+
93+ #endregion
94+
6995 public async Task<HttpResponseMessage> GetAsync(string url, string referer)
7096 {
7197 var request = CreateRequestMessage(url, referer, HttpMethod.Post);
@@ -175,10 +201,5 @@ namespace TestNarou3.OuterEdge.Repository.API
175201
176202 return Encoding.UTF8.GetString(raw);
177203 }
178-
179- public void Destroy()
180- {
181- httpClient.Dispose();
182- }
183204 }
184205 }
--- a/TestNarou3.OuterEdge/Repository/API/NarouRepository.cs
+++ b/TestNarou3.OuterEdge/Repository/API/NarouRepository.cs
@@ -46,6 +46,32 @@ namespace TestNarou3.OuterEdge.Repository.API
4646
4747 private readonly HttpClientHelper httpClient = new();
4848
49+ private bool disposedValue;
50+
51+ #region IDisposable
52+
53+ protected virtual void Dispose(bool disposing)
54+ {
55+ if (!disposedValue)
56+ {
57+ if (disposing)
58+ {
59+ this.httpClient?.Dispose();
60+ logger.Trace("NarouRepository disposed.");
61+ }
62+
63+ disposedValue = true;
64+ }
65+ }
66+
67+ public void Dispose()
68+ {
69+ Dispose(disposing: true);
70+ System.GC.SuppressFinalize(this);
71+ }
72+
73+ #endregion
74+
4975 public string Login(string id, string password)
5076 {
5177 var form = new Dictionary<string, string>()
@@ -253,11 +279,5 @@ namespace TestNarou3.OuterEdge.Repository.API
253279
254280 return json;
255281 }
256-
257- public void Destroy()
258- {
259- this.httpClient?.Destroy();
260- }
261-
262282 }
263283 }
--- a/TestNarou3.OuterEdge/UI/View/BookmarkDetailListView.xaml
+++ b/TestNarou3.OuterEdge/UI/View/BookmarkDetailListView.xaml
@@ -17,13 +17,14 @@
1717 <conv:StringFormatConverter x:Key="StringFormat" />
1818 </UserControl.Resources>
1919
20- <ctc:DataGrid ItemsSource="{x:Bind ViewModel.Rows, Mode=OneWay}"
20+ <ctc:DataGrid x:Name="dg" ItemsSource="{x:Bind ViewModel.Rows, Mode=OneWay}"
2121 AutoGenerateColumns="False"
22+ IsReadOnly="True"
2223 CanUserReorderColumns="False"
2324 CanUserSortColumns="True"
25+ Sorting="OnSorting"
2426 SelectionMode="Single"
2527 SelectedItem="{x:Bind ViewModel.SelectedItem.Value, Mode=TwoWay}"
26- IsReadOnly="True"
2728 RowBackground="{ThemeResource SystemControlBackgroundAltMediumLowBrush}"
2829 AlternatingRowBackground="{ThemeResource SystemControlBackgroundAltMediumHighBrush}"
2930 GridLinesVisibility="None">
@@ -47,7 +48,7 @@
4748
4849 <ctc:DataGrid.Columns>
4950
50- <ctc:DataGridTemplateColumn Header="概" Width="10">
51+ <ctc:DataGridTemplateColumn Header="概" Width="10" CanUserSort="False">
5152 <ctc:DataGridTemplateColumn.CellTemplate>
5253 <DataTemplate x:DataType="vm:IBookmarkDetailListRowViewModel">
5354 <Grid VerticalAlignment="Center">
@@ -57,7 +58,7 @@
5758 </DataTemplate>
5859 </ctc:DataGridTemplateColumn.CellTemplate>
5960 </ctc:DataGridTemplateColumn>
60- <ctc:DataGridTemplateColumn Header="タイトル" Width="300">
61+ <ctc:DataGridTemplateColumn Header="タイトル" Width="300" Tag="Title">
6162 <ctc:DataGridTemplateColumn.CellTemplate>
6263 <DataTemplate x:DataType="vm:IBookmarkDetailListRowViewModel">
6364 <Grid VerticalAlignment="Center">
@@ -70,7 +71,7 @@
7071 </DataTemplate>
7172 </ctc:DataGridTemplateColumn.CellTemplate>
7273 </ctc:DataGridTemplateColumn>
73- <ctc:DataGridTemplateColumn Header="作者" Width="100">
74+ <ctc:DataGridTemplateColumn Header="作者" Width="100" Tag="Writer">
7475 <ctc:DataGridTemplateColumn.CellTemplate>
7576 <DataTemplate x:DataType="vm:IBookmarkDetailListRowViewModel">
7677 <Grid VerticalAlignment="Center">
@@ -83,7 +84,7 @@
8384 </DataTemplate>
8485 </ctc:DataGridTemplateColumn.CellTemplate>
8586 </ctc:DataGridTemplateColumn>
86- <ctc:DataGridTemplateColumn Header="完結" Width="40">
87+ <ctc:DataGridTemplateColumn Header="完結" Width="40" Tag="End">
8788 <ctc:DataGridTemplateColumn.CellTemplate>
8889 <DataTemplate x:DataType="vm:IBookmarkDetailListRowViewModel">
8990 <Grid VerticalAlignment="Center">
@@ -92,7 +93,7 @@
9293 </DataTemplate>
9394 </ctc:DataGridTemplateColumn.CellTemplate>
9495 </ctc:DataGridTemplateColumn>
95- <ctc:DataGridTextColumn Header="話数" Width="60"
96+ <ctc:DataGridTextColumn Header="話数" Width="60" Tag="GeneralAllNo"
9697 Binding="{Binding GeneralAllNo.Value, Converter={StaticResource StringFormat},ConverterParameter=\{0:N0\}}" >
9798 <ctc:DataGridTextColumn.ElementStyle>
9899 <Style TargetType="TextBlock">
@@ -100,7 +101,7 @@
100101 </Style>
101102 </ctc:DataGridTextColumn.ElementStyle>
102103 </ctc:DataGridTextColumn>
103- <ctc:DataGridTextColumn Header="長さ[h]" Width="70"
104+ <ctc:DataGridTextColumn Header="長さ[h]" Width="70" Tag="Time"
104105 Binding="{Binding Time.Value, Converter={StaticResource StringFormat},ConverterParameter=\{0:N0\}}">
105106 <ctc:DataGridTextColumn.ElementStyle>
106107 <Style TargetType="TextBlock">
@@ -108,7 +109,7 @@
108109 </Style>
109110 </ctc:DataGridTextColumn.ElementStyle>
110111 </ctc:DataGridTextColumn>
111- <ctc:DataGridTemplateColumn Header="エタ" Width="25">
112+ <ctc:DataGridTemplateColumn Header="エタ" Width="25" Tag="IsStop">
112113 <ctc:DataGridTemplateColumn.CellTemplate>
113114 <DataTemplate x:DataType="vm:IBookmarkDetailListRowViewModel">
114115 <Grid VerticalAlignment="Center">
@@ -117,7 +118,7 @@
117118 </DataTemplate>
118119 </ctc:DataGridTemplateColumn.CellTemplate>
119120 </ctc:DataGridTemplateColumn>
120- <ctc:DataGridTextColumn Header="総合評価pt." Width="100"
121+ <ctc:DataGridTextColumn Header="総合評価pt." Width="100" Tag="GlobalPoint"
121122 Binding="{Binding GlobalPoint.Value, Converter={StaticResource StringFormat},ConverterParameter=\{0:N0\}}" >
122123 <ctc:DataGridTextColumn.ElementStyle>
123124 <Style TargetType="TextBlock">
@@ -125,7 +126,7 @@
125126 </Style>
126127 </ctc:DataGridTextColumn.ElementStyle>
127128 </ctc:DataGridTextColumn>
128- <ctc:DataGridTextColumn Header="評価/分" Width="80"
129+ <ctc:DataGridTextColumn Header="評価/分" Width="80" Tag="PointPerMin"
129130 Binding="{Binding PointPerMin.Value, Converter={StaticResource StringFormat},ConverterParameter=\{0:N0\}}" >
130131 <ctc:DataGridTextColumn.ElementStyle>
131132 <Style TargetType="TextBlock">
@@ -133,7 +134,7 @@
133134 </Style>
134135 </ctc:DataGridTextColumn.ElementStyle>
135136 </ctc:DataGridTextColumn>
136- <ctc:DataGridTextColumn Header="日間pt." Width="80"
137+ <ctc:DataGridTextColumn Header="日間pt." Width="80" Tag="DailyPoint"
137138 Binding="{Binding DailyPoint.Value, Converter={StaticResource StringFormat},ConverterParameter=\{0:N0\}}" >
138139 <ctc:DataGridTextColumn.ElementStyle>
139140 <Style TargetType="TextBlock">
@@ -141,7 +142,7 @@
141142 </Style>
142143 </ctc:DataGridTextColumn.ElementStyle>
143144 </ctc:DataGridTextColumn>
144- <ctc:DataGridTextColumn Header="週間pt." Width="80"
145+ <ctc:DataGridTextColumn Header="週間pt." Width="80" Tag="WeeklyPoint"
145146 Binding="{Binding WeeklyPoint.Value, Converter={StaticResource StringFormat},ConverterParameter=\{0:N0\}}" >
146147 <ctc:DataGridTextColumn.ElementStyle>
147148 <Style TargetType="TextBlock">
@@ -149,7 +150,7 @@
149150 </Style>
150151 </ctc:DataGridTextColumn.ElementStyle>
151152 </ctc:DataGridTextColumn>
152- <ctc:DataGridTextColumn Header="月間pt." Width="80"
153+ <ctc:DataGridTextColumn Header="月間pt." Width="80" Tag="MonthlyPoint"
153154 Binding="{Binding MonthlyPoint.Value, Converter={StaticResource StringFormat},ConverterParameter=\{0:N0\}}" >
154155 <ctc:DataGridTextColumn.ElementStyle>
155156 <Style TargetType="TextBlock">
@@ -157,7 +158,7 @@
157158 </Style>
158159 </ctc:DataGridTextColumn.ElementStyle>
159160 </ctc:DataGridTextColumn>
160- <ctc:DataGridTextColumn Header="四半期pt." Width="80"
161+ <ctc:DataGridTextColumn Header="四半期pt." Width="80" Tag="QuarterPoint"
161162 Binding="{Binding QuarterPoint.Value, Converter={StaticResource StringFormat},ConverterParameter=\{0:N0\}}" >
162163 <ctc:DataGridTextColumn.ElementStyle>
163164 <Style TargetType="TextBlock">
@@ -165,7 +166,7 @@
165166 </Style>
166167 </ctc:DataGridTextColumn.ElementStyle>
167168 </ctc:DataGridTextColumn>
168- <ctc:DataGridTextColumn Header="年間pt." Width="80"
169+ <ctc:DataGridTextColumn Header="年間pt." Width="80" Tag="YearlyPoint"
169170 Binding="{Binding YearlyPoint.Value, Converter={StaticResource StringFormat},ConverterParameter=\{0:N0\}}" >
170171 <ctc:DataGridTextColumn.ElementStyle>
171172 <Style TargetType="TextBlock">
@@ -173,7 +174,7 @@
173174 </Style>
174175 </ctc:DataGridTextColumn.ElementStyle>
175176 </ctc:DataGridTextColumn>
176- <ctc:DataGridTextColumn Header="ブクマ数" Width="80"
177+ <ctc:DataGridTextColumn Header="ブクマ数" Width="80" Tag="FavNovelCnt"
177178 Binding="{Binding FavNovelCnt.Value, Converter={StaticResource StringFormat},ConverterParameter=\{0:N0\}}" >
178179 <ctc:DataGridTextColumn.ElementStyle>
179180 <Style TargetType="TextBlock">
@@ -181,7 +182,7 @@
181182 </Style>
182183 </ctc:DataGridTextColumn.ElementStyle>
183184 </ctc:DataGridTextColumn>
184- <ctc:DataGridTextColumn Header="感想数" Width="80"
185+ <ctc:DataGridTextColumn Header="感想数" Width="80" Tag="ImpressionCnt"
185186 Binding="{Binding ImpressionCnt.Value, Converter={StaticResource StringFormat},ConverterParameter=\{0:N0\}}" >
186187 <ctc:DataGridTextColumn.ElementStyle>
187188 <Style TargetType="TextBlock">
@@ -189,7 +190,7 @@
189190 </Style>
190191 </ctc:DataGridTextColumn.ElementStyle>
191192 </ctc:DataGridTextColumn>
192- <ctc:DataGridTextColumn Header="レビュー数" Width="60"
193+ <ctc:DataGridTextColumn Header="レビュー数" Width="60" Tag="ReviewCnt"
193194 Binding="{Binding ReviewCnt.Value, Converter={StaticResource StringFormat},ConverterParameter=\{0:N0\}}" >
194195 <ctc:DataGridTextColumn.ElementStyle>
195196 <Style TargetType="TextBlock">
@@ -197,7 +198,7 @@
197198 </Style>
198199 </ctc:DataGridTextColumn.ElementStyle>
199200 </ctc:DataGridTextColumn>
200- <ctc:DataGridTextColumn Header="評価pt." Width="80"
201+ <ctc:DataGridTextColumn Header="評価pt." Width="80" Tag="AllPoint"
201202 Binding="{Binding AllPoint.Value, Converter={StaticResource StringFormat},ConverterParameter=\{0:N0\}}" >
202203 <ctc:DataGridTextColumn.ElementStyle>
203204 <Style TargetType="TextBlock">
@@ -205,7 +206,7 @@
205206 </Style>
206207 </ctc:DataGridTextColumn.ElementStyle>
207208 </ctc:DataGridTextColumn>
208- <ctc:DataGridTextColumn Header="評価者数" Width="70"
209+ <ctc:DataGridTextColumn Header="評価者数" Width="70" Tag="AllHyokaCnt"
209210 Binding="{Binding AllHyokaCnt.Value, Converter={StaticResource StringFormat},ConverterParameter=\{0:N0\}}" >
210211 <ctc:DataGridTextColumn.ElementStyle>
211212 <Style TargetType="TextBlock">
@@ -213,7 +214,7 @@
213214 </Style>
214215 </ctc:DataGridTextColumn.ElementStyle>
215216 </ctc:DataGridTextColumn>
216- <ctc:DataGridTextColumn Header="最終掲載日" Width="100"
217+ <ctc:DataGridTextColumn Header="最終掲載日" Width="100" Tag="GeneralLastUp"
217218 Binding="{Binding GeneralLastUp.Value}">
218219 <ctc:DataGridTextColumn.ElementStyle>
219220 <Style TargetType="TextBlock">
@@ -221,7 +222,7 @@
221222 </Style>
222223 </ctc:DataGridTextColumn.ElementStyle>
223224 </ctc:DataGridTextColumn>
224- <ctc:DataGridTextColumn Header="初回掲載日" Width="100"
225+ <ctc:DataGridTextColumn Header="初回掲載日" Width="100" Tag="GeneralFirstUp"
225226 Binding="{Binding GeneralFirstUp.Value}">
226227 <ctc:DataGridTextColumn.ElementStyle>
227228 <Style TargetType="TextBlock">
@@ -229,7 +230,7 @@
229230 </Style>
230231 </ctc:DataGridTextColumn.ElementStyle>
231232 </ctc:DataGridTextColumn>
232- <ctc:DataGridTextColumn Header="小説更新日" Width="100"
233+ <ctc:DataGridTextColumn Header="小説更新日" Width="100" Tag="NovelUpdatedAt"
233234 Binding="{Binding NovelUpdatedAt.Value}">
234235 <ctc:DataGridTextColumn.ElementStyle>
235236 <Style TargetType="TextBlock">
--- a/TestNarou3.OuterEdge/UI/View/BookmarkDetailListView.xaml.cs
+++ b/TestNarou3.OuterEdge/UI/View/BookmarkDetailListView.xaml.cs
@@ -1,16 +1,20 @@
1-using Microsoft.UI.Xaml;
1+using CommunityToolkit.WinUI.UI.Controls;
2+using Microsoft.UI.Xaml;
23 using Microsoft.UI.Xaml.Controls;
34 using Microsoft.UI.Xaml.Controls.Primitives;
45 using Microsoft.UI.Xaml.Data;
56 using Microsoft.UI.Xaml.Input;
67 using Microsoft.UI.Xaml.Media;
78 using Microsoft.UI.Xaml.Navigation;
9+using NLog;
810 using System;
911 using System.Collections.Generic;
12+using System.Collections.ObjectModel;
1013 using System.IO;
1114 using System.Linq;
1215 using System.Runtime.InteropServices.WindowsRuntime;
1316 using TestNarou3.Adaptor.Boundary.Gateway.ViewModel;
17+using TestNarou3.Adaptor.Boundary.Gateway.ViewModel.Child;
1418 using Windows.Foundation;
1519 using Windows.Foundation.Collections;
1620
@@ -21,6 +25,8 @@ namespace TestNarou3.OuterEdge.UI.View
2125 {
2226 public sealed partial class BookmarkDetailListView : UserControl
2327 {
28+ private static readonly ILogger logger = LogManager.GetCurrentClassLogger();
29+
2430 public IBookmarkDetailListViewModel ViewModel { get; }
2531
2632 public BookmarkDetailListView(IBookmarkDetailListViewModel viewModel)
@@ -29,5 +35,303 @@ namespace TestNarou3.OuterEdge.UI.View
2935
3036 this.InitializeComponent();
3137 }
38+
39+ private void OnSorting(object sender, DataGridColumnEventArgs e)
40+ {
41+ string tag = e.Column.Tag.ToString();
42+
43+ DataGridSortDirection direction = e.Column.SortDirection ?? DataGridSortDirection.Ascending;
44+
45+ logger.Trace("OnSorting: tag [{0}], direction [{1}]", tag, direction.ToString());
46+
47+ switch (tag)
48+ {
49+ case "Title":
50+ if ((e.Column.SortDirection == null) || (direction == DataGridSortDirection.Descending))
51+ {
52+ this.ViewModel.SortByViewColumn(tag, r => r.Title.Value, true);
53+ e.Column.SortDirection = DataGridSortDirection.Ascending;
54+ }
55+ else
56+ {
57+ this.ViewModel.SortByViewColumn(tag, r => r.Title.Value, false);
58+ e.Column.SortDirection = DataGridSortDirection.Descending;
59+ }
60+ break;
61+
62+ case "Writer":
63+ if ((e.Column.SortDirection == null) || (direction == DataGridSortDirection.Descending))
64+ {
65+ this.ViewModel.SortByViewColumn(tag, r => r.Writer.Value, true);
66+ e.Column.SortDirection = DataGridSortDirection.Ascending;
67+ }
68+ else
69+ {
70+ this.ViewModel.SortByViewColumn(tag, r => r.Writer.Value, false);
71+ e.Column.SortDirection = DataGridSortDirection.Descending;
72+ }
73+ break;
74+
75+ case "End":
76+ if (direction == DataGridSortDirection.Ascending)
77+ {
78+ this.ViewModel.SortByViewColumn(tag, r => r.End.Value, false);
79+ e.Column.SortDirection = DataGridSortDirection.Descending;
80+ }
81+ else
82+ {
83+ this.ViewModel.SortByViewColumn(tag, r => r.End.Value, true);
84+ e.Column.SortDirection = DataGridSortDirection.Ascending;
85+ }
86+ break;
87+
88+ case "GeneralAllNo":
89+ if (direction == DataGridSortDirection.Ascending)
90+ {
91+ this.ViewModel.SortByViewColumn(tag, r => r.GeneralAllNo.Value, false);
92+ e.Column.SortDirection = DataGridSortDirection.Descending;
93+ }
94+ else
95+ {
96+ this.ViewModel.SortByViewColumn(tag, r => r.GeneralAllNo.Value, true);
97+ e.Column.SortDirection = DataGridSortDirection.Ascending;
98+ }
99+ break;
100+
101+ case "Time":
102+ if (direction == DataGridSortDirection.Ascending)
103+ {
104+ this.ViewModel.SortByViewColumn(tag, r => r.Time.Value, false);
105+ e.Column.SortDirection = DataGridSortDirection.Descending;
106+ }
107+ else
108+ {
109+ this.ViewModel.SortByViewColumn(tag, r => r.Time.Value, true);
110+ e.Column.SortDirection = DataGridSortDirection.Ascending;
111+ }
112+ break;
113+
114+ case "IsStop":
115+ if ((e.Column.SortDirection == null) || (direction == DataGridSortDirection.Descending))
116+ {
117+ this.ViewModel.SortByViewColumn(tag, r => r.IsStop.Value, true);
118+ e.Column.SortDirection = DataGridSortDirection.Ascending;
119+ }
120+ else
121+ {
122+ this.ViewModel.SortByViewColumn(tag, r => r.IsStop.Value, false);
123+ e.Column.SortDirection = DataGridSortDirection.Descending;
124+ }
125+ break;
126+
127+ case "GlobalPoint":
128+ if (direction == DataGridSortDirection.Ascending)
129+ {
130+ this.ViewModel.SortByViewColumn(tag, r => r.GlobalPoint.Value, false);
131+ e.Column.SortDirection = DataGridSortDirection.Descending;
132+ }
133+ else
134+ {
135+ this.ViewModel.SortByViewColumn(tag, r => r.GlobalPoint.Value, true);
136+ e.Column.SortDirection = DataGridSortDirection.Ascending;
137+ }
138+ break;
139+
140+ case "PointPerMin":
141+ if (direction == DataGridSortDirection.Ascending)
142+ {
143+ this.ViewModel.SortByViewColumn(tag, r => r.PointPerMin.Value, false);
144+ e.Column.SortDirection = DataGridSortDirection.Descending;
145+ }
146+ else
147+ {
148+ this.ViewModel.SortByViewColumn(tag, r => r.PointPerMin.Value, true);
149+ e.Column.SortDirection = DataGridSortDirection.Ascending;
150+ }
151+ break;
152+
153+ case "DailyPoint":
154+ if (direction == DataGridSortDirection.Ascending)
155+ {
156+ this.ViewModel.SortByViewColumn(tag, r => r.DailyPoint.Value, false);
157+ e.Column.SortDirection = DataGridSortDirection.Descending;
158+ }
159+ else
160+ {
161+ this.ViewModel.SortByViewColumn(tag, r => r.DailyPoint.Value, true);
162+ e.Column.SortDirection = DataGridSortDirection.Ascending;
163+ }
164+ break;
165+
166+ case "WeeklyPoint":
167+ if (direction == DataGridSortDirection.Ascending)
168+ {
169+ this.ViewModel.SortByViewColumn(tag, r => r.WeeklyPoint.Value, false);
170+ e.Column.SortDirection = DataGridSortDirection.Descending;
171+ }
172+ else
173+ {
174+ this.ViewModel.SortByViewColumn(tag, r => r.WeeklyPoint.Value, true);
175+ e.Column.SortDirection = DataGridSortDirection.Ascending;
176+ }
177+ break;
178+
179+ case "MonthlyPoint":
180+ if (direction == DataGridSortDirection.Ascending)
181+ {
182+ this.ViewModel.SortByViewColumn(tag, r => r.MonthlyPoint.Value, false);
183+ e.Column.SortDirection = DataGridSortDirection.Descending;
184+ }
185+ else
186+ {
187+ this.ViewModel.SortByViewColumn(tag, r => r.MonthlyPoint.Value, true);
188+ e.Column.SortDirection = DataGridSortDirection.Ascending;
189+ }
190+ break;
191+
192+ case "QuarterPoint":
193+ if (direction == DataGridSortDirection.Ascending)
194+ {
195+ this.ViewModel.SortByViewColumn(tag, r => r.QuarterPoint.Value, false);
196+ e.Column.SortDirection = DataGridSortDirection.Descending;
197+ }
198+ else
199+ {
200+ this.ViewModel.SortByViewColumn(tag, r => r.QuarterPoint.Value, true);
201+ e.Column.SortDirection = DataGridSortDirection.Ascending;
202+ }
203+ break;
204+
205+ case "YearlyPoint":
206+ if (direction == DataGridSortDirection.Ascending)
207+ {
208+ this.ViewModel.SortByViewColumn(tag, r => r.YearlyPoint.Value, false);
209+ e.Column.SortDirection = DataGridSortDirection.Descending;
210+ }
211+ else
212+ {
213+ this.ViewModel.SortByViewColumn(tag, r => r.YearlyPoint.Value, true);
214+ e.Column.SortDirection = DataGridSortDirection.Ascending;
215+ }
216+ break;
217+
218+ case "FavNovelCnt":
219+ if (direction == DataGridSortDirection.Ascending)
220+ {
221+ this.ViewModel.SortByViewColumn(tag, r => r.FavNovelCnt.Value, false);
222+ e.Column.SortDirection = DataGridSortDirection.Descending;
223+ }
224+ else
225+ {
226+ this.ViewModel.SortByViewColumn(tag, r => r.FavNovelCnt.Value, true);
227+ e.Column.SortDirection = DataGridSortDirection.Ascending;
228+ }
229+ break;
230+
231+ case "ImpressionCnt":
232+ if (direction == DataGridSortDirection.Ascending)
233+ {
234+ this.ViewModel.SortByViewColumn(tag, r => r.ImpressionCnt.Value, false);
235+ e.Column.SortDirection = DataGridSortDirection.Descending;
236+ }
237+ else
238+ {
239+ this.ViewModel.SortByViewColumn(tag, r => r.ImpressionCnt.Value, true);
240+ e.Column.SortDirection = DataGridSortDirection.Ascending;
241+ }
242+ break;
243+
244+ case "ReviewCnt":
245+ if (direction == DataGridSortDirection.Ascending)
246+ {
247+ this.ViewModel.SortByViewColumn(tag, r => r.ReviewCnt.Value, false);
248+ e.Column.SortDirection = DataGridSortDirection.Descending;
249+ }
250+ else
251+ {
252+ this.ViewModel.SortByViewColumn(tag, r => r.ReviewCnt.Value, true);
253+ e.Column.SortDirection = DataGridSortDirection.Ascending;
254+ }
255+ break;
256+
257+ case "AllPoint":
258+ if (direction == DataGridSortDirection.Ascending)
259+ {
260+ this.ViewModel.SortByViewColumn(tag, r => r.AllPoint.Value, false);
261+ e.Column.SortDirection = DataGridSortDirection.Descending;
262+ }
263+ else
264+ {
265+ this.ViewModel.SortByViewColumn(tag, r => r.AllPoint.Value, true);
266+ e.Column.SortDirection = DataGridSortDirection.Ascending;
267+ }
268+ break;
269+
270+ case "AllHyokaCnt":
271+ if (direction == DataGridSortDirection.Ascending)
272+ {
273+ this.ViewModel.SortByViewColumn(tag, r => r.AllHyokaCnt.Value, false);
274+ e.Column.SortDirection = DataGridSortDirection.Descending;
275+ }
276+ else
277+ {
278+ this.ViewModel.SortByViewColumn(tag, r => r.AllHyokaCnt.Value, true);
279+ e.Column.SortDirection = DataGridSortDirection.Ascending;
280+ }
281+ break;
282+
283+ case "GeneralLastUp":
284+ if (direction == DataGridSortDirection.Ascending)
285+ {
286+ this.ViewModel.SortByValueColumn(tag, r => r.GeneralLastUp.Value, false);
287+ e.Column.SortDirection = DataGridSortDirection.Descending;
288+ }
289+ else
290+ {
291+ this.ViewModel.SortByValueColumn(tag, r => r.GeneralLastUp.Value, true);
292+ e.Column.SortDirection = DataGridSortDirection.Ascending;
293+ }
294+ break;
295+
296+ case "GeneralFirstUp":
297+ if (direction == DataGridSortDirection.Ascending)
298+ {
299+ this.ViewModel.SortByValueColumn(tag, r => r.GeneralFirstUp.Value, false);
300+ e.Column.SortDirection = DataGridSortDirection.Descending;
301+ }
302+ else
303+ {
304+ this.ViewModel.SortByValueColumn(tag, r => r.GeneralFirstUp.Value, true);
305+ e.Column.SortDirection = DataGridSortDirection.Ascending;
306+ }
307+ break;
308+
309+ case "NovelUpdatedAt":
310+ if (direction == DataGridSortDirection.Ascending)
311+ {
312+ this.ViewModel.SortByValueColumn(tag, r => r.NovelUpdatedAt.Value, false);
313+ e.Column.SortDirection = DataGridSortDirection.Descending;
314+ }
315+ else
316+ {
317+ this.ViewModel.SortByValueColumn(tag, r => r.NovelUpdatedAt.Value, true);
318+ e.Column.SortDirection = DataGridSortDirection.Ascending;
319+ }
320+ break;
321+
322+ default:
323+ logger.Trace("OnSorting: column not sortable.");
324+ return;
325+ }
326+
327+ // Remove sorting indicators from other columns
328+ foreach (var dgColumn in dg.Columns)
329+ {
330+ if (dgColumn.Tag?.ToString() != tag)
331+ {
332+ dgColumn.SortDirection = null;
333+ }
334+ }
335+ }
32336 }
33337 }
--- a/TestNarou3.sln
+++ b/TestNarou3.sln
@@ -19,13 +19,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Prism.Unity.WinUI", "D:\Rep
1919 EndProject
2020 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CleanAuLait", "..\CleanAuLait\CleanAuLait.csproj", "{543C3E97-A0BC-4AC6-8780-701902406542}"
2121 EndProject
22-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CleanAuLait.Prism.WinUI3", "..\CleanAuLait.Prism.WinUI3\CleanAuLait.Prism.WinUI3.csproj", "{F804C913-6C3E-4116-82DB-24BFD501E397}"
22+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CleanAuLait.Prism.WinUI3", "..\CleanAuLait.Prism.WinUI3\CleanAuLait.Prism.WinUI3.csproj", "{F804C913-6C3E-4116-82DB-24BFD501E397}"
2323 EndProject
24-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestNarou3.10Domain", "TestNarou3.Domain\TestNarou3.10Domain.csproj", "{9D49E4D8-8D72-4273-8393-D39EB047E8EE}"
24+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestNarou3.10Domain", "TestNarou3.Domain\TestNarou3.10Domain.csproj", "{9D49E4D8-8D72-4273-8393-D39EB047E8EE}"
2525 EndProject
26-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ObservableCollections", "..\ObservableCollectionsMod\src\ObservableCollections\ObservableCollections.csproj", "{17A69251-440F-4665-ACD1-986351AC168E}"
26+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestNarou3.20UseCase", "TestNarou3.UseCase\TestNarou3.20UseCase.csproj", "{7A85A717-EFEF-4F87-A2BB-76D03F864287}"
2727 EndProject
28-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestNarou3.20UseCase", "TestNarou3.UseCase\TestNarou3.20UseCase.csproj", "{7A85A717-EFEF-4F87-A2BB-76D03F864287}"
28+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CleanAuLait.ObservableCollectionsMod", "..\CleanAuLait.ObservableCollectionsMod\CleanAuLait.ObservableCollectionsMod.csproj", "{B9BA0032-9C0E-4B3A-A646-8280D64EF45B}"
2929 EndProject
3030 Global
3131 GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -207,22 +207,6 @@ Global
207207 {9D49E4D8-8D72-4273-8393-D39EB047E8EE}.Release|x64.Build.0 = Release|Any CPU
208208 {9D49E4D8-8D72-4273-8393-D39EB047E8EE}.Release|x86.ActiveCfg = Release|Any CPU
209209 {9D49E4D8-8D72-4273-8393-D39EB047E8EE}.Release|x86.Build.0 = Release|Any CPU
210- {17A69251-440F-4665-ACD1-986351AC168E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
211- {17A69251-440F-4665-ACD1-986351AC168E}.Debug|Any CPU.Build.0 = Debug|Any CPU
212- {17A69251-440F-4665-ACD1-986351AC168E}.Debug|arm64.ActiveCfg = Debug|Any CPU
213- {17A69251-440F-4665-ACD1-986351AC168E}.Debug|arm64.Build.0 = Debug|Any CPU
214- {17A69251-440F-4665-ACD1-986351AC168E}.Debug|x64.ActiveCfg = Debug|Any CPU
215- {17A69251-440F-4665-ACD1-986351AC168E}.Debug|x64.Build.0 = Debug|Any CPU
216- {17A69251-440F-4665-ACD1-986351AC168E}.Debug|x86.ActiveCfg = Debug|Any CPU
217- {17A69251-440F-4665-ACD1-986351AC168E}.Debug|x86.Build.0 = Debug|Any CPU
218- {17A69251-440F-4665-ACD1-986351AC168E}.Release|Any CPU.ActiveCfg = Release|Any CPU
219- {17A69251-440F-4665-ACD1-986351AC168E}.Release|Any CPU.Build.0 = Release|Any CPU
220- {17A69251-440F-4665-ACD1-986351AC168E}.Release|arm64.ActiveCfg = Release|Any CPU
221- {17A69251-440F-4665-ACD1-986351AC168E}.Release|arm64.Build.0 = Release|Any CPU
222- {17A69251-440F-4665-ACD1-986351AC168E}.Release|x64.ActiveCfg = Release|Any CPU
223- {17A69251-440F-4665-ACD1-986351AC168E}.Release|x64.Build.0 = Release|Any CPU
224- {17A69251-440F-4665-ACD1-986351AC168E}.Release|x86.ActiveCfg = Release|Any CPU
225- {17A69251-440F-4665-ACD1-986351AC168E}.Release|x86.Build.0 = Release|Any CPU
226210 {7A85A717-EFEF-4F87-A2BB-76D03F864287}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
227211 {7A85A717-EFEF-4F87-A2BB-76D03F864287}.Debug|Any CPU.Build.0 = Debug|Any CPU
228212 {7A85A717-EFEF-4F87-A2BB-76D03F864287}.Debug|arm64.ActiveCfg = Debug|Any CPU
@@ -239,6 +223,22 @@ Global
239223 {7A85A717-EFEF-4F87-A2BB-76D03F864287}.Release|x64.Build.0 = Release|Any CPU
240224 {7A85A717-EFEF-4F87-A2BB-76D03F864287}.Release|x86.ActiveCfg = Release|Any CPU
241225 {7A85A717-EFEF-4F87-A2BB-76D03F864287}.Release|x86.Build.0 = Release|Any CPU
226+ {B9BA0032-9C0E-4B3A-A646-8280D64EF45B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
227+ {B9BA0032-9C0E-4B3A-A646-8280D64EF45B}.Debug|Any CPU.Build.0 = Debug|Any CPU
228+ {B9BA0032-9C0E-4B3A-A646-8280D64EF45B}.Debug|arm64.ActiveCfg = Debug|Any CPU
229+ {B9BA0032-9C0E-4B3A-A646-8280D64EF45B}.Debug|arm64.Build.0 = Debug|Any CPU
230+ {B9BA0032-9C0E-4B3A-A646-8280D64EF45B}.Debug|x64.ActiveCfg = Debug|Any CPU
231+ {B9BA0032-9C0E-4B3A-A646-8280D64EF45B}.Debug|x64.Build.0 = Debug|Any CPU
232+ {B9BA0032-9C0E-4B3A-A646-8280D64EF45B}.Debug|x86.ActiveCfg = Debug|Any CPU
233+ {B9BA0032-9C0E-4B3A-A646-8280D64EF45B}.Debug|x86.Build.0 = Debug|Any CPU
234+ {B9BA0032-9C0E-4B3A-A646-8280D64EF45B}.Release|Any CPU.ActiveCfg = Release|Any CPU
235+ {B9BA0032-9C0E-4B3A-A646-8280D64EF45B}.Release|Any CPU.Build.0 = Release|Any CPU
236+ {B9BA0032-9C0E-4B3A-A646-8280D64EF45B}.Release|arm64.ActiveCfg = Release|Any CPU
237+ {B9BA0032-9C0E-4B3A-A646-8280D64EF45B}.Release|arm64.Build.0 = Release|Any CPU
238+ {B9BA0032-9C0E-4B3A-A646-8280D64EF45B}.Release|x64.ActiveCfg = Release|Any CPU
239+ {B9BA0032-9C0E-4B3A-A646-8280D64EF45B}.Release|x64.Build.0 = Release|Any CPU
240+ {B9BA0032-9C0E-4B3A-A646-8280D64EF45B}.Release|x86.ActiveCfg = Release|Any CPU
241+ {B9BA0032-9C0E-4B3A-A646-8280D64EF45B}.Release|x86.Build.0 = Release|Any CPU
242242 EndGlobalSection
243243 GlobalSection(SolutionProperties) = preSolution
244244 HideSolutionNode = FALSE
--- a/TestNarou3/App.xaml.cs
+++ b/TestNarou3/App.xaml.cs
@@ -278,6 +278,11 @@ public partial class App : PrismApplication
278278 var vm = Container.Resolve<IMainWindowViewModel>();
279279 vm.OnClosing();
280280
281+ if (Container.GetContainer() is IDisposable disposable)
282+ {
283+ disposable.Dispose();
284+ }
285+
281286 LogManager.Shutdown();
282287 }
283288
--- a/TestNarou3/Properties/launchSettings.json
+++ b/TestNarou3/Properties/launchSettings.json
@@ -1,7 +1,8 @@
11 {
22 "profiles": {
33 "TestNarou3 (Package)": {
4- "commandName": "MsixPackage"
4+ "commandName": "MsixPackage",
5+ "nativeDebugging": false
56 },
67 "TestNarou3 (Unpackaged)": {
78 "commandName": "Project"