Click here to Skip to main content
15,886,689 members
Articles / Desktop Programming / WPF

WPF ListView which can do - Sorting, Filtering, Totals, Cell-focus, Editing, and More

Rate me:
Please Sign up or sign in to vote.
4.89/5 (65 votes)
21 Apr 2010CPOL6 min read 278.2K   11.4K   172  
Enhanced WPF ListView that is almost a DataGrid
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Controls.Primitives;
using System.Collections;
using System.Timers;
using System.Windows.Threading;
using System.Linq;
using Microsoft.Windows.Themes;

//  Christoph Brändle (dialogik.ch)
//  Article published: 

namespace DsxGridCtrl
{
    #region TemplateParts

    [TemplatePart(Name = cPART_ListViewLeft,        Type = typeof(ListView))]
    [TemplatePart(Name = cPART_ListViewCenter,      Type = typeof(ListView))]
    [TemplatePart(Name = cPART_ListViewRight,       Type = typeof(ListView))]

    [TemplatePart(Name = cPART_GridViewLeft,        Type = typeof(DsxGridView))]
    [TemplatePart(Name = cPART_GridViewCenter,      Type = typeof(DsxGridView))]
    [TemplatePart(Name = cPART_GridViewRight,       Type = typeof(DsxGridView))]

    #endregion

    #region StyleParts
    [StyleTypedProperty(Property = "HeaderStyle",   StyleTargetType = typeof(DsxHeaderStyle ))]
    [StyleTypedProperty(Property = "FilterStyle",   StyleTargetType = typeof(DsxFilterStyle ))]
    [StyleTypedProperty(Property = "FooterStyle",   StyleTargetType = typeof(DsxFooterStyle ))]
    [StyleTypedProperty(Property = "RowCellStyle",  StyleTargetType = typeof(DsxRowCellStyle))]

    #endregion

    public class DsxDataGrid : Selector
    {
        #region Consts

        internal const string   cPART_ListViewLeft      = "PART_ListViewLeft";
        internal const string   cPART_ListViewCenter    = "PART_ListViewCenter";
        internal const string   cPART_ListViewRight     = "PART_ListViewRight";

        internal const string   cPART_GridViewLeft      = "PART_GridViewLeft";
        internal const string   cPART_GridViewCenter    = "PART_GridViewCenter";
        internal const string   cPART_GridViewRight     = "PART_GridViewRight";

        internal const string   cPART_FilterCheck       = "PART_FilterCheck";
        internal const string   cPART_FilterText        = "PART_FilterText";

        #endregion

        #region ctors

        static DsxDataGrid()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(DsxDataGrid), new FrameworkPropertyMetadata((typeof(DsxDataGrid))));
        }

        public DsxDataGrid()
        {
            this.Columns            = new GridViewColumnCollection();
            this.InnerColumns       = new List<DsxColumn>();
            this.FilterColumns      = new List<DsxColumn>();
            this.FooterColumns      = new List<DsxColumn>();
            this.HeightTracker      = new DsxHeightTracker(this);

            this.Loaded             += OnLoaded;
            this.SelectionChanged   += OnSelectionChanged;
            this.SizeChanged        += OnSizeChanged;

            this.IsSynchronizedWithCurrentItem = true;
        }
      
        #endregion

        #region members / properties

        internal ListView               PART_ListViewLeft       { get; set; }
        internal ListView               PART_ListViewCenter     { get; set; }
        internal ListView               PART_ListViewRight      { get; set; }

        internal DsxGridView            PART_GridViewLeft       { get; set; }
        internal DsxGridView            PART_GridViewCenter     { get; set; }
        internal DsxGridView            PART_GridViewRight      { get; set; }

        private ScrollViewer            ScrollViewerLeft        { get; set; }
        private ScrollViewer            ScrollViewerRight       { get; set; }
        private ScrollViewer            ScrollViewerCenter      { get; set; }

        private List<DsxColumn>         InnerColumns            { get; set; }
        private List<DsxColumn>         FilterColumns           { get; set; }
        private List<DsxColumn>         FooterColumns           { get; set; }

        private Timer                   FilterWaitTimer         { get; set; }

        private GridViewColumnHeader    SortHeader              { get; set; }
        private SortAdorner             SortAdorner             { get; set; }
        private DsxColumn               SortColumn              { get; set; }

        internal ICollectionView        DisplaySource           { get; set; }

        private DsxColumn               LastFocusColumn         { get; set; }
        private DsxCellBase             LastFocusCell           { get; set; }
        private DsxCellBase             LastEditCell            { get; set; }
        private object                  LastFocusRow            { get; set; }
        private Adorner                 LastAdorner             { get; set; }

        internal bool                   IsGridAreaLeft          { get; set; }
        internal bool                   IsGridAreaCenter        { get; set; }
        internal bool                   IsGridAreaRight         { get; set; }

        internal int                    AreaLeftColCount        { get; set; }
        internal int                    AreaCenterColCount      { get; set; }
        internal int                    AreaRightColCount       { get; set; }

        #endregion


        #region Override - OnApplyTemplate

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            this.PART_ListViewLeft      = GetTemplateChild(cPART_ListViewLeft)      as ListView;
            this.PART_ListViewCenter    = GetTemplateChild(cPART_ListViewCenter)    as ListView;
            this.PART_ListViewRight     = GetTemplateChild(cPART_ListViewRight)     as ListView;

            this.PART_GridViewLeft      = GetTemplateChild(cPART_GridViewLeft)      as DsxGridView;
            this.PART_GridViewCenter    = GetTemplateChild(cPART_GridViewCenter)    as DsxGridView;
            this.PART_GridViewRight     = GetTemplateChild(cPART_GridViewRight)     as DsxGridView;

            this.PART_ListViewLeft      .AlternationCount = this.AlternatingRowBrushes.Count;
            this.PART_ListViewCenter    .AlternationCount = this.AlternatingRowBrushes.Count;
            this.PART_ListViewRight     .AlternationCount = this.AlternatingRowBrushes.Count;

            CreateColumnLayout();
        }
        #endregion

        #region Method - CreateColumnLayout

        private void CreateColumnLayout()
        {
            DsxColumn   _gridViewColumn;
            int         _gridColCount = 0;

            if (!this.IsInitialized)
            {
                return;
            }

            if (this.InnerColumns.Count > 0)
            {
                if (this.IsGridAreaLeft)
                {
                    this.PART_ListViewLeft .RemoveHandler(GridViewColumnHeader.ClickEvent, new RoutedEventHandler(OnGridViewColumnHeaderClicked));
                }
                if (this.IsGridAreaCenter)
                {
                    this.PART_ListViewCenter.RemoveHandler(GridViewColumnHeader.ClickEvent, new RoutedEventHandler(OnGridViewColumnHeaderClicked));
                }
                if (this.IsGridAreaRight)
                {
                    this.PART_ListViewRight .RemoveHandler(GridViewColumnHeader.ClickEvent, new RoutedEventHandler(OnGridViewColumnHeaderClicked));
                }

                this.PART_GridViewLeft  .Columns.Clear();
                this.PART_GridViewCenter.Columns.Clear();
                this.PART_GridViewRight .Columns.Clear();

                this.InnerColumns .Clear();
                this.FilterColumns.Clear();
                this.FooterColumns.Clear();
            }

            //  map the columns (we need DsxColumns)
            foreach(GridViewColumn _column in this.Columns)
            {
                _gridViewColumn = new DsxColumn(_column, this);
                
                //  filtering
                if (_gridViewColumn.IsFilterActive)
                {
                    _gridViewColumn.FilterTextChanged += OnColumnFilterTextChanged;
                    this.FilterColumns.Add(_gridViewColumn);
                }

                //  summaries
                if (_gridViewColumn.IsFooterActive)
                {
                    this.FooterColumns.Add(_gridViewColumn);
                }

                //  columns
                DsxGridView _gridView = GetGridView(_gridViewColumn.ColumnArea);

                            _gridViewColumn.ColAreaIndex = _gridView.Columns.Count;
                            _gridViewColumn.ColIndex     = _gridColCount;
                            _gridColCount++;

                            _gridView.Columns.Add(_gridViewColumn);     

                this.InnerColumns.Add(_gridViewColumn);
            }

            this.AreaLeftColCount   = this.PART_GridViewLeft  .Columns.Count;
            this.AreaCenterColCount = this.PART_GridViewCenter.Columns.Count;
            this.AreaRightColCount  = this.PART_GridViewRight .Columns.Count;

            this.IsGridAreaLeft     = this.AreaLeftColCount   > 0;
            this.IsGridAreaCenter   = this.AreaCenterColCount > 0;
            this.IsGridAreaRight    = this.AreaRightColCount  > 0;

            if (this.IsGridAreaLeft)
            {
                this.PART_ListViewLeft.AddHandler(GridViewColumnHeader.ClickEvent, new RoutedEventHandler(OnGridViewColumnHeaderClicked));
            }
            else
            {
                this.AreaLeftWidth          = new GridLength(0.0);
                this.SplitterLeftIsSizing   = false;
                this.SplitterLeftWidth      = new GridLength(0.0);
            }

            if (this.IsGridAreaCenter)
            {
                this.PART_ListViewCenter.AddHandler(GridViewColumnHeader.ClickEvent, new RoutedEventHandler(OnGridViewColumnHeaderClicked));
            }
            else
            {
                this.AreaCenterWidth        = new GridLength(0.0);
                this.SplitterRightIsSizing  = false;
                this.SplitterRightWidth     = new GridLength(0.0);
                this.AreaRightWidth         = new GridLength(this.AreaRightWidth.Value, GridUnitType.Star);
            }

            if (this.IsGridAreaRight)
            {
                this.PART_ListViewRight.AddHandler(GridViewColumnHeader.ClickEvent, new RoutedEventHandler(OnGridViewColumnHeaderClicked));
            }
            else if (this.Columns.Count>0)
            {
                throw new NotSupportedException("at least one column must be in the right area");
            }

            //  check the limitations
            if (this.IsGridAreaLeft || this.IsGridAreaCenter)
            {
                if (this.IsVirtualizing)
                {
                    throw new NotSupportedException("Multiple areas and IsVirtualizing are not allowed: turn off IsVirtualizing");
                }
                if (this.ItemFixHeight == 0.0 || this.ItemMinHeight != 0.0 || this.ItemMaxHeight != 0.0)
                {
                    throw new NotSupportedException("Multiple areas and variable ItemHeight are not allowed: set ItemFixHeight and turn off ItemMinHeight/ItemMaxHeight");
                }
            }

        }
        #endregion


        #region EventConsumer - OnLoaded

        void OnLoaded(object sender, RoutedEventArgs e)
        {
            //  usually don't check for TemplatePart
            this.ScrollViewerLeft       = (VisualTreeHelper.GetChild(this.PART_ListViewLeft,   0) as Decorator).Child as ScrollViewer;
            this.ScrollViewerCenter     = (VisualTreeHelper.GetChild(this.PART_ListViewCenter, 0) as Decorator).Child as ScrollViewer;
            this.ScrollViewerRight      = (VisualTreeHelper.GetChild(this.PART_ListViewRight,  0) as Decorator).Child as ScrollViewer;

            DsxFilterClear  _clearBtn = ElementHelper.FindVisualChild<DsxFilterClear>(this.ScrollViewerRight, "PART_dsxFilterBtn");
            
            if (_clearBtn != null)
            {
                _clearBtn.Click += delegate { ResetFilters(); };
            }


            this.ScrollViewerLeft  .SetValue(ScrollSynchronizer.VScrollGroupProperty, "listFull");
            this.ScrollViewerCenter.SetValue(ScrollSynchronizer.VScrollGroupProperty, "listFull");
            this.ScrollViewerRight .SetValue(ScrollSynchronizer.VScrollGroupProperty, "listFull");

            this.PART_ListViewLeft  .PreviewMouseLeftButtonDown += OnPreviewMouseLeftButtonDown;
            this.PART_ListViewCenter.PreviewMouseLeftButtonDown += OnPreviewMouseLeftButtonDown;
            this.PART_ListViewRight .PreviewMouseLeftButtonDown += OnPreviewMouseLeftButtonDown;

            this.PART_ListViewLeft  .PreviewGotKeyboardFocus    += OnPreviewGotKeyboardFocus;
            this.PART_ListViewCenter.PreviewGotKeyboardFocus    += OnPreviewGotKeyboardFocus;
            this.PART_ListViewRight .PreviewGotKeyboardFocus    += OnPreviewGotKeyboardFocus;

            this.PART_ListViewLeft  .PreviewKeyDown             += OnPreviewKeyDown;
            this.PART_ListViewCenter.PreviewKeyDown             += OnPreviewKeyDown;
            this.PART_ListViewRight .PreviewKeyDown             += OnPreviewKeyDown;

            //  force calculate initial display
            this.HasData = false;
        }
        #endregion

        #region EventConsumer - OnSizeChanged

        void OnSizeChanged(object sender, SizeChangedEventArgs e)
        {
            if (e.HeightChanged)
            {
                this.HeightTracker.UpdateLayout();
            }
        }
        #endregion

        #region EventConsumer - OnColumnFilterTextChanged

        void OnColumnFilterTextChanged(object sender, EventArgs e)
        {
            UpdateAdorner(null);
            FilterWaitQueue();
        }
        #endregion

        #region Callback - CheckColumnFilters

        private bool CheckColumnFilters(object listItem)
        {
            foreach(DsxColumn _column in this.FilterColumns)
            {
                if (!_column.FilterCheckValue(listItem))
                {
                    return false;
                }
            }
            return true;
        }
        #endregion


        #region EventConsumer - OnGridViewColumnHeaderClicked

        private void OnGridViewColumnHeaderClicked(object sender, RoutedEventArgs e)
        {
            e.Handled = true;

            GridViewColumnHeader _gridViewHeader = e.OriginalSource as GridViewColumnHeader;

            if (_gridViewHeader != null) // && _gridViewHeader.Tag!=null && _gridViewHeader.Tag.ToString().Equals("Hdr"))
            {
                //  we have header, filter and footer, all are GridViewHeaderRowPresenter's
                //  so we get click from all of them and we need to filter out
                Border _visualBorder = ElementHelper.FindVisualChild<Border>(_gridViewHeader);

                if (_visualBorder == null || !_visualBorder.Name.Contains("Header"))
                {
                    return;
                }

                DsxColumn    _gridViewColumn = _gridViewHeader.Column as DsxColumn;

                SetSortColumn(_gridViewColumn, _gridViewHeader);
            }
        }
        #endregion

        #region EventConsumer - OnSelectionChanged

        void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (!this.IsEnabled || !this.CellAdornerIsVisible || e == null || e.AddedItems.Count == 0)
            {
                return;
            }

            object  _rowItem = e.AddedItems[0];

            if (this.LastFocusRow != _rowItem && this.LastFocusColumn != null)
            {
                if (e.OriginalSource != GetListView(this.LastFocusColumn.ColumnArea))
                {
                    return;
                }
                SelectCellViewElement(_rowItem);
            }
        }
        #endregion


        #region EventConsumer - OnPreviewMouseLeftButtonDown

        private void OnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            FrameworkElement _hitElement = e.OriginalSource as FrameworkElement;

            if (!this.CellAdornerIsVisible || _hitElement == null)
            {
                return;
            }


            if (_hitElement is BulletChrome || _hitElement is DsxRowCell<CheckBox>)
            {
                if (this.AllowCheckAnyTime)
                {
                    DsxCellBase _parentCell = _hitElement as DsxCellBase;
                    
                    if (_parentCell == null)
                    {
                        _parentCell = ElementHelper.FindLogicalParent<DsxCellBase>(_hitElement);
                    }

                    if (_parentCell != null && _parentCell.Column != null && _parentCell.Column.ViewType==EViewType.CheckBox)
                    {
                        _parentCell.Column.ToggleCheck(_parentCell);
                        e.Handled = true;
                        return;
                    }
                }
            }

            if (_hitElement is Border && !(_hitElement is DsxCellBase))
            {
                //  try to find which cell we did hit
                //  because all cells should be top aligned, try to find dirty
                Point            _point      = e.GetPosition((UIElement)sender);
                                 _point.Y    = 10;
                HitTestResult    _hitResult  = VisualTreeHelper.HitTest(_hitElement, _point);
               
                if (_hitResult != null && _hitResult.VisualHit is FrameworkElement)
                {
                    _hitElement = (FrameworkElement)_hitResult.VisualHit;
                }
                else
                {
                    return;
                }
            }

            if (_hitElement == this.LastEditCell && this.LastEditCell.IsEditMode)
            {
                return;
            }

            FrameworkElement _element = UpdateAdorner(_hitElement as FrameworkElement);
            
            SetCellFocus (_element);
        }   
        #endregion

        #region EventConsumer - OnPreviewGotKeyboardFocus

        void OnPreviewGotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
        {
            if (!this.CellAdornerIsVisible)
            {
                return;
            }

            if ((e.OriginalSource as FrameworkElement).IsFocused)
            {
                return;
            }

            FrameworkElement _focusElement = e.OriginalSource as FrameworkElement;

            this.UpdateAdorner(_focusElement);
        }
        #endregion

        #region EventConsumer - OnPreviewKeyDown

        void OnPreviewKeyDown(object sender, KeyEventArgs e)
        {
            if (!this.CellAdornerIsVisible || this.LastFocusColumn == null || this.LastFocusCell == null || this.LastFocusRow == null || this.SelectedItem == null)
            {
                return;
            }


            bool _isEditing = false;

            if (this.LastEditCell != null && this.LastEditCell.IsEditMode)
            {
                _isEditing = true;
            }

            if (!_isEditing)
            {
                if (e.Key == Key.Space && this.AllowCheckAnyTime)
                {
                    if (    this.LastFocusCell != null 
                         && this.LastFocusColumn != null 
                         && this.LastFocusColumn.ViewType == EViewType.CheckBox)
                    {
                        e.Handled = true;
                        this.LastFocusColumn.ToggleCheck(this.LastFocusCell);
                    }
                    return;
                }

                if (e.Key == Key.F2 && this.CellEditingIsEnabled)
                {
                    if (    this.LastFocusCell != null 
                         && this.LastFocusColumn != null 
                         && this.LastFocusColumn.IsEditable)
                    {
                        e.Handled = true;
                        SetEditCell(this.LastFocusColumn, this.LastFocusCell);
                    }
                    return;
                }
            }

            if (_isEditing && this.CellEditingIsEnabled)
            {
                if (e.Key == Key.Escape)
                {
                    e.Handled = true;
                    if (this.LastAdorner != null && this.LastAdorner is EditAdorner)
                    {
                        (this.LastAdorner as EditAdorner).CancelEditing();
                    }
                }
                if (e.Key == Key.Enter)
                {
                    e.Handled = true;
                }
                
                if (    e.Key == Key.Enter  ||  e.Key == Key.Escape
                    ||  e.Key == Key.Up     ||  e.Key == Key.Down
                    ||  e.Key == Key.PageUp ||  e.Key == Key.PageDown)
                {
                    this.LastEditCell.Dispatcher.BeginInvoke( new Action(delegate 
                                                            {   
                                                                this.LastEditCell.Focus();
                                                                RemoveAdorner(this.LastEditCell, this.LastAdorner);
                                                            }), 
                                                            DispatcherPriority.Input);
                }
                return;
            }


            if ((e.Key == Key.Left) && this.LastFocusColumn.ColIndex > 0)
            {
                e.Handled = true;

                if (this.LastFocusColumn.ColAreaIndex == 0)
                {
                    if (this.LastFocusColumn.ColumnArea == EArea.Left)
                    {
                        return;
                    }
                    else if (this.LastFocusColumn.ColumnArea == EArea.Center && !this.IsGridAreaLeft)
                    {
                        return;
                    }
                    else if (this.LastFocusColumn.ColumnArea == EArea.Right &&  !this.IsGridAreaCenter && !this.IsGridAreaLeft)
                    {
                        return;
                    }
                }

                GridView _curArea = GetGridView(this.LastFocusColumn.ColumnArea);

                //  Ctrl-Left
                if ( (Keyboard.Modifiers & ModifierKeys.Control) > 0 )
                {
                    if (this.LastFocusColumn.ColumnArea == EArea.Right)
                    {
                        if (this.IsGridAreaCenter)
                        {
                            UpdateAdorner(null);
                            this.LastFocusColumn = (DsxColumn)GetGridView(EArea.Center).Columns[this.AreaCenterColCount-1];
                        }
                        else if (this.IsGridAreaLeft)
                        {
                            UpdateAdorner(null);
                            this.LastFocusColumn = (DsxColumn)GetGridView(EArea.Left).Columns[this.AreaLeftColCount-1];
                        }
                    }
                    else if (this.LastFocusColumn.ColumnArea == EArea.Center)
                    {
                        if (this.IsGridAreaLeft)
                        {
                            UpdateAdorner(null);
                            this.LastFocusColumn = (DsxColumn)GetGridView(EArea.Left).Columns[this.AreaLeftColCount-1];
                        }
                    }
                    else
                    {
                        return;
                    }
                }
                else
                {
                    if (this.LastFocusColumn.ColAreaIndex > 0)
                    {
                        UpdateAdorner(null);
                        this.LastFocusColumn = (DsxColumn)_curArea.Columns[this.LastFocusColumn.ColAreaIndex-1];
                    }
                    else if (this.LastFocusColumn.ColumnArea == EArea.Right)
                    {
                        if (this.IsGridAreaCenter)
                        {
                            UpdateAdorner(null);
                            this.LastFocusColumn = (DsxColumn)GetGridView(EArea.Center).Columns[this.AreaCenterColCount-1];
                        }
                        else if (this.IsGridAreaLeft)
                        {
                            UpdateAdorner(null);
                            this.LastFocusColumn = (DsxColumn)GetGridView(EArea.Left).Columns[this.AreaLeftColCount-1];
                        }
                    }
                    else if (this.LastFocusColumn.ColumnArea == EArea.Center)
                    {
                        if (this.IsGridAreaLeft)
                        {
                            UpdateAdorner(null);
                            this.LastFocusColumn = (DsxColumn)GetGridView(EArea.Left).Columns[this.AreaLeftColCount-1];
                        }
                    }
                    else
                    {
                        return;
                    }
                }
                SelectCellViewElement(this.SelectedItem);
            }
            else if ((e.Key == Key.Right))
            {
                e.Handled = true;

                if (this.LastFocusColumn.ColumnArea == EArea.Right && this.LastFocusColumn.ColAreaIndex == (this.AreaRightColCount-1))
                {
                    return;
                }
                GridView _curArea = GetGridView(this.LastFocusColumn.ColumnArea);

                //  Ctrl-Right
                if ( (Keyboard.Modifiers & ModifierKeys.Control) > 0 )
                {
                    if (this.LastFocusColumn.ColumnArea == EArea.Left)
                    {
                        if (this.IsGridAreaCenter)
                        {
                            UpdateAdorner(null);
                            this.LastFocusColumn = (DsxColumn)GetGridView(EArea.Center).Columns[0];
                        }
                        else if (this.IsGridAreaRight)
                        {
                            UpdateAdorner(null);
                            this.LastFocusColumn = (DsxColumn)GetGridView(EArea.Right).Columns[0];
                        }
                    }
                    else if (this.LastFocusColumn.ColumnArea == EArea.Center)
                    {
                        if (this.IsGridAreaRight)
                        {
                            UpdateAdorner(null);
                            this.LastFocusColumn = (DsxColumn)GetGridView(EArea.Right).Columns[0];
                        }
                    }
                    else
                    {
                        return;
                    }
                }
                else
                {
                    if (this.LastFocusColumn.ColAreaIndex < (_curArea.Columns.Count-1))
                    {
                        UpdateAdorner(null);
                        this.LastFocusColumn = (DsxColumn)_curArea.Columns[this.LastFocusColumn.ColAreaIndex+1];
                    }
                    else if (this.LastFocusColumn.ColumnArea == EArea.Left)
                    {
                        if (this.IsGridAreaCenter)
                        {
                            UpdateAdorner(null);
                            this.LastFocusColumn = (DsxColumn)GetGridView(EArea.Center).Columns[0];
                        }
                        else if (this.IsGridAreaRight)
                        {
                            UpdateAdorner(null);
                            this.LastFocusColumn = (DsxColumn)GetGridView(EArea.Right).Columns[0];
                        }
                    }
                    else if (this.LastFocusColumn.ColumnArea == EArea.Center)
                    {
                        if (this.IsGridAreaRight)
                        {
                            UpdateAdorner(null);
                            this.LastFocusColumn = (DsxColumn)GetGridView(EArea.Right).Columns[0];
                        }
                    }
                    else
                    {
                        return;
                    }
                }
                SelectCellViewElement(this.SelectedItem);
            }
            else if (e.Key == Key.Home && this.LastFocusColumn.ColIndex > 0)
            {
                e.Handled = true;
                UpdateAdorner(null);
                this.LastFocusColumn = (DsxColumn)GetGridView(EArea.Left).Columns[0];
                SelectCellViewElement(this.SelectedItem);
            }
            else if (e.Key == Key.End && this.LastFocusColumn.ColIndex < this.InnerColumns.Count-1 )
            {
                e.Handled = true;
                UpdateAdorner(null);
                this.LastFocusColumn = (DsxColumn)GetGridView(EArea.Right).Columns[ ( GetGridView(EArea.Right).Columns.Count-1) ];
                SelectCellViewElement(this.SelectedItem);
            }
        }
        #endregion


        #region Override - OnItemSourceChanged

        protected override void OnItemsSourceChanged(System.Collections.IEnumerable oldValue, System.Collections.IEnumerable newValue)
        {
            RecalcDisplaySource();
        }

        #endregion

        #region Method - RebuildLayout
		
		private void RebuildLayout()
		{
            IEnumerable _itemsSource = this.ItemsSource;

            if (_itemsSource != null)
            {
                this.ItemsSource = null;
            }
            if (this.SortColumn != null)
            {
                this.SortColumn = null;
            }

            CreateColumnLayout();

            if (_itemsSource != null)
            {
                this.ItemsSource = _itemsSource;
            }

            SetSortColumn(this.SortField);
		}
        #endregion
		

        #region Method - SelectCellViewElement

        private void SelectCellViewElement(object rowItem)
        {
            ListView        _listView = GetListView(this.LastFocusColumn.ColumnArea);
            DsxGridView     _gridView = GetGridView(this.LastFocusColumn.ColumnArea);
            ListViewItem    _listItem = _listView.ItemContainerGenerator.ContainerFromItem(rowItem) as ListViewItem; 
            if (_listItem != null) 
            { 
                if (!_listItem.IsLoaded) 
                { 
                    _listItem.ApplyTemplate(); 
                } 
                GridViewRowPresenter _rowPresenter = ElementHelper.FindVisualChild<GridViewRowPresenter>(_listItem); 

                if(_rowPresenter != null) 
                { 
                    if (VisualTreeHelper.GetChildrenCount(_rowPresenter)>0)
                    {
                        ContentPresenter    _templatedParent = VisualTreeHelper.GetChild(_rowPresenter, this.LastFocusColumn.ColAreaIndex) as ContentPresenter; 
                        DataTemplate        _dataTemplate    = this.LastFocusColumn.CellTemplate; 

                        if(_dataTemplate != null && _templatedParent != null) 
                        { 
                            if (_dataTemplate.VisualTree != null)
                            {
                                FrameworkElement _element  = _dataTemplate.FindName(this.LastFocusColumn.CellPartFrameName, _templatedParent) as FrameworkElement; 
                                SetCellFocus(_element);
                            }
                            else if (!String.IsNullOrEmpty(this.LastFocusColumn.CellPartFrameName))
                            {
                                FrameworkElement _element  = ElementHelper.FindVisualChild<FrameworkElement>(_templatedParent, this.LastFocusColumn.CellPartFrameName);
                                SetCellFocus(_element);
                            }
                            else
                            {
                                try
                                {
                                    FrameworkElement _element  = ElementHelper.FindVisualChild<FrameworkElement>(_templatedParent);
                                    SetCellFocus(_element);
                                }
                                catch (Exception)
                                {
                                }
                            }
                        } 
                    }
                } 
            } 
        }
        #endregion

        #region Method - RemoveAdorner

        internal void RemoveAdorner(FrameworkElement gridViewCell, Adorner cellViewAdorner)
        {
            if (cellViewAdorner != null && gridViewCell != null)
            {
                AdornerLayer.GetAdornerLayer(gridViewCell).Remove(cellViewAdorner);
            }
            if (cellViewAdorner == this.LastAdorner)
            {
                this.LastAdorner = null;
            }
            if (gridViewCell == this.LastEditCell)
            {
                if (this.LastEditCell != null)
                {
                    this.LastEditCell.IsEditMode = false;
                    this.LastEditCell = null;
                }
            }
        }
        #endregion

        #region Method - AddEditAdorner

        internal void AddEditAdorner()
        {
            if (this.LastAdorner != null)
            {
                RemoveAdorner(this.LastFocusCell, this.LastAdorner);
            }
            
            this.LastEditCell            = this.LastFocusCell;
            this.LastEditCell.IsEditMode = true;

            if (this.LastFocusColumn != null && (this.LastFocusColumn.EditType != EEditType.CellTemplate || this.LastEditCell is DsxFilterCheckCell || this.LastEditCell is DsxFilterTextCell))
            {
                this.LastAdorner = new EditAdorner(this, this.LastFocusColumn, this.LastEditCell, (this.LastFocusCell.Name == DsxDataGrid.cPART_FilterText || this.LastFocusCell.Name == cPART_FilterCheck ));
                if (this.LastEditCell != null)
                {
                    AdornerLayer.GetAdornerLayer(this.LastEditCell).Add(this.LastAdorner);
                }
            }
            else
            {
                //  let the celltemplate trigger do its work
                LastEditCell.Dispatcher.BeginInvoke( new Action(delegate 
                                                        {   
                                                            this.LastEditCell.SetCellEditFocus(this.LastEditCell.Child); 
                                                        }), 
                                                        DispatcherPriority.Input);
            }
        }
        #endregion

        #region Method - SetEditCell

        public void SetEditCell(DsxColumn gridViewColumn, FrameworkElement gridViewCell)
        {
            if (this.LastFocusColumn != gridViewColumn || this.LastFocusCell != gridViewCell)
            {
                throw new Exception("SetEditCell");
            }
            else
            {
                AddEditAdorner();
            }
        }
        #endregion

        #region Method - SetCellFocus

        private void SetCellFocus(FrameworkElement focusElement)
        {
            FrameworkElement _focusElement = focusElement;

            if (_focusElement != null && !_focusElement.Focusable && _focusElement.Parent != null)
            {
                if ((_focusElement.Parent as FrameworkElement).Focusable)
                {
                    _focusElement = (FrameworkElement)_focusElement.Parent;
                }
            }

            if (_focusElement != null && !_focusElement.IsFocused && !_focusElement.IsKeyboardFocusWithin)
            {
                if (_focusElement is DsxCellBase)
                {
                    if ((_focusElement as DsxCellBase).IsEditMode)
                    {
                        return;
                    }
                }
                _focusElement.Dispatcher.BeginInvoke( new Action(delegate 
                                                        {   
                                                            _focusElement.Focus(); 
                                                        }), 
                                                        DispatcherPriority.Input);
            }
        }
        #endregion

        #region Method - UpdateAdorner

        private FrameworkElement UpdateAdorner(FrameworkElement focusElement)
        {
            if (focusElement == null && this.LastAdorner is EditAdorner && (this.LastAdorner as EditAdorner).IsFilter)
            {
                return this.LastFocusCell;
            }

            FrameworkElement    _focusElement = focusElement;
            DsxCellBase         _focusCell    = focusElement as DsxCellBase;

            //  1st test
            if (this.LastFocusCell != null && this.LastFocusCell == _focusCell)
            {
                return this.LastFocusCell;
            }

            //  compare the right level
            if (_focusCell == null && _focusElement != null)
            {
                while (_focusCell == null && (_focusElement.Parent != null || _focusElement.TemplatedParent != null))
                {
                    if (_focusElement.Parent != null)
                    {
                        _focusElement   = _focusElement.Parent as FrameworkElement;
                        _focusCell      = _focusElement as DsxCellBase;
                    }
                    else if (_focusElement.TemplatedParent != null)
                    {
                        _focusElement   = _focusElement.TemplatedParent as FrameworkElement;
                        _focusCell      = _focusElement as DsxCellBase;
                    }
                }
                if (_focusCell == null)
                {
                    return this.LastFocusCell;
                }

                //  2nd test
                if (this.LastFocusCell != null && this.LastFocusCell == _focusCell)
                {
                    return this.LastFocusCell;
                }
            }

            //  filter
            if (_focusCell != null && _focusCell != this.LastFocusCell && (_focusCell.Name==cPART_FilterText || _focusCell.Name==cPART_FilterCheck) )
            {
                if (this.LastFocusCell != null)
                {
                    RemoveAdorner(this.LastFocusCell, this.LastAdorner);
                    this.LastFocusCell = null;
                }

                this.LastFocusRow    = null;
                this.LastFocusColumn = (_focusElement.TemplatedParent as GridViewColumnHeader).Column as DsxColumn;
                this.LastFocusCell   = _focusCell;
                if (this.LastFocusCell.Column == null)
                {
                    this.LastFocusCell.Column = this.LastFocusColumn;
                }


                AddEditAdorner();
                return this.LastFocusCell;
            }


            //  Cells with Celltemplate dont have the GridViewColumn set
            if (_focusCell != null && _focusCell.Column == null)
            {
                ContentPresenter _columnPresenter;
                ContentPresenter _contentPresenter = _focusCell.TemplatedParent as ContentPresenter;

                if (_contentPresenter != null)
                {
                    GridViewRowPresenter _rowPresenter = _contentPresenter.Parent as GridViewRowPresenter;
                    if (_rowPresenter != null)
                    {
                        int _colCount = _rowPresenter.Columns.Count;
                        for (int i=0; i < _colCount; i++)
                        {
                            _columnPresenter = VisualTreeHelper.GetChild(_rowPresenter, i) as ContentPresenter; 
                            if (_columnPresenter == _contentPresenter)
                            {
                                _focusCell.Column = _rowPresenter.Columns[i] as DsxColumn;
                                this.HeightTracker.UpdateRowArea(_rowPresenter);
                                break;
                            }
                        }
                    }
                }

                if (_focusCell.Column == null)
                {
                    throw new Exception("focusCell.Column could not be resolved");
                }
            }

            //  needed for cross-selection change row/col
            if (this.LastFocusCell != null && this.LastFocusCell != _focusElement)
            {
                RemoveAdorner(this.LastFocusCell, this.LastAdorner);

                if (focusElement == null || (focusElement is ListViewItem))
                {
                    this.LastFocusRow  = null;
                    this.LastFocusCell = null;
                }
            }

            if (_focusElement != null && this.LastFocusCell != _focusElement)
            {
                RemoveAdorner(this.LastFocusCell, this.LastAdorner);

                if (this.LastFocusCell != null)
                {
                    this.LastFocusCell.IsEditMode = false;
                }

                //  timer
                this.LastFocusRow    = this.SelectedItem;
                this.LastFocusColumn = _focusCell.Column;
                this.LastFocusCell   = _focusCell;
            }
            return this.LastFocusCell;
        }
        #endregion


        #region Method - SetSortColumn

        private void SetSortColumn(string sortField)
        {
            if (this.SortColumn != null && this.SortColumn.FieldName.Equals(SortField))
            {
                return;
            }

            DsxColumn _sortColumn = null;

            foreach(DsxColumn _column in this.InnerColumns)
            {
                if (_column.FieldName.Equals(SortField))
                {
                    _sortColumn = _column;
                    break;
                }
            }
            
            if (_sortColumn != null && _sortColumn != this.SortColumn)
            {
                ListView                    _listView        = GetListView(_sortColumn.ColumnArea);
                GridViewHeaderRowPresenter  _headerPresenter = ElementHelper.FindVisualChild<GridViewHeaderRowPresenter>(_listView, "PART_HeaderRow");
                GridViewColumnHeader        _gridViewHeader  = null;
                int                         _childrenCount   = VisualTreeHelper.GetChildrenCount(_headerPresenter);  

                //  enumeration through the children is needed, since the colAreaIndex is not matching the Children Position
                for (int i = 0; i < _childrenCount; i++)  
                {    
                    DependencyObject _child = VisualTreeHelper.GetChild(_headerPresenter, i);

                    _gridViewHeader = _child as GridViewColumnHeader;

                    if (_gridViewHeader != null && _gridViewHeader.Column != null && _gridViewHeader.Column == _sortColumn)
                    {
                        break;
                    }
                }

                SetSortColumn(_sortColumn, _gridViewHeader);
            }
        }

        private void SetSortColumn(DsxColumn sortColumn, GridViewColumnHeader sortHeader)
        {
            if (sortColumn != null && sortColumn.IsSortable && sortHeader != null)
            {
                //  remove an existing adorner
                if (this.SortHeader != null)
                {
                    AdornerLayer _adorner = AdornerLayer.GetAdornerLayer(this.SortHeader);
                    if (_adorner != null)
                    {
                        _adorner.Remove(this.SortAdorner);
                    }
                }

                if (this.SortColumn != sortColumn)
                {
                    sortColumn.SortDirection = ListSortDirection.Ascending;
                }
                else
                {
                    sortColumn.SortDirection = sortColumn.SortDirection == ListSortDirection.Ascending 
                                                                            ? ListSortDirection.Descending
                                                                            : ListSortDirection.Ascending;
                }

                this.SortHeader   = sortHeader;
                this.SortColumn   = sortColumn;
                this.SortField    = SortColumn.FieldName;

                //  create adorner
                if (this.SortHeader != null)
                {
                    this.SortAdorner = new SortAdorner(this.SortHeader, sortColumn.SortDirection);
                    AdornerLayer.GetAdornerLayer(this.SortHeader).Add(this.SortAdorner);
                }
                
                RecalcDisplaySource();
            }
        }
        #endregion


        #region Method - FilterWaitQueue

        private void FilterWaitQueue()
        {
            if (this.FilterWaitTimer == null)
            {
                this.FilterWaitTimer = new Timer(200);
                this.FilterWaitTimer.AutoReset = false;
                this.FilterWaitTimer.Elapsed += delegate 
                { 
                    this.Dispatcher.BeginInvoke( new Action(delegate{ RecalcDisplaySource(); }), DispatcherPriority.Normal);
                };
            }
            else
            {
                this.FilterWaitTimer.Stop();
            }
            this.FilterWaitTimer.Start();
        }
        #endregion

        #region Method - RecalcDisplaySource

        private void RecalcDisplaySource()
        {
            if (this.ItemsSource == null && this.HasData != true)
            {
                return;
            }

            UpdateAdorner(null);

            this.DisplaySource = CollectionViewSource.GetDefaultView( this.ItemsSource );

            this.IsEnabled = false;

            //  this enforces the ListViewLayoutManager to resize properly
            this.PART_ListViewLeft   .IsEnabled = false;
            this.PART_ListViewCenter .IsEnabled = false;
            this.PART_ListViewRight  .IsEnabled = false;

            if (this.DisplaySource != null)
            {
                //  filter, sorting
                using(this.DisplaySource.DeferRefresh())
                {
                    if (this.FilterColumns.Count>0)
                    {
                        bool _filterActive = false;
                        foreach(DsxColumn _filterColumn in this.FilterColumns)
                        {
                            if (!String.IsNullOrEmpty(_filterColumn.FilterTextValue))
                            {
                                _filterActive = true;
                                break;
                            }
                        }
                        this.ComputedFilterClearVisibility = _filterActive ? Visibility.Visible : Visibility.Hidden;
                        this.DisplaySource.Filter                = this.CheckColumnFilters;
                    }
                
                    this.DisplaySource.SortDescriptions.Clear();
                
                    if (this.SortColumn != null)
                    {
                        this.DisplaySource.SortDescriptions.Add(new SortDescription(this.SortColumn.FieldName, this.SortColumn.SortDirection));
                    }
                }
            }

            //  summarize
            if (this.FooterColumns.Count>0)
            {
                foreach(DsxColumn _column in this.FooterColumns)
                {
                    _column.FooterComputedValue = 0.0M;
                }

                if (this.DisplaySource != null)
                {
                    decimal _itemValue  = 0.0M;
                    int     _count      = 0;
                    
                    foreach(object _item in this.DisplaySource)
                    {
                        _count++;

                        foreach(DsxColumn _column in this.FooterColumns)
                        {
                            switch(_column.FooterType)
                            {
                                case EFooterType.Sum:
                                case EFooterType.Avg:
                                     _column.FooterComputedValue += _column.GetFieldValue<decimal>(_item);
                                    break;
                                case EFooterType.Min:
                                    _itemValue = _column.GetFieldValue<decimal>(_item);
                                    _column.FooterComputedValue = (_column.FooterComputedValue != 0.0M && _itemValue < _column.FooterComputedValue) ? _column.FooterComputedValue : _itemValue;
                                    break;
                                case EFooterType.Max:
                                    _itemValue = _column.GetFieldValue<decimal>(_item);
                                    _column.FooterComputedValue = (_itemValue > _column.FooterComputedValue) ? _itemValue : _column.FooterComputedValue;
                                    break;
                                case EFooterType.Count:
                                    break;
                            }
                        }
                    }
                    foreach(DsxColumn _column in this.FooterColumns)
                    {
                        if (_column.FooterType == EFooterType.Avg && _column.FooterComputedValue!=0)
                        {
                            _column.FooterComputedValue /= _count;
                            _column.FooterComputedDisplay = string.Format("{0:F2}", _column.FooterComputedValue);
                        }
                        else if (_column.FooterType == EFooterType.Count)
                        {
                            _column.FooterComputedDisplay = string.Format("{0}", _count);
                        }
                        else
                        {
                            _column.FooterComputedDisplay = string.Format("{0:F2}", _column.FooterComputedValue);
                        }
                    }
                }
            }

            this.HeightTracker.ClearHeightTracker();
            this.HeightTracker.CheckHeightTracker();

            //  apply data
            if (this.IsGridAreaLeft)
            {
                this.PART_ListViewLeft.ItemsSource = this.DisplaySource;
                this.PART_ListViewLeft.IsEnabled = true;
            }
            if (this.IsGridAreaCenter)
            {
                this.PART_ListViewCenter.ItemsSource = this.DisplaySource;
                this.PART_ListViewCenter.IsEnabled = true;
            }
            if (this.IsGridAreaRight)
            {
                this.PART_ListViewRight.ItemsSource = this.DisplaySource;
                this.PART_ListViewRight.IsEnabled = true;
            }

            this.HasData   = this.ItemsSource != null;
            this.IsEnabled = true;

            this.HeightTracker.UpdateLayout();
        }
        #endregion


        #region Method - ResetFilters

        private void ResetFilters()
        {
            foreach(DsxColumn _column in this.FilterColumns)
            {
                _column.FilterTextValue = String.Empty;
            }
            RecalcDisplaySource();
        }
        #endregion

        #region Method - GetListView

        private ListView GetListView(EArea columnArea)
        {
            switch(columnArea)
            {
                case EArea.Left:       return this.PART_ListViewLeft;
                case EArea.Center:     return this.PART_ListViewCenter;
                case EArea.Right:      return this.PART_ListViewRight;
            }
            return null;
        }
        #endregion

        #region Method - GetGridView

        private DsxGridView GetGridView(EArea columnArea)
        {
            switch(columnArea)
            {
                case EArea.Left:       return this.PART_GridViewLeft;
                case EArea.Center:     return this.PART_GridViewCenter;
                case EArea.Right:      return this.PART_GridViewRight;
            }
            return null;
        }
        #endregion


        #region Method - SetTheme

        public void SetTheme(string themeColor)
        {
            this.Style       = (Style)this.TryFindResource("dsxDataGridStyle"+themeColor);

            this.HeaderStyle = (Style)this.TryFindResource("dsxHeaderStyle"  +themeColor);
            this.FilterStyle = (Style)this.TryFindResource("dsxFilterStyle"  +themeColor);
            this.FooterStyle = (Style)this.TryFindResource("dsxFooterStyle"  +themeColor);
			
			RebuildLayout();
        }
        #endregion



        #region DP - CornerRadius

        public static readonly DependencyProperty CornerRadiusProperty =
            DependencyProperty.Register("CornerRadius", typeof(CornerRadius), typeof(DsxDataGrid), new PropertyMetadata(new CornerRadius(2)) );

        public GridLength CornerRadius
        {
            get { return (GridLength)GetValue(CornerRadiusProperty); }
            set { SetValue(CornerRadiusProperty, value); }
        }
        #endregion


        #region DP - AreaLeftWidth

        public static readonly DependencyProperty AreaLeftWidthProperty =
            DependencyProperty.Register("AreaLeftWidth", typeof(GridLength), typeof(DsxDataGrid), new PropertyMetadata(new GridLength(100, GridUnitType.Pixel)) );

        /// <summary>
        /// Typically the sum of all columns in the left area + 2
        /// </summary>
        public GridLength AreaLeftWidth
        {
            get { return (GridLength)GetValue(AreaLeftWidthProperty); }
            set { SetValue(AreaLeftWidthProperty, value); }
        }
        #endregion

        #region DP - AreaCenterWidth

        public static readonly DependencyProperty AreaCenterWidthProperty =
            DependencyProperty.Register("AreaCenterWidth", typeof(GridLength), typeof(DsxDataGrid), new PropertyMetadata(new GridLength(100, GridUnitType.Star)) );

        /// <summary>
        /// Typically not set (=100*)
        /// </summary>
        public GridLength AreaCenterWidth
        {
            get { return (GridLength)GetValue(AreaCenterWidthProperty); }
            set { SetValue(AreaCenterWidthProperty, value); }
        }
        #endregion

        #region DP - AreaRightWidth

        public static readonly DependencyProperty AreaRightWidthProperty =
            DependencyProperty.Register("AreaRightWidth", typeof(GridLength), typeof(DsxDataGrid), new PropertyMetadata(new GridLength(100, GridUnitType.Pixel)) );

        /// <summary>
        /// Typically the sum of all columns in the right area + 22
        /// </summary>
        public GridLength AreaRightWidth
        {
            get { return (GridLength)GetValue(AreaRightWidthProperty); }
            set { SetValue(AreaRightWidthProperty, value); }
        }
        #endregion


        #region DP - SplitterLeftWidth

        public static readonly DependencyProperty SplitterLeftWidthProperty =
            DependencyProperty.Register("SplitterLeftWidth", typeof(GridLength), typeof(DsxDataGrid), new PropertyMetadata(new GridLength(3.0)) );

        public GridLength SplitterLeftWidth
        {
            get { return (GridLength)GetValue(SplitterLeftWidthProperty); }
            set { SetValue(SplitterLeftWidthProperty, value); }
        }
        #endregion

        #region DP - SplitterRightWidth

        public static readonly DependencyProperty SplitterRightWidthProperty =
            DependencyProperty.Register("SplitterRightWidth", typeof(GridLength), typeof(DsxDataGrid), new PropertyMetadata(new GridLength(3.0)) );

        public GridLength SplitterRightWidth
        {
            get { return (GridLength)GetValue(SplitterRightWidthProperty); }
            set { SetValue(SplitterRightWidthProperty, value); }
        }
        #endregion

        #region DP - SplitterLeftBackground

        public static readonly DependencyProperty SplitterLeftBackgroundProperty =
            DependencyProperty.Register("SplitterLeftBackground", typeof(Brush), typeof(DsxDataGrid), new PropertyMetadata(Brushes.DarkGray) );

        public Brush SplitterLeftBackground
        {
            get { return (Brush)GetValue(SplitterLeftBackgroundProperty); }
            set { SetValue(SplitterLeftBackgroundProperty, value); }
        }
        #endregion

        #region DP - SplitterRightBackground

        public static readonly DependencyProperty SplitterRightBackgroundProperty =
            DependencyProperty.Register("SplitterRightBackground", typeof(Brush), typeof(DsxDataGrid), new PropertyMetadata(Brushes.DarkGray) );

        public Brush SplitterRightBackground
        {
            get { return (Brush)GetValue(SplitterRightBackgroundProperty); }
            set { SetValue(SplitterRightBackgroundProperty, value); }
        }
        #endregion

        #region DP - SplitterLeftIsSizing

        public static readonly DependencyProperty SplitterLeftIsSizingProperty =
            DependencyProperty.Register("SplitterLeftIsSizing", typeof(bool), typeof(DsxDataGrid), new PropertyMetadata(false) );

        public bool SplitterLeftIsSizing
        {
            get { return (bool)GetValue(SplitterLeftIsSizingProperty); }
            set { SetValue(SplitterLeftIsSizingProperty, value); }
        }
        #endregion

        #region DP - SplitterRightIsSizing

        public static readonly DependencyProperty SplitterRightIsSizingProperty =
            DependencyProperty.Register("SplitterRightIsSizing", typeof(bool), typeof(DsxDataGrid), new PropertyMetadata(false) );

        public bool SplitterRightIsSizing
        {
            get { return (bool)GetValue(SplitterRightIsSizingProperty); }
            set { SetValue(SplitterRightIsSizingProperty, value); }
        }
        #endregion


        #region DP - CellEditingIsEnabled

        public static readonly DependencyProperty CellEditingIsEnabledProperty =
            DependencyProperty.Register("CellEditingIsEnabled", typeof(bool), typeof(DsxDataGrid), new PropertyMetadata(false) );

        public bool CellEditingIsEnabled
        {
            get { return (bool)GetValue(CellEditingIsEnabledProperty); }
            set { SetValue(CellEditingIsEnabledProperty, value); }
        }
        #endregion


        #region DP - CellAdornerIsVisible

        public static readonly DependencyProperty CellAdornerIsVisibleProperty =
            DependencyProperty.Register("CellAdornerIsVisible", typeof(bool), typeof(DsxDataGrid), new PropertyMetadata(false) );

        public bool CellAdornerIsVisible
        {
            get { return (bool)GetValue(CellAdornerIsVisibleProperty); }
            set { SetValue(CellAdornerIsVisibleProperty, value); }
        }
        #endregion

        #region DP - CellAdornerViewBorderBrush

        public static readonly DependencyProperty CellAdornerViewBorderBrushProperty =
            DependencyProperty.Register("CellAdornerViewBorderBrush", typeof(Brush), typeof(DsxDataGrid), new PropertyMetadata( Brushes.DimGray) );

        public Brush CellAdornerViewBorderBrush
        {
            get { return (Brush)GetValue(CellAdornerViewBorderBrushProperty); }
            set { SetValue(CellAdornerViewBorderBrushProperty, value); }
        }
        #endregion

        #region DP - CellAdornerEditableBorderBrush

        public static readonly DependencyProperty CellAdornerEditableBorderBrushProperty =
            DependencyProperty.Register("CellAdornerEditableBorderBrush", typeof(Brush), typeof(DsxDataGrid), new PropertyMetadata( Brushes.DarkGray) );

        public Brush CellAdornerEditableBorderBrush
        {
            get { return (Brush)GetValue(CellAdornerEditableBorderBrushProperty); }
            set { SetValue(CellAdornerEditableBorderBrushProperty, value); }
        }
        #endregion

        #region DP - CellAdornerEditingBorderBrush

        public static readonly DependencyProperty CellAdornerEditingBorderBrushProperty =
            DependencyProperty.Register("CellAdornerEditingBorderBrush", typeof(Brush), typeof(DsxDataGrid), new PropertyMetadata( new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FF404040"))) );

        public Brush CellAdornerEditingBorderBrush
        {
            get { return (Brush)GetValue(CellAdornerEditingBorderBrushProperty); }
            set { SetValue(CellAdornerEditingBorderBrushProperty, value); }
        }
        #endregion

        #region DP - CellAdornerFilterBorderBrush

        public static readonly DependencyProperty CellAdornerFilterBorderBrushProperty =
            DependencyProperty.Register("CellAdornerFilterBorderBrush", typeof(Brush), typeof(DsxDataGrid), new PropertyMetadata( Brushes.DimGray) );

        public Brush CellAdornerFilterBorderBrush
        {
            get { return (Brush)GetValue(CellAdornerFilterBorderBrushProperty); }
            set { SetValue(CellAdornerFilterBorderBrushProperty, value); }
        }
        #endregion

        #region DP - SortAdornerIndicatorBrush

        public static readonly DependencyProperty SortAdornerIndicatorBrushProperty =
            DependencyProperty.Register("SortAdornerIndicatorBrush", typeof(Brush), typeof(DsxDataGrid), new PropertyMetadata( Brushes.DimGray) );

        public Brush SortAdornerIndicatorBrush
        {
            get { return (Brush)GetValue(SortAdornerIndicatorBrushProperty); }
            set { SetValue(SortAdornerIndicatorBrushProperty, value); }
        }
        #endregion



        #region DP - AllowCheckAnyTime

        public static readonly DependencyProperty AllowCheckAnyTimeProperty =
            DependencyProperty.Register("AllowCheckAnyTime", typeof(bool), typeof(DsxDataGrid), new PropertyMetadata(false) );

        public bool AllowCheckAnyTime
        {
            get { return (bool)GetValue(AllowCheckAnyTimeProperty); }
            set { SetValue(AllowCheckAnyTimeProperty, value); }
        }
        #endregion


        #region DP - SortField

        public static readonly DependencyProperty SortFieldProperty =
            DependencyProperty.Register("SortField", typeof(string), typeof(DsxDataGrid), new PropertyMetadata(null, OnSortFieldChanged) );

        public string SortField
        {
            get { return (string)GetValue(SortFieldProperty); }
            set { SetValue(SortFieldProperty, value); }
        }

        private static void OnSortFieldChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
        {
            if (d == null)
            {
                return;
            }

            DsxDataGrid  _context    = (DsxDataGrid)d;
            string       _newValue   = (string)e.NewValue;
            string       _oldValue   = (string)e.OldValue;

            if (_newValue != _oldValue && _context.IsInitialized)
            {
                _context.SetSortColumn(_newValue);
            }
        }

        #endregion


        #region DP - HeaderHeight

        public static readonly DependencyProperty HeaderHeightProperty =
            DependencyProperty.Register("HeaderHeight", typeof(double), typeof(DsxDataGrid), new PropertyMetadata(22.0) );

        public double HeaderHeight
        {
            get { return (double)GetValue(HeaderHeightProperty); }
            set { SetValue(HeaderHeightProperty, value); }
        }
        #endregion

        #region DP - FilterHeight

        public static readonly DependencyProperty FilterHeightProperty =
            DependencyProperty.Register("FilterHeight", typeof(double), typeof(DsxDataGrid), new PropertyMetadata(22.0) );

        public double FilterHeight
        {
            get { return (double)GetValue(FilterHeightProperty); }
            set { SetValue(FilterHeightProperty, value); }
        }
        #endregion

        #region DP - ItemFixHeight

        public static readonly DependencyProperty ItemFixHeightProperty =
            DependencyProperty.Register("ItemFixHeight", typeof(double), typeof(DsxDataGrid), new PropertyMetadata(20.0) );

        public double ItemFixHeight
        {
            get { return (double)GetValue(ItemFixHeightProperty); }
            set { SetValue(ItemFixHeightProperty, value); }
        }
        #endregion

        #region DP - ItemMinHeight

        public static readonly DependencyProperty ItemMinHeightProperty =
            DependencyProperty.Register("ItemMinHeight", typeof(double), typeof(DsxDataGrid), new PropertyMetadata(0.0) );

        public double ItemMinHeight
        {
            get { return (double)GetValue(ItemMinHeightProperty); }
            set { SetValue(ItemMinHeightProperty, value); }
        }
        #endregion

        #region DP - ItemMaxHeight

        public static readonly DependencyProperty ItemMaxHeightProperty =
            DependencyProperty.Register("ItemMaxHeight", typeof(double), typeof(DsxDataGrid), new PropertyMetadata(0.0) );

        public double ItemMaxHeight
        {
            get { return (double)GetValue(ItemMaxHeightProperty); }
            set { SetValue(ItemMaxHeightProperty, value); }
        }
        #endregion

        #region DP - FooterHeight

        public static readonly DependencyProperty FooterHeightProperty =
            DependencyProperty.Register("FooterHeight", typeof(double), typeof(DsxDataGrid), new PropertyMetadata(21.0) );

        public double FooterHeight
        {
            get { return (double)GetValue(FooterHeightProperty); }
            set { SetValue(FooterHeightProperty, value); }
        }
        #endregion


        #region DP - Columns

        public static readonly DependencyProperty ColumnsProperty =
            DependencyProperty.Register("Columns", typeof(GridViewColumnCollection), typeof(DsxDataGrid), new PropertyMetadata(null));

        public GridViewColumnCollection Columns
        {
            get { return (GridViewColumnCollection)GetValue(ColumnsProperty); }
            set { SetValue(ColumnsProperty, value); }
        }
        #endregion

        #region DP - HeightTracker

        public static readonly DependencyProperty HeightTrackerProperty =
            DependencyProperty.Register("HeightTracker", typeof(DsxHeightTracker), typeof(DsxDataGrid), new PropertyMetadata(null) );

        public DsxHeightTracker HeightTracker
        {
            get         { return (DsxHeightTracker)GetValue(HeightTrackerProperty); }
            private set { SetValue(HeightTrackerProperty, value); }
        }
        #endregion


        #region DP - ComputedHeaderVisibility

        public static readonly DependencyProperty ComputedHeaderVisibilityProperty =
            DependencyProperty.Register("ComputedHeaderVisibility", typeof(Visibility), typeof(DsxDataGrid), new PropertyMetadata(Visibility.Visible));

        public Visibility ComputedHeaderVisibility
        {
            get         { return (Visibility)GetValue(ComputedHeaderVisibilityProperty); }
            private set { SetValue(ComputedHeaderVisibilityProperty, value); }
        }
        #endregion

        #region DP - ComputedFilterVisibility

        public static readonly DependencyProperty ComputedFilterVisibilityProperty =
            DependencyProperty.Register("ComputedFilterVisibility", typeof(Visibility), typeof(DsxDataGrid), new PropertyMetadata(Visibility.Visible));

        public Visibility ComputedFilterVisibility
        {
            get         { return (Visibility)GetValue(ComputedFilterVisibilityProperty); }
            private set { SetValue(ComputedFilterVisibilityProperty, value); }
        }
        #endregion

        #region DP - ComputedFilterClearVisibility

        public static readonly DependencyProperty ComputedFilterClearVisibilityProperty =
            DependencyProperty.Register("ComputedFilterClearVisibility", typeof(Visibility), typeof(DsxDataGrid), new PropertyMetadata(Visibility.Hidden));

        public Visibility ComputedFilterClearVisibility
        {
            get         { return (Visibility)GetValue(ComputedFilterClearVisibilityProperty); }
            private set { SetValue(ComputedFilterClearVisibilityProperty, value); }
        }
        #endregion

        #region DP - ComputedFooterVisibility

        public static readonly DependencyProperty ComputedFooterVisibilityProperty =
            DependencyProperty.Register("ComputedFooterVisibility", typeof(Visibility), typeof(DsxDataGrid), new PropertyMetadata(Visibility.Visible));

        public Visibility ComputedFooterVisibility
        {
            get         { return (Visibility)GetValue(ComputedFooterVisibilityProperty); }
            private set { SetValue(ComputedFooterVisibilityProperty, value); }
        }
        #endregion



        #region DP - HeaderVisibility

        public static readonly DependencyProperty HeaderVisibilityProperty =
            DependencyProperty.Register("HeaderVisibility", typeof(EVisibility), typeof(DsxDataGrid), new PropertyMetadata(EVisibility.Collapsed, OnGridLayoutPartChanged));

        public EVisibility HeaderVisibility
        {
            get { return (EVisibility)GetValue(HeaderVisibilityProperty); }
            set { SetValue(HeaderVisibilityProperty, value); }
        }
        #endregion

        #region DP - FilterVisibility

        public static readonly DependencyProperty FilterVisibilityProperty =
            DependencyProperty.Register("FilterVisibility", typeof(EVisibility), typeof(DsxDataGrid), new PropertyMetadata(EVisibility.Collapsed, OnGridLayoutPartChanged));

        public EVisibility FilterVisibility
        {
            get { return (EVisibility)GetValue(FilterVisibilityProperty); }
            set { SetValue(FilterVisibilityProperty, value); }
        }
        #endregion

        #region DP - FooterVisibility

        public static readonly DependencyProperty FooterVisibilityProperty =
            DependencyProperty.Register("FooterVisibility", typeof(EVisibility), typeof(DsxDataGrid), new PropertyMetadata(EVisibility.Collapsed, OnGridLayoutPartChanged));

        public EVisibility FooterVisibility
        {
            get { return (EVisibility)GetValue(FooterVisibilityProperty); }
            set { SetValue(FooterVisibilityProperty, value); }
        }
        #endregion


        #region DP - HorizontalScrollbarVisibility
        public static readonly DependencyProperty HorizontalScrollbarVisibilityProperty =
            DependencyProperty.Register("HorizontalScrollbarVisibility", typeof(ScrollBarVisibility), typeof(DsxDataGrid), new PropertyMetadata(ScrollBarVisibility.Auto));

        public ScrollBarVisibility HorizontalScrollbarVisibility
        {
            get { return (ScrollBarVisibility)GetValue(HorizontalScrollbarVisibilityProperty); }
            set { SetValue(HorizontalScrollbarVisibilityProperty, value); }
        }
        #endregion

        #region DP - VerticalScrollbarVisibility

        public static readonly DependencyProperty VerticalScrollbarVisibilityProperty =
            DependencyProperty.Register("VerticalScrollbarVisibility", typeof(ScrollBarVisibility), typeof(DsxDataGrid), new PropertyMetadata(ScrollBarVisibility.Visible));

        public ScrollBarVisibility VerticalScrollbarVisibility
        {
            get { return (ScrollBarVisibility)GetValue(VerticalScrollbarVisibilityProperty); }
            set { SetValue(VerticalScrollbarVisibilityProperty, value); }
        }
        #endregion

       

        #region DP - HorizontalGridLinesIsVisible

        public static readonly DependencyProperty HorizontalGridLinesIsVisibleProperty =
            DependencyProperty.Register("HorizontalGridLinesIsVisible", typeof(bool), typeof(DsxDataGrid), new PropertyMetadata(false, OnGridLayoutPartChanged) );

        public bool HorizontalGridLinesIsVisible
        {
            get { return (bool)GetValue(HorizontalGridLinesIsVisibleProperty); }
            set { SetValue(HorizontalGridLinesIsVisibleProperty, value); }
        }
        #endregion

        #region DP - VerticalGridLinesIsVisible

        public static readonly DependencyProperty VerticalGridLinesIsVisibleProperty =
            DependencyProperty.Register("VerticalGridLinesIsVisible", typeof(bool), typeof(DsxDataGrid), new PropertyMetadata(false, OnGridLayoutPartChanged) );

        public bool VerticalGridLinesIsVisible
        {
            get { return (bool)GetValue(VerticalGridLinesIsVisibleProperty); }
            set { SetValue(VerticalGridLinesIsVisibleProperty, value); }
        }
        #endregion

        #region DP - HorizontalGridLinesBrush

        public static readonly DependencyProperty HorizontalGridLinesBrushProperty =
            DependencyProperty.Register("HorizontalGridLinesBrush", typeof(Brush), typeof(DsxDataGrid), new PropertyMetadata( Brushes.DimGray) );

        public Brush HorizontalGridLinesBrush
        {
            get { return (Brush)GetValue(HorizontalGridLinesBrushProperty); }
            set { SetValue(HorizontalGridLinesBrushProperty, value); }
        }
        #endregion

        #region DP - VerticalGridLinesBrush

        public static readonly DependencyProperty VerticalGridLinesBrushProperty =
            DependencyProperty.Register("VerticalGridLinesBrush", typeof(Brush), typeof(DsxDataGrid), new PropertyMetadata( Brushes.DimGray) );

        public Brush VerticalGridLinesBrush
        {
            get { return (Brush)GetValue(VerticalGridLinesBrushProperty); }
            set { SetValue(VerticalGridLinesBrushProperty, value); }
        }
        #endregion

        #region DP - SelectedRowBrush

        public static readonly DependencyProperty SelectedRowBrushProperty =
            DependencyProperty.Register("SelectedRowBrush", typeof(Brush), typeof(DsxDataGrid), new PropertyMetadata( new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FFE8E8E8"))) );

        public Brush SelectedRowBrush
        {
            get { return (Brush)GetValue(SelectedRowBrushProperty); }
            set { SetValue(SelectedRowBrushProperty, value); }
        }
        #endregion

        #region DP - AlternatingRowBrushes

        public static readonly DependencyProperty AlternatingRowBrushesProperty =
            DependencyProperty.Register("AlternatingRowBrushes", typeof(List<Brush>), typeof(DsxDataGrid), new PropertyMetadata(new List<Brush>() ) );

        public List<Brush> AlternatingRowBrushes
        {
            get { return (List<Brush>)GetValue(AlternatingRowBrushesProperty); }
            set { SetValue(AlternatingRowBrushesProperty, value); }
        }
        #endregion


        #region DP - IsVirtualizing

        public static readonly DependencyProperty IsVirtualizingProperty =
            DependencyProperty.Register("IsVirtualizing", typeof(bool), typeof(DsxDataGrid), new PropertyMetadata(true));

        public bool IsVirtualizing
        {
            get { return (bool)GetValue(IsVirtualizingProperty); }
            set { SetValue(IsVirtualizingProperty, value); }
        }
        #endregion

        #region DP - HasData

        public static readonly DependencyProperty HasDataProperty =
            DependencyProperty.Register("HasData", typeof(bool?), typeof(DsxDataGrid), new PropertyMetadata(null, OnHasDataChanged));

        public bool? HasData
        {
            get         { return (bool?)GetValue(HasDataProperty); }
            private set { SetValue(HasDataProperty, value); }
        }

        private static void OnHasDataChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
        {
            if (d == null || e.NewValue == null)
            {
                return;
            }

            DsxDataGrid     _context    = (DsxDataGrid)d;
            bool?           _newValue   = (bool?)e.NewValue;
            bool?           _oldValue   = (bool?)e.OldValue;

            switch(_context.HeaderVisibility)
            {
                case EVisibility.Auto:       _context.ComputedHeaderVisibility = (bool)_newValue ? Visibility.Visible : Visibility.Hidden;   break;
                case EVisibility.Visible:    _context.ComputedHeaderVisibility = Visibility.Visible;                                   break;
                case EVisibility.Hidden:     _context.ComputedHeaderVisibility = Visibility.Hidden;                                    break;
                case EVisibility.Collapsed:  _context.ComputedHeaderVisibility = Visibility.Collapsed;                                 break;
            }

            switch(_context.FilterVisibility)
            {
                case EVisibility.Auto:       _context.ComputedFilterVisibility = (bool)_newValue ? Visibility.Visible : Visibility.Hidden;   break;
                case EVisibility.Visible:    _context.ComputedFilterVisibility = Visibility.Visible;                                   break;
                case EVisibility.Hidden:     _context.ComputedFilterVisibility = Visibility.Hidden;                                    break;
                case EVisibility.Collapsed:  _context.ComputedFilterVisibility = Visibility.Collapsed;                                 break;
            }

            switch(_context.FooterVisibility)
            {
                case EVisibility.Auto:       _context.ComputedFooterVisibility = (bool)_newValue ? Visibility.Visible : Visibility.Hidden;   break;
                case EVisibility.Visible:    _context.ComputedFooterVisibility = Visibility.Visible;                                   break;
                case EVisibility.Hidden:     _context.ComputedFooterVisibility = Visibility.Hidden;                                    break;
                case EVisibility.Collapsed:  _context.ComputedFooterVisibility = Visibility.Collapsed;                                 break;
            }

            if (!String.IsNullOrEmpty(_context.SortField))
            {
                _context.SetSortColumn(_context.SortField);
            }
        }
        #endregion


        #region DP - HeaderStyle

        public static readonly DependencyProperty HeaderStyleProperty =
            DependencyProperty.Register("HeaderStyle", typeof(Style), typeof(DsxDataGrid), new PropertyMetadata(null, OnHeaderStyleChanged) );

        public Style HeaderStyle
        {
            get { return (Style)GetValue(HeaderStyleProperty); }
            set { SetValue(HeaderStyleProperty, value); }
        }

        private static void OnHeaderStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
        {
            if (d == null)
            {
                return;
            }

            DsxDataGrid _context    = (DsxDataGrid)d;
            Style       _newValue   = (Style)e.NewValue;
            Style       _oldValue   = (Style)e.OldValue;

            if (_newValue != _oldValue)
            {
                //  because the applied style wont change (see DsxHeaderStyleConverter)
                //  we have to make sure the style is re-evaluted
                Style _style;

                _style = _context.PART_GridViewLeft  .ColumnHeaderContainerStyle;
                         _context.PART_GridViewLeft  .ColumnHeaderContainerStyle = null;
                         _context.PART_GridViewLeft  .ColumnHeaderContainerStyle = _style;

                _style = _context.PART_GridViewCenter.ColumnHeaderContainerStyle;
                         _context.PART_GridViewCenter.ColumnHeaderContainerStyle = null;
                         _context.PART_GridViewCenter.ColumnHeaderContainerStyle = _style;
                
                _style = _context.PART_GridViewRight .ColumnHeaderContainerStyle;
                         _context.PART_GridViewRight .ColumnHeaderContainerStyle = null;
                         _context.PART_GridViewRight .ColumnHeaderContainerStyle = _style;

                Border   _fillThumb = ElementHelper.FindVisualChild<Border>(_context.ScrollViewerRight, "PART_HeaderThumb");
                         
                         _fillThumb.GetBindingExpression(Border.CornerRadiusProperty   ).UpdateTarget();
                         _fillThumb.GetBindingExpression(Border.BackgroundProperty     ).UpdateTarget();
                         _fillThumb.GetBindingExpression(Border.BorderBrushProperty    ).UpdateTarget();
                         _fillThumb.GetBindingExpression(Border.PaddingProperty        ).UpdateTarget();
                         _fillThumb.GetBindingExpression(Border.BorderThicknessProperty).UpdateTarget();

            }
        }
        #endregion

        #region DP - FilterStyle

        public static readonly DependencyProperty FilterStyleProperty =
            DependencyProperty.Register("FilterStyle", typeof(Style), typeof(DsxDataGrid), new PropertyMetadata(null, OnFilterStyleChanged) );

        public Style FilterStyle
        {
            get { return (Style)GetValue(FilterStyleProperty); }
            set { SetValue(FilterStyleProperty, value); }
        }

        private static void OnFilterStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
        {
            if (d == null)
            {
                return;
            }

            DsxDataGrid _context    = (DsxDataGrid)d;
            Style       _newValue   = (Style)e.NewValue;
            Style       _oldValue   = (Style)e.OldValue;

            if (_newValue != _oldValue)
            {
                //  because the applied style wont change (see DsxFilterStyleConverter)
                //  we have to make sure the style is re-evaluted
                Style _style;

                _style = _context.PART_GridViewLeft  .ColumnFilterContainerStyle;
                         _context.PART_GridViewLeft  .ColumnFilterContainerStyle = null;
                         _context.PART_GridViewLeft  .ColumnFilterContainerStyle = _style;

                _style = _context.PART_GridViewCenter.ColumnFilterContainerStyle;
                         _context.PART_GridViewCenter.ColumnFilterContainerStyle = null;
                         _context.PART_GridViewCenter.ColumnFilterContainerStyle = _style;
                
                _style = _context.PART_GridViewRight .ColumnFilterContainerStyle;
                         _context.PART_GridViewRight .ColumnFilterContainerStyle = null;
                         _context.PART_GridViewRight .ColumnFilterContainerStyle = _style;

            }
        }

        #endregion

        #region DP - FooterStyle

        public static readonly DependencyProperty FooterStyleProperty =
            DependencyProperty.Register("FooterStyle", typeof(Style), typeof(DsxDataGrid), new PropertyMetadata(null, OnFooterStyleChanged) );

        public Style FooterStyle
        {
            get { return (Style)GetValue(FooterStyleProperty); }
            set { SetValue(FooterStyleProperty, value); }
        }

        private static void OnFooterStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
        {
            if (d == null)
            {
                return;
            }

            DsxDataGrid _context    = (DsxDataGrid)d;
            Style       _newValue   = (Style)e.NewValue;
            Style       _oldValue   = (Style)e.OldValue;

            if (_newValue != _oldValue)
            {
                //  because the applied style wont change (see DsxFooterStyleConverter)
                //  we have to make sure the style is re-evaluted
                Style _style;

                _style = _context.PART_GridViewLeft  .ColumnFooterContainerStyle;
                         _context.PART_GridViewLeft  .ColumnFooterContainerStyle = null;
                         _context.PART_GridViewLeft  .ColumnFooterContainerStyle = _style;

                _style = _context.PART_GridViewCenter.ColumnFooterContainerStyle;
                         _context.PART_GridViewCenter.ColumnFooterContainerStyle = null;
                         _context.PART_GridViewCenter.ColumnFooterContainerStyle = _style;
                
                _style = _context.PART_GridViewRight .ColumnFooterContainerStyle;
                         _context.PART_GridViewRight .ColumnFooterContainerStyle = null;
                         _context.PART_GridViewRight .ColumnFooterContainerStyle = _style;

                Border   _fillThumb = ElementHelper.FindVisualChild<Border>(_context.ScrollViewerRight, "PART_FooterThumb");

                         _fillThumb.GetBindingExpression(Border.CornerRadiusProperty   ).UpdateTarget();
                         _fillThumb.GetBindingExpression(Border.BackgroundProperty     ).UpdateTarget();
                         _fillThumb.GetBindingExpression(Border.BorderBrushProperty    ).UpdateTarget();
                         _fillThumb.GetBindingExpression(Border.PaddingProperty        ).UpdateTarget();
                         _fillThumb.GetBindingExpression(Border.BorderThicknessProperty).UpdateTarget();
            }
        }
        #endregion

        #region DP - RowCellStyle

        public static readonly DependencyProperty RowCellStyleProperty =
            DependencyProperty.Register("RowCellStyle", typeof(Style), typeof(DsxDataGrid), new PropertyMetadata(null) );

        public Style RowCellStyle
        {
            get { return (Style)GetValue(RowCellStyleProperty); }
            set { SetValue(RowCellStyleProperty, value); }
        }
        #endregion


        #region DP Callback - OnGridLayoutPartChanged

        private static void OnGridLayoutPartChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
        {
            if (d == null || e.NewValue == null)
            {
                return;
            }

            DsxDataGrid _context        = (DsxDataGrid)d;
			
			_context.RebuildLayout();
        }
        #endregion
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Switzerland Switzerland
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions