Skip to content

Commit a0eccec

Browse files
committed
refactor: Move ListView sort logic to behavior class
Moved ListView sorting logic from code-behind to a new behavior class `ListViewClickSortBehavior`.
1 parent cb051e5 commit a0eccec

File tree

5 files changed

+91
-136
lines changed

5 files changed

+91
-136
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
using System.Windows.Controls.Primitives;
2+
using FoliCon.Modules.utils;
3+
4+
namespace FoliCon.Modules.UI;
5+
6+
public class ListViewClickSortBehavior : Behavior<ListView>
7+
{
8+
private GridViewColumnHeader _lastHeaderClicked;
9+
private ListSortDirection _lastDirection = ListSortDirection.Ascending;
10+
11+
protected override void OnAttached()
12+
{
13+
base.OnAttached();
14+
15+
AssociatedObject.AddHandler(ButtonBase.ClickEvent, new RoutedEventHandler(OnClick));
16+
((INotifyCollectionChanged) AssociatedObject.Items).CollectionChanged += ListView_CollectionChanged;
17+
}
18+
19+
protected override void OnDetaching()
20+
{
21+
base.OnDetaching();
22+
23+
AssociatedObject.RemoveHandler(ButtonBase.ClickEvent, new RoutedEventHandler(OnClick));
24+
((INotifyCollectionChanged) AssociatedObject.Items).CollectionChanged -= ListView_CollectionChanged;
25+
}
26+
27+
private void ListView_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
28+
{
29+
if (e.Action == NotifyCollectionChangedAction.Reset)
30+
{
31+
UiUtils.SetColumnWidth(AssociatedObject);
32+
}
33+
}
34+
35+
private void OnClick(object sender, RoutedEventArgs e)
36+
{
37+
if (e.OriginalSource is not GridViewColumnHeader headerClicked) return;
38+
if (headerClicked.Role == GridViewColumnHeaderRole.Padding) return;
39+
40+
ListSortDirection direction;
41+
if (headerClicked != _lastHeaderClicked)
42+
{
43+
direction = ListSortDirection.Ascending;
44+
}
45+
else
46+
{
47+
direction = _lastDirection == ListSortDirection.Ascending
48+
? ListSortDirection.Descending
49+
: ListSortDirection.Ascending;
50+
}
51+
52+
var header = headerClicked.Column.Header as string;
53+
Sort(header, direction);
54+
55+
headerClicked.Column.HeaderTemplate = direction == ListSortDirection.Ascending
56+
? Application.Current.Resources["HeaderTemplateArrowUp"] as DataTemplate
57+
: Application.Current.Resources["HeaderTemplateArrowDown"] as DataTemplate;
58+
59+
// Remove arrow from previously sorted header
60+
if (_lastHeaderClicked != null && _lastHeaderClicked != headerClicked)
61+
{
62+
_lastHeaderClicked.Column.HeaderTemplate = null;
63+
}
64+
65+
_lastHeaderClicked = headerClicked;
66+
_lastDirection = direction;
67+
}
68+
69+
private void Sort(string sortBy, ListSortDirection direction)
70+
{
71+
var dataView = CollectionViewSource.GetDefaultView(AssociatedObject.ItemsSource);
72+
dataView.SortDescriptions.Clear();
73+
var sd = new SortDescription(sortBy, direction);
74+
dataView.SortDescriptions.Add(sd);
75+
dataView.Refresh();
76+
}
77+
}

FoliCon/Views/MainWindow.xaml

+5-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
xmlns:extension="clr-namespace:FoliCon.Modules.Extension"
1212
xmlns:ui="clr-namespace:FoliCon.Modules.UI"
1313
xmlns:enums="clr-namespace:FoliCon.Models.Enums"
14+
xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
1415
mc:Ignorable="d"
1516
prism:ViewModelLocator.AutoWireViewModel="True"
1617
Title="{Binding Title}" Height="714" Width="851" MinWidth="850" MinHeight="630"
@@ -243,12 +244,15 @@
243244
<ListView x:Name="FinalList" Grid.Row="3" Grid.ColumnSpan="2" Grid.Column="0"
244245
ItemsSource="{Binding FinalListViewData.Data}"
245246
SelectedItem="{Binding FinalListViewData.SelectedItem}"
246-
hc:Empty.ShowEmpty="true" GridViewColumnHeader.Click="FinalList_OnClick" >
247+
hc:Empty.ShowEmpty="true">
247248
<hc:Interaction.Triggers>
248249
<hc:EventTrigger EventName="MouseDoubleClick">
249250
<hc:LaunchUriOrFileAction Path="{Binding FinalListViewData.SelectedItem.Folder}" />
250251
</hc:EventTrigger>
251252
</hc:Interaction.Triggers>
253+
<b:Interaction.Behaviors>
254+
<ui:ListViewClickSortBehavior/>
255+
</b:Interaction.Behaviors>
252256
<ListView.View>
253257
<GridView>
254258
<GridViewColumn Header="{extension:Lang Key={x:Static langs:LangKeys.Title}}" Width="Auto" DisplayMemberBinding="{Binding Title}" />

FoliCon/Views/MainWindow.xaml.cs

+1-64
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,11 @@ namespace FoliCon.Views;
88
/// </summary>
99
public partial class MainWindow
1010
{
11-
private GridViewColumnHeader _lastHeaderClicked;
12-
private ListSortDirection _lastDirection = ListSortDirection.Ascending;
1311
public MainWindow()
1412
{
1513
InitializeComponent();
16-
((INotifyCollectionChanged)FinalList.Items).CollectionChanged += ListView_CollectionChanged;
17-
}
18-
19-
private void ListView_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
20-
{
21-
22-
if (e.Action == NotifyCollectionChangedAction.Reset)
23-
{
24-
UiUtils.SetColumnWidth(FinalList);
25-
}
2614
}
15+
2716

2817
private void CmbLanguage_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
2918
{
@@ -46,58 +35,6 @@ private void CmbLanguage_OnSelectionChanged(object sender, SelectionChangedEvent
4635

4736
}
4837

49-
private void FinalList_OnClick(object sender, RoutedEventArgs e)
50-
{
51-
if (e.OriginalSource is not GridViewColumnHeader headerClicked)
52-
{
53-
return;
54-
}
55-
56-
if (headerClicked.Role == GridViewColumnHeaderRole.Padding)
57-
{
58-
return;
59-
}
60-
61-
ListSortDirection direction;
62-
if (headerClicked != _lastHeaderClicked)
63-
{
64-
direction = ListSortDirection.Ascending;
65-
}
66-
else
67-
{
68-
direction = _lastDirection == ListSortDirection.Ascending
69-
? ListSortDirection.Descending
70-
: ListSortDirection.Ascending;
71-
}
72-
73-
var header = headerClicked.Column.Header as string;
74-
Sort(header, direction);
75-
76-
headerClicked.Column.HeaderTemplate = direction == ListSortDirection.Ascending
77-
? Application.Current.Resources["HeaderTemplateArrowUp"] as DataTemplate
78-
: Application.Current.Resources["HeaderTemplateArrowDown"] as DataTemplate;
79-
80-
// Remove arrow from previously sorted header
81-
if (_lastHeaderClicked != null && _lastHeaderClicked != headerClicked)
82-
{
83-
_lastHeaderClicked.Column.HeaderTemplate = null;
84-
}
85-
86-
87-
_lastHeaderClicked = headerClicked;
88-
_lastDirection = direction;
89-
}
90-
private void Sort(string sortBy, ListSortDirection direction)
91-
{
92-
var dataView =
93-
CollectionViewSource.GetDefaultView(FinalList.ItemsSource);
94-
95-
dataView.SortDescriptions.Clear();
96-
var sd = new SortDescription(sortBy, direction);
97-
dataView.SortDescriptions.Add(sd);
98-
dataView.Refresh();
99-
}
100-
10138
private void MainWindow_OnClosed(object sender, EventArgs e)
10239
{
10340
FileUtils.DeleteFoliConTempDeviationDirectory();

FoliCon/Views/SearchResult.xaml

+5-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
xmlns:convertor="clr-namespace:FoliCon.Modules.Convertor"
1212
xmlns:extension="clr-namespace:FoliCon.Modules.Extension"
1313
xmlns:data="clr-namespace:FoliCon.Models.Data"
14+
xmlns:ui="clr-namespace:FoliCon.Modules.UI"
1415
mc:Ignorable="d"
1516
prism:ViewModelLocator.AutoWireViewModel="True"
1617
d:DataContext="{d:DesignInstance viewModels:SearchResultViewModel }" Unloaded="UserControl_Unloaded" Background="{DynamicResource RegionBrush}">
@@ -54,7 +55,7 @@
5455
<Button Content="{extension:Lang Key={x:Static langs:LangKeys.Skip}}" HorizontalAlignment="Right" VerticalAlignment="Top" Grid.Row="0" Style="{StaticResource ButtonDanger}"
5556
Command="{Binding SkipCommand}" IsCancel="True" ToolTip="{extension:Lang Key={x:Static langs:LangKeys.SkipThisTitle}}" />
5657
<ListView x:Name="ListViewResult" ItemsSource="{Binding ResultListViewData.Data}" Background="{DynamicResource PrimaryRegionBrush}"
57-
SelectedItem="{Binding ResultListViewData.SelectedItem}" IsSynchronizedWithCurrentItem="True" Grid.Row="1" hc:Empty.ShowEmpty="true" GridViewColumnHeader.Click="ListViewResult_OnClick">
58+
SelectedItem="{Binding ResultListViewData.SelectedItem}" IsSynchronizedWithCurrentItem="True" Grid.Row="1" hc:Empty.ShowEmpty="true">
5859
<hc:Interaction.Triggers>
5960
<hc:EventTrigger EventName="MouseDoubleClick">
6061
<hc:EventToCommand Command="{Binding PickCommand}" PassEventArgsToCommand="True"/>
@@ -63,6 +64,9 @@
6364
<hc:EventToCommand Command="{Binding SelectionChanged}" PassEventArgsToCommand="True" />
6465
</hc:EventTrigger>
6566
</hc:Interaction.Triggers>
67+
<i:Interaction.Behaviors>
68+
<ui:ListViewClickSortBehavior/>
69+
</i:Interaction.Behaviors>
6670
<ListView.View>
6771
<GridView>
6872
<GridViewColumn DisplayMemberBinding="{Binding Title}" Width="auto" Header="{extension:Lang Key={x:Static langs:LangKeys.Title}}"/>

FoliCon/Views/SearchResult.xaml.cs

+3-70
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,17 @@
1-
using FoliCon.Modules.utils;
2-
3-
namespace FoliCon.Views;
1+
namespace FoliCon.Views;
42

53
/// <summary>
64
/// Interaction logic for SearchResult
75
/// </summary>
86
public partial class SearchResult
97
{
10-
private GridViewColumnHeader _lastHeaderClicked;
11-
private ListSortDirection _lastDirection = ListSortDirection.Ascending;
12-
138
public SearchResult()
149
{
1510
InitializeComponent();
16-
((INotifyCollectionChanged)ListViewResult.Items).CollectionChanged += ListView_CollectionChanged;
17-
}
18-
19-
private void ListView_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
20-
{
21-
if (e.Action == NotifyCollectionChangedAction.Reset)
22-
{
23-
UiUtils.SetColumnWidth(ListViewResult);
24-
}
2511
}
2612

27-
private void ListViewResult_OnClick(object sender, RoutedEventArgs e)
13+
private void UserControl_Unloaded(object sender, RoutedEventArgs e)
2814
{
29-
if (e.OriginalSource is not GridViewColumnHeader headerClicked)
30-
{
31-
return;
32-
}
33-
34-
if (headerClicked.Role == GridViewColumnHeaderRole.Padding)
35-
{
36-
return;
37-
}
38-
39-
ListSortDirection direction;
40-
if (headerClicked != _lastHeaderClicked)
41-
{
42-
direction = ListSortDirection.Ascending;
43-
}
44-
else
45-
{
46-
direction = _lastDirection == ListSortDirection.Ascending
47-
? ListSortDirection.Descending
48-
: ListSortDirection.Ascending;
49-
}
50-
51-
var header = headerClicked.Column.Header as string;
52-
Sort(header, direction);
53-
54-
headerClicked.Column.HeaderTemplate = direction == ListSortDirection.Ascending
55-
? Application.Current.Resources["HeaderTemplateArrowUp"] as DataTemplate
56-
: Application.Current.Resources["HeaderTemplateArrowDown"] as DataTemplate;
57-
58-
// Remove arrow from previously sorted header
59-
if (_lastHeaderClicked != null && _lastHeaderClicked != headerClicked)
60-
{
61-
_lastHeaderClicked.Column.HeaderTemplate = null;
62-
}
63-
64-
65-
_lastHeaderClicked = headerClicked;
66-
_lastDirection = direction;
15+
WebBox.Browser.Dispose();
6716
}
68-
69-
private void Sort(string sortBy, ListSortDirection direction)
70-
{
71-
var dataView =
72-
CollectionViewSource.GetDefaultView(ListViewResult.ItemsSource);
73-
74-
dataView.SortDescriptions.Clear();
75-
var sd = new SortDescription(sortBy, direction);
76-
dataView.SortDescriptions.Add(sd);
77-
dataView.Refresh();
78-
}
79-
80-
private void UserControl_Unloaded(object sender, RoutedEventArgs e)
81-
{
82-
WebBox.Browser.Dispose();
83-
}
8417
}

0 commit comments

Comments
 (0)