From fe756648de363eb91d95658800821eab92b9e679 Mon Sep 17 00:00:00 2001 From: Valdimir Date: Sun, 28 Jan 2024 23:10:11 +0200 Subject: [PATCH] listview drag --- TV Player WPF/App.xaml.cs | 13 +- TV Player WPF/Assets/GroupButtonStyle.xaml | 26 +++- TV Player WPF/ProgramsList.xaml | 13 +- TV Player WPF/ProgramsList.xaml.cs | 120 +++++++++++++++++- TV Player WPF/ViewModels/TVPlayerViewModel.cs | 7 +- 5 files changed, 164 insertions(+), 15 deletions(-) diff --git a/TV Player WPF/App.xaml.cs b/TV Player WPF/App.xaml.cs index a67111b..e934073 100644 --- a/TV Player WPF/App.xaml.cs +++ b/TV Player WPF/App.xaml.cs @@ -1,5 +1,4 @@ using System.Windows; -using System.Windows.Controls.Primitives; using TV_Player.ViewModels; namespace TV_Player @@ -10,13 +9,13 @@ namespace TV_Player public partial class App : Application { private TVPlayerViewModel _tvPlayer; - - private const string Guid = "250C5597-BA73-40DF-B2CF-DD644F044834"; + + private const string Guid = "ac8ab758-01e2-47c3-ad42-31e96d8203c0"; static readonly Mutex Mutex = new Mutex(true, "{" + Guid + "}"); protected override void OnStartup(StartupEventArgs e) { AppDomain.CurrentDomain.UnhandledException += ReportAndRestart; - + if (!Mutex.WaitOne(TimeSpan.Zero, true)) { MessageBox.Show("Programm already running"); @@ -32,13 +31,13 @@ namespace TV_Player { string info = e.ExceptionObject.ToString(); - MessageBox.Show(info,"Application"); + var result=MessageBox.Show(info, "Application", MessageBoxButton.OK, MessageBoxImage.Stop); - Environment.Exit(1); + //Environment.Exit(1); } protected override void OnExit(ExitEventArgs e) { - _tvPlayer = null; + _tvPlayer.Dispose(); base.OnExit(e); } } diff --git a/TV Player WPF/Assets/GroupButtonStyle.xaml b/TV Player WPF/Assets/GroupButtonStyle.xaml index 8ce8bfb..0972b13 100644 --- a/TV Player WPF/Assets/GroupButtonStyle.xaml +++ b/TV Player WPF/Assets/GroupButtonStyle.xaml @@ -68,7 +68,7 @@ c-0.781-0.781-0.788-2.047-0.007-2.828L51.438,14.43c1.754-1.755,1.753-4.61-0.001- - + + + + \ No newline at end of file diff --git a/TV Player WPF/ProgramsList.xaml b/TV Player WPF/ProgramsList.xaml index 0dd2ef8..df0e09a 100644 --- a/TV Player WPF/ProgramsList.xaml +++ b/TV Player WPF/ProgramsList.xaml @@ -6,9 +6,12 @@ mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> - @@ -18,7 +21,7 @@ - + @@ -31,6 +34,12 @@ + + + + + + diff --git a/TV Player WPF/ProgramsList.xaml.cs b/TV Player WPF/ProgramsList.xaml.cs index a34a823..07a2298 100644 --- a/TV Player WPF/ProgramsList.xaml.cs +++ b/TV Player WPF/ProgramsList.xaml.cs @@ -1,4 +1,8 @@ -using System.Windows.Controls; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Threading; namespace TV_Player { @@ -7,16 +11,128 @@ namespace TV_Player /// public partial class ProgramsList : UserControl { + private Point _mousePosition; + private bool _isDragging; + private DispatcherTimer clickTimer; + public ProgramsList() { InitializeComponent(); + clickTimer = new DispatcherTimer(); + clickTimer.Interval = TimeSpan.FromMilliseconds(200); // Adjust the interval as needed + clickTimer.Tick += ClickTimer_Tick; } + private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { - if (DataContext is ProgramsListViewModel viewModel) + if (_isDragging) + { + e.Handled = true; // Prevent selection change during drag-and-drop + } + else if (DataContext is ProgramsListViewModel viewModel) { viewModel.ItemSelectedCommand.Execute(null); } } + + private void ListView_PreviewMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e) + { + _isDragging = true; + _mousePosition = e.GetPosition(null); + } + + private void ListView_MouseMove(object sender, System.Windows.Input.MouseEventArgs e) + { + if (e.LeftButton == MouseButtonState.Pressed) + { + Point currentPosition = e.GetPosition(null); + + if (!_isDragging && (Math.Abs(currentPosition.X - _mousePosition.X) > SystemParameters.MinimumHorizontalDragDistance || + Math.Abs(currentPosition.Y - _mousePosition.Y) > SystemParameters.MinimumVerticalDragDistance)) + { + _isDragging = true; + e.Handled = true; + } + + if (_isDragging) + { + // Get the ListView scroll viewer + ScrollViewer scrollViewer = FindVisualChild(programsList); + + if (scrollViewer != null) + { + double verticalScrollPosition = currentPosition.Y - _mousePosition.Y; + scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset - verticalScrollPosition); + } + } + } + } + + private void ListView_PreviewMouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e) + { + _isDragging = false; + clickTimer.Stop(); + + if (IsClick()) + { + // Perform selection logic here + ListViewItem listViewItem = FindAncestor((DependencyObject)e.OriginalSource); + if (listViewItem != null) + { + listViewItem.IsSelected = true; + if (DataContext is ProgramsListViewModel viewModel) + { + viewModel.ItemSelectedCommand.Execute(null); + } + } + } + } + + private void ClickTimer_Tick(object sender, EventArgs e) + { + clickTimer.Stop(); + } + + private bool IsClick() + { + Point currentPosition = Mouse.GetPosition(null); + return Math.Abs(currentPosition.X - _mousePosition.X) < SystemParameters.MinimumHorizontalDragDistance && + Math.Abs(currentPosition.Y - _mousePosition.Y) < SystemParameters.MinimumVerticalDragDistance; + } + + private static T FindVisualChild(DependencyObject obj) where T : DependencyObject + { + for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++) + { + DependencyObject child = VisualTreeHelper.GetChild(obj, i); + if (child != null && child is T) + { + return (T)child; + } + else + { + T childOfChild = FindVisualChild(child); + if (childOfChild != null) + { + return childOfChild; + } + } + } + return null; + } + + private static T FindAncestor(DependencyObject current) where T : DependencyObject + { + do + { + if (current is T ancestor) + { + return ancestor; + } + current = VisualTreeHelper.GetParent(current); + } while (current != null); + + return null; + } } } diff --git a/TV Player WPF/ViewModels/TVPlayerViewModel.cs b/TV Player WPF/ViewModels/TVPlayerViewModel.cs index db9cfbe..76bd9f7 100644 --- a/TV Player WPF/ViewModels/TVPlayerViewModel.cs +++ b/TV Player WPF/ViewModels/TVPlayerViewModel.cs @@ -2,7 +2,7 @@ namespace TV_Player.ViewModels { - public class TVPlayerViewModel + public class TVPlayerViewModel : IDisposable { private readonly MainViewModel _mainViewModel; @@ -66,5 +66,10 @@ namespace TV_Player.ViewModels _mainViewModel.Control = control; } + public void Dispose() + { + if (_mainViewModel.Control is IDisposable disposable) + disposable.Dispose(); + } } }