Skip to content

Commit 60f3dd0

Browse files
committed
Fix issues when copying hits in native client
Closes #1082
1 parent 644e146 commit 60f3dd0

4 files changed

Lines changed: 91 additions & 5 deletions

File tree

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
using OpenBullet2.Native.Extensions;
2+
using System.Collections.ObjectModel;
3+
using System.Windows.Controls;
4+
5+
namespace OpenBullet2.Native.Tests;
6+
7+
[Collection("WPF")]
8+
public sealed class ListBoxExtensionsTests(WpfAppFixture fixture)
9+
{
10+
[Fact]
11+
public async Task GetSelectedItemsInDisplayOrder_ReturnsItemsInVisibleOrder()
12+
{
13+
await fixture.InvokeAsync(_ =>
14+
{
15+
var items = new[]
16+
{
17+
new TestItem("first"),
18+
new TestItem("second"),
19+
new TestItem("third")
20+
};
21+
22+
var listView = new ListView
23+
{
24+
SelectionMode = SelectionMode.Extended,
25+
ItemsSource = items
26+
};
27+
28+
listView.SelectedItems.Add(items[2]);
29+
listView.SelectedItems.Add(items[0]);
30+
31+
var selected = listView.GetSelectedItemsInDisplayOrder<TestItem>();
32+
33+
Assert.Equal([items[0], items[2]], selected);
34+
});
35+
}
36+
37+
[Fact]
38+
public async Task GetSelectedItemsInDisplayOrder_ExcludesItemsNoLongerInTheList()
39+
{
40+
await fixture.InvokeAsync(_ =>
41+
{
42+
var items = new ObservableCollection<TestItem>
43+
{
44+
new("first"),
45+
new("second"),
46+
new("third")
47+
};
48+
49+
var listView = new ListView
50+
{
51+
SelectionMode = SelectionMode.Extended,
52+
ItemsSource = items
53+
};
54+
55+
listView.SelectedItems.Add(items[1]);
56+
items.RemoveAt(1);
57+
58+
var selected = listView.GetSelectedItemsInDisplayOrder<TestItem>();
59+
60+
Assert.Empty(selected);
61+
});
62+
}
63+
64+
private sealed record TestItem(string Value);
65+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
using System.Windows.Controls;
4+
5+
namespace OpenBullet2.Native.Extensions;
6+
7+
public static class ListBoxExtensions
8+
{
9+
public static List<T> GetSelectedItemsInDisplayOrder<T>(this ListBox listBox)
10+
{
11+
if (listBox.SelectedItems.Count == 0)
12+
{
13+
return [];
14+
}
15+
16+
var selectedItems = listBox.SelectedItems.Cast<object>().ToHashSet();
17+
18+
return listBox.Items
19+
.Cast<object>()
20+
.Where(selectedItems.Contains)
21+
.Cast<T>()
22+
.ToList();
23+
}
24+
}

OpenBullet2.Native/Views/Pages/Hits.xaml.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,7 @@ public partial class Hits : Page
3535
private GridViewColumnHeader? listViewSortCol;
3636
private SortAdorner? listViewSortAdorner;
3737

38-
private IEnumerable<HitEntity> SelectedHits => hitsListView.SelectedItems
39-
.Cast<HitEntity>()
40-
.OrderBy(hit => hitsListView.Items.IndexOf(hit))
41-
.ToList();
38+
private IEnumerable<HitEntity> SelectedHits => hitsListView.GetSelectedItemsInDisplayOrder<HitEntity>();
4239

4340
private readonly Func<HitEntity, string> captureMapping = new(hit => $"{hit.Data} | {hit.CapturedData}");
4441
private readonly Func<HitEntity, string> fullMapping = new(hit =>

OpenBullet2.Native/Views/Pages/MultiRunJobViewer.xaml.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public partial class MultiRunJobViewer : Page
3131
private GridViewColumnHeader? listViewSortCol;
3232
private SortAdorner? listViewSortAdorner;
3333

34-
private IEnumerable<HitViewModel> SelectedHits => hitsListView.SelectedItems.Cast<HitViewModel>().ToList();
34+
private IEnumerable<HitViewModel> SelectedHits => hitsListView.GetSelectedItemsInDisplayOrder<HitViewModel>();
3535
private MultiRunJobViewerViewModel ViewModel => vm
3636
?? throw new InvalidOperationException("The job viewer has not been bound yet");
3737

0 commit comments

Comments
 (0)