using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Markup; using System.Windows.Shapes; using System.Windows.Threading; using Tango.Core.Threading; namespace Tango.Touch.Controls { [ContentProperty(nameof(Content))] public class TouchVirtualizedContentControl : Control { private LightTouchScrollViewer _scrollViewer; private ContentPresenter _innerBorder; private ActionTimer _updateTimer; private Point _location; private bool _loaded; public UIElement Content { get { return (UIElement)GetValue(ContentProperty); } set { SetValue(ContentProperty, value); } } public static readonly DependencyProperty ContentProperty = DependencyProperty.Register("Content", typeof(UIElement), typeof(TouchVirtualizedContentControl), new PropertyMetadata(null)); public bool CanMovePosition { get { return (bool)GetValue(CanMovePositionProperty); } set { SetValue(CanMovePositionProperty, value); } } public static readonly DependencyProperty CanMovePositionProperty = DependencyProperty.Register("CanMovePosition", typeof(bool), typeof(TouchVirtualizedContentControl), new PropertyMetadata(false)); public LightTouchDataGrid DataGrid { get { return (LightTouchDataGrid)GetValue(DataGridProperty); } set { SetValue(DataGridProperty, value); } } public static readonly DependencyProperty DataGridProperty = DependencyProperty.Register("DataGrid", typeof(LightTouchDataGrid), typeof(TouchVirtualizedContentControl), new PropertyMetadata(null)); static TouchVirtualizedContentControl() { DefaultStyleKeyProperty.OverrideMetadata(typeof(TouchVirtualizedContentControl), new FrameworkPropertyMetadata(typeof(TouchVirtualizedContentControl))); } public TouchVirtualizedContentControl() { _updateTimer = new ActionTimer(TimeSpan.FromMilliseconds(100)); Loaded += TouchVirtualizedContentControl_Loaded; } public override void OnApplyTemplate() { base.OnApplyTemplate(); _innerBorder = GetTemplateChild("PART_innerBorder") as ContentPresenter; } private void TouchVirtualizedContentControl_Loaded(object sender, System.Windows.RoutedEventArgs e) { _scrollViewer = this.FindAncestor(); _scrollViewer.Scrolling += _scrollViewer_Scrolling; if (DataGrid != null) { DataGrid.SortingChanged += DataGrid_SortingChanged; DataGrid.FilterChanged += DataGrid_FilterChanged; } _location = this.TranslatePoint(new Point(0, 0), _scrollViewer.GetContentGrid()); _scrollViewer.GetContentGrid().SizeChanged += TouchVirtualizedContentControl_SizeChanged; ApplyVirtualization(); _loaded = true; } private void DataGrid_FilterChanged(object sender, EventArgs e) { InvalidateVirtualization(); } private void DataGrid_SortingChanged(object sender, EventArgs e) { InvalidateVirtualization(); } private void TouchVirtualizedContentControl_SizeChanged(object sender, SizeChangedEventArgs e) { InvalidateVirtualization(); } private void _scrollViewer_Scrolling(object sender, DoubleValueChangedEventArgs e) { if (_loaded) { ApplyVirtualization(); } } private void InvalidateVirtualization() { _updateTimer.ResetReplace(() => { Dispatcher.BeginInvoke(new Action(() => { _location = this.TranslatePoint(new Point(0, 0), _scrollViewer.GetContentGrid()); ApplyVirtualization(); })); }); } private void ApplyVirtualization() { var _border_viewport = _scrollViewer.GetViewportBorder(); if (CanMovePosition) { _location = this.TranslatePoint(new Point(0, 0), _scrollViewer.GetContentGrid()); } Rect bounds = new Rect(_location.X, _location.Y, ActualWidth, ActualHeight); Rect rect = new Rect(0.0, _scrollViewer.GetScrollPosition(), _border_viewport.ActualWidth, _border_viewport.ActualHeight); if (_innerBorder != null) { if (bounds.IntersectsWith(rect)) { if (_innerBorder.Visibility == Visibility.Hidden) { //Debug.WriteLine("Visible"); Dispatcher.BeginInvoke(new Action(() => { _innerBorder.Visibility = Visibility.Visible; }), DispatcherPriority.Background); } } else { if (_innerBorder.Visibility == Visibility.Visible) { Dispatcher.BeginInvoke(new Action(() => { //Debug.WriteLine("Hidden"); _innerBorder.Visibility = Visibility.Hidden; }), DispatcherPriority.Background); } } } } } }