Skip to content

Commit e85f56e

Browse files
committed
Fix context menu bug and ui changes
1 parent 30e6b7a commit e85f56e

6 files changed

Lines changed: 84 additions & 10 deletions

File tree

AutoMidiPlayer.WPF/AutoMidiPlayer.WPF.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<UseWPF>true</UseWPF>
77
<StartupObject>AutoMidiPlayer.WPF.App</StartupObject>
88
<ApplicationManifest>app.manifest</ApplicationManifest>
9-
<Version>5.9.3</Version>
9+
<Version>5.9.5</Version>
1010
<ApplicationIcon>item_windsong_lyre.ico</ApplicationIcon>
1111
<Nullable>enable</Nullable>
1212
<RepositoryUrl>https://github.com/Jed556/AutoMidiPlayer</RepositoryUrl>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System.Windows;
2+
3+
namespace AutoMidiPlayer.WPF.ModernWPF;
4+
5+
/// <summary>
6+
/// A proxy class that allows binding to the DataContext from elements
7+
/// that are not part of the visual tree (like ContextMenus in NotifyIcon).
8+
/// </summary>
9+
public class BindingProxy : Freezable
10+
{
11+
public static readonly DependencyProperty DataProperty =
12+
DependencyProperty.Register(nameof(Data), typeof(object), typeof(BindingProxy),
13+
new PropertyMetadata(null));
14+
15+
public object? Data
16+
{
17+
get => GetValue(DataProperty);
18+
set => SetValue(DataProperty, value);
19+
}
20+
21+
protected override Freezable CreateInstanceCore()
22+
{
23+
return new BindingProxy();
24+
}
25+
}

AutoMidiPlayer.WPF/ViewModels/QueueViewModel.cs

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,12 @@ private void OnTrackViewPropertyChanged(object? sender, System.ComponentModel.Pr
6060
}
6161
}
6262

63-
public BindableCollection<MidiFile> FilteredTracks => string.IsNullOrWhiteSpace(FilterText)
64-
? Tracks
65-
: new(Tracks.Where(t => t.Title.Contains(FilterText, StringComparison.OrdinalIgnoreCase)));
63+
private BindableCollection<MidiFile> _filteredTracks = new();
64+
public BindableCollection<MidiFile> FilteredTracks
65+
{
66+
get => _filteredTracks;
67+
private set => SetAndNotify(ref _filteredTracks, value);
68+
}
6669

6770
public BindableCollection<MidiFile> Tracks { get; } = new();
6871

@@ -184,12 +187,12 @@ public async void PlayPauseFromQueue(MidiFile? file)
184187
public void ClearQueue()
185188
{
186189
Tracks.Clear();
187-
FilteredTracks.Clear();
188190
History.Clear();
189191

190192
OpenedFile = null;
191193
SelectedFile = null;
192194
SaveQueue();
195+
ApplyFilter();
193196
}
194197

195198
public void RemoveTrack()
@@ -359,6 +362,7 @@ public void RestoreQueue(IEnumerable<MidiFile> availableTracks)
359362
ShuffledTracks = new(Tracks.OrderBy(_ => Guid.NewGuid()));
360363

361364
RefreshQueue();
365+
ApplyFilter();
362366
}
363367

364368
/// <summary>
@@ -431,6 +435,7 @@ public void OnQueueModified()
431435
{
432436
SaveQueue();
433437
RefreshQueue();
438+
ApplyFilter();
434439
}
435440

436441
private void RefreshQueue()
@@ -442,15 +447,40 @@ private void RefreshQueue()
442447
}
443448
}
444449

450+
/// <summary>
451+
/// Apply filter to create a new FilteredTracks collection
452+
/// </summary>
453+
public void ApplyFilter()
454+
{
455+
IEnumerable<MidiFile> filtered = string.IsNullOrWhiteSpace(FilterText)
456+
? Tracks
457+
: Tracks.Where(t => t.Title.Contains(FilterText, StringComparison.OrdinalIgnoreCase));
458+
459+
FilteredTracks = new BindableCollection<MidiFile>(filtered);
460+
}
461+
462+
/// <summary>
463+
/// Called by PropertyChanged.Fody when FilterText changes
464+
/// </summary>
465+
private void OnFilterTextChanged() => ApplyFilter();
466+
445467
/// <summary>
446468
/// Refresh the currently playing song in the list to reflect property changes
447469
/// </summary>
448470
public void RefreshCurrentSong()
449471
{
450-
// Force UI to refresh by notifying FilteredTracks changed
472+
// Force UI to refresh by recreating the filtered collection
473+
// This ensures the ListView re-renders items when Song properties change
451474
System.Windows.Application.Current?.Dispatcher?.BeginInvoke(() =>
452475
{
453-
NotifyOfPropertyChange(nameof(FilteredTracks));
476+
ApplyFilter();
454477
});
455478
}
479+
480+
protected override void OnDeactivate()
481+
{
482+
base.OnDeactivate();
483+
// Clear the semi-active (single-clicked) row when switching tabs
484+
SelectedFile = null;
485+
}
456486
}

AutoMidiPlayer.WPF/ViewModels/SongsViewModel.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,4 +445,11 @@ public void RefreshCurrentSong()
445445
// Force a complete list refresh to show updated values
446446
ApplySort();
447447
}
448+
449+
protected override void OnDeactivate()
450+
{
451+
base.OnDeactivate();
452+
// Clear the semi-active (single-clicked) row when switching tabs
453+
SelectedFile = null;
454+
}
448455
}

AutoMidiPlayer.WPF/ViewModels/TrackViewModel.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,11 @@ public async Task PlayPause()
303303
if (Playback is null)
304304
await InitializePlayback();
305305

306-
if (Playback!.IsRunning)
306+
// If still null (no file opened), do nothing
307+
if (Playback is null)
308+
return;
309+
310+
if (Playback.IsRunning)
307311
{
308312
Playback.Stop();
309313
// Save position on pause

AutoMidiPlayer.WPF/Views/MainWindowView.xaml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
xmlns:viewModels="clr-namespace:AutoMidiPlayer.WPF.ViewModels"
1414
xmlns:core="clr-namespace:AutoMidiPlayer.WPF.Core"
1515
d:DataContext="{d:DesignInstance Type=viewModels:MainWindowViewModel}"
16+
x:Name="MainWindow"
1617
Title="{Binding Title}"
1718
Height="650"
1819
Width="1000"
@@ -24,6 +25,11 @@
2425
WindowCornerPreference="Round"
2526
WindowStartupLocation="CenterScreen">
2627

28+
<ui:UiWindow.Resources>
29+
<modernWpf:BindingProxy x:Key="DataContextProxy"
30+
Data="{Binding}"/>
31+
</ui:UiWindow.Resources>
32+
2733
<Grid AllowDrop="True"
2834
Drop="{s:Action OnFileDrop}"
2935
DragOver="{s:Action OnDragOver}"
@@ -54,10 +60,12 @@
5460
TooltipText="MIDI Player">
5561
<ui:NotifyIcon.Menu>
5662
<ContextMenu>
57-
<ui:MenuItem Command="{s:Action PlayPause, Target=TrackView}"
63+
<ui:MenuItem s:View.ActionTarget="{Binding Data.TrackView, Source={StaticResource DataContextProxy}}"
64+
Command="{s:Action PlayPause}"
5865
Header="Play"
5966
SymbolIcon="Play16"/>
60-
<ui:MenuItem Command="{s:Action Next, Target=TrackView}"
67+
<ui:MenuItem s:View.ActionTarget="{Binding Data.TrackView, Source={StaticResource DataContextProxy}}"
68+
Command="{s:Action Next}"
6169
Header="Next"
6270
SymbolIcon="Next16"/>
6371
</ContextMenu>

0 commit comments

Comments
 (0)