Vývoj moderních aplikací na platformě Microsoft .NET

Je vyžadována podpora jazyka JavaScript

Některé stránky na tomto webu vyžadují podporu jazyka JavaScript. Váš webový prohlížeč jazyk JavaScript nepodporuje nebo jazyk JavaScript není povolen.

Chcete-li zjistit, zda webový prohlížeč podporuje jazyk JavaScript nebo jazyk JavaScript chcete povolit, přečtěte si nápovědu k vašemu webovému prohlížeči.


extendeddatagrid.cs

Download file

Toto je zdrojový kód souboru extendeddatagrid.cs

using System;
using System.Collections;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace IMP.Windows.Controls
{
    /// <summary>
    /// Fixed DataGrid control
    /// </summary>
    /// <remarks>
    /// Fixes <c>MouseLeftButtonDown</c> event
    /// Fixes rows selecting with <c>Extended</c> <c>SelectionMode</c> for multiselect DragDrop
    /// Přidává metody <c>HitTest</c>
    /// </remarks>
    public class ExtendedDataGrid : System.Windows.Controls.DataGrid
    {
        #region delegate and events
        /// <summary>
        /// MouseLeftButtonDown event
        /// </summary>
        public new event MouseButtonEventHandler MouseLeftButtonDown;
        #endregion

        #region member varible and default property initialization
        private IList LastSelectionRemovedItems;
        private bool KeyboardStateOnMouseLeftButtonDown;
#if !SILVERLIGHT
        private DataGridRow LeftButtonDowmLastRow;
#endif
        #endregion

        #region constructors and destructors
        /// <summary>
        /// ExtendedDataGrid control constructor
        /// </summary>
        public ExtendedDataGrid()
        {
            base.AddHandler(FrameworkElement.MouseLeftButtonDownEvent, new MouseButtonEventHandler(Base_MouseLeftButtonDown), true);
        }
        #endregion

        #region action methods
        /// <summary>
        /// Get DataGrid Row from mouse position in <c>MouseEventArgs</c>
        /// </summary>
        /// <param name="e"><c>MouseEventArgs</c></param>
        /// <returns>DataGrid Row</returns>
        public DataGridRow HitTest(MouseEventArgs e)
        {
#if SILVERLIGHT
            var root = Application.Current.RootVisual;
            return HitTest(e.GetPosition(root));
#else
            return HitTest(e.GetPosition(this));
#endif
        }

#if SILVERLIGHT
        /// <summary>
        /// Get DataGrid Row from mouse position in <c>DragEventArgs</c>
        /// </summary>
        /// <param name="e"><c>DragEventArgs</c></param>
        /// <returns>DataGrid Row</returns>
        public DataGridRow HitTest(Microsoft.Windows.DragEventArgs e)
        {
            var root = Application.Current.RootVisual;
            return HitTest(e.GetPosition(root));
        }
#else
        /// <summary>
        /// Get DataGrid Row from mouse position in <c>DragEventArgs</c>
        /// </summary>
        /// <param name="e"><c>DragEventArgs</c></param>
        /// <returns>DataGrid Row</returns>
        public DataGridRow HitTest(DragEventArgs e)
        {
            return HitTest(e.GetPosition(this));
        }
#endif

        /// <summary>
        /// Get DataGrid Row from mouse position relative to RootVisual
        /// </summary>
        /// <param name="pt"><c>Point</c> with mouse position relative to RootVisual</param>
        /// <returns>DataGrid Row</returns>
        public DataGridRow HitTest(Point pt)
        {
#if SILVERLIGHT
            var root = Application.Current.RootVisual;
            var elements = VisualTreeHelper.FindElementsInHostCoordinates(pt, root);

            foreach (var element in elements)
            {
                var row = element as DataGridRow;
                if (row != null)
                {
                    //Kontrola zda Row patří k gridu this
                    if (this.Columns[0].GetCellContent(row) != null)
                    {
                        return row;
                    }
                }
            }
#else
            var hitResultsList = new List<UIElement>();
            VisualTreeHelper.HitTest(this, null, result =>
            {
                var element = result.VisualHit as UIElement;
                if (element != null)
                {
                    hitResultsList.Add(element);
                }
                return HitTestResultBehavior.Continue;
            }, new PointHitTestParameters(pt));

            var elements = hitResultsList;

            foreach (var element in elements)
            {
                var row = GetVisualParent<DataGridRow>(element);
                if (row != null)
                {
                    //Kontrola zda Row patří k gridu this
                    if (this.Columns[0].GetCellContent(row) != null)
                    {
                        return row;
                    }
                }
            }
#endif

            return null;
        }
        #endregion

        #region private member functions
        /// <summary>
        /// Overrides OnSelectionChanged
        /// </summary>
        protected override void OnSelectionChanged(System.Windows.Controls.SelectionChangedEventArgs e)
        {
            this.LastSelectionRemovedItems = null;
            if (this.SelectionMode == DataGridSelectionMode.Extended && e.RemovedItems.Count != 0 && e.AddedItems.Count == 0 &&
                (Keyboard.Modifiers & ModifierKeys.Control) == 0 && (Keyboard.Modifiers & ModifierKeys.Shift) == 0)
            {
                //Označení záznamu, který již byl označen jako součást multiselektu
                //Zapamatování pro obnovu označení na MouseLeftButtonDown
                this.LastSelectionRemovedItems = e.RemovedItems;
            }

            base.OnSelectionChanged(e);
        }

        private void Base_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            this.OnMouseLeftButtonDown(e);
        }

        /// <summary>
        /// Raise MouseLeftButtonDown event
        /// </summary>
        protected new virtual void OnMouseLeftButtonDown(MouseButtonEventArgs e)
        {
#if !SILVERLIGHT
            this.LeftButtonDowmLastRow = null;
#endif

            if (this.LastSelectionRemovedItems != null)
            {
                if (this.ItemsSource != null)
                {
#if !SILVERLIGHT
                    this.LeftButtonDowmLastRow = this.HitTest(e);
#endif

                    //Vrácení označení podle zapamatování v OnSelectionChanged
                    foreach (var item in this.LastSelectionRemovedItems)
                    {
                        try
                        {
                            this.SelectedItems.Add(item);
                        }
                        catch (ArgumentException)
                        {
                            //The item is not contained in the ItemsSource.
                        }
                    }
                }

                this.LastSelectionRemovedItems = null;
            }

            this.KeyboardStateOnMouseLeftButtonDown = (Keyboard.Modifiers & ModifierKeys.Control) != 0 || (Keyboard.Modifiers & ModifierKeys.Shift) != 0;

            if (MouseLeftButtonDown != null)
            {
                MouseLeftButtonDown(this, e);
            }
        }

        /// <summary>
        /// Overrides OnMouseLeftButtonUp
        /// </summary>
        protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
        {
#if SILVERLIGHT
            if (!e.Handled && this.SelectionMode == DataGridSelectionMode.Extended && this.SelectedItems.Count > 1 &&
                (Keyboard.Modifiers & ModifierKeys.Control) == 0 && (Keyboard.Modifiers & ModifierKeys.Shift) == 0 && !this.KeyboardStateOnMouseLeftButtonDown &&
                !Microsoft.Windows.DragDrop.IsDragInProgress)
            {
                var row = this.HitTest(e);
                if (row != null)
                {
                    var item = row.DataContext;
                    this.SelectedItems.Clear();
                    this.SelectedItem = item;
                }
            }
#else
            if (!e.Handled && this.SelectionMode == DataGridSelectionMode.Extended && this.SelectedItems.Count > 1 &&
                (Keyboard.Modifiers & ModifierKeys.Control) == 0 && (Keyboard.Modifiers & ModifierKeys.Shift) == 0 && !this.KeyboardStateOnMouseLeftButtonDown)
            {
                var row = this.HitTest(e);
                if (row != null && row == this.LeftButtonDowmLastRow)
                {
                    var item = row.DataContext;
                    this.SelectedItems.Clear();
                    this.SelectedItem = item;
                }
                this.LeftButtonDowmLastRow = null;
            }
#endif

            this.KeyboardStateOnMouseLeftButtonDown = false;

            base.OnMouseLeftButtonUp(e);
        }

#if !SILVERLIGHT
        private static T GetVisualParent<T>(Visual element) where T : Visual
        {
            T item = default(T);
            var v = VisualTreeHelper.GetParent(element) as Visual;

            while (v != null)
            {
                item = v as T;
                if (item != null)
                {
                    return item;
                }

                v = VisualTreeHelper.GetParent(v) as Visual;
            }

            return null;
        }
#endif
        #endregion
    }
}