private bool TryGetRecycledCell(ColumnBase column, out Cell cell)
        {
            cell = null;

            if (m_recyclingBins == null)
            {
                return(false);
            }

            // Make sure the cell recycling group is up-to-date.
            var dataGridContext = this.DataGridContext;

            if (dataGridContext != null)
            {
                var propertyDescription = ItemsSourceHelper.CreateOrGetPropertyDescriptionFromColumn(dataGridContext, column, null);
                ItemsSourceHelper.UpdateColumnFromPropertyDescription(column, dataGridContext.DataGridControl.DefaultCellEditors, dataGridContext.AutoCreateForeignKeyConfigurations, propertyDescription);
            }

            var recyclingGroup = this.GetRecyclingGroup(column);
            var recycleBin     = default(LinkedList <Cell>);

            if (m_recyclingBins.TryGetValue(recyclingGroup, out recycleBin))
            {
                // Try to recycle a cell that has already the appropriate column in order to minimize the cell's initialization time.
                var targetNode = default(LinkedListNode <Cell>);

                for (var node = recycleBin.Last; node != null; node = node.Previous)
                {
                    targetNode = node;

                    if (targetNode.Value.ParentColumn == column)
                    {
                        break;
                    }
                }

                // From here, the target node is either:
                //   1. The cell with minimal initialization time.
                //   2. The oldest cell.
                //   3. null in case of an empty bin.
                if (targetNode != null)
                {
                    cell = targetNode.Value;
                    recycleBin.Remove(targetNode);
                }
            }

            return(cell != null);
        }
예제 #2
0
        protected internal virtual void SetupDisplayMemberBinding(DataGridContext dataGridContext)
        {
            // Bind the cell content.
            var column = this.ParentColumn as Column;

            if (column != null)
            {
                var displayMemberBinding = default(BindingBase);
                var dataItem             = this.ParentRow.DataContext;

                // If the dataContext is our ParentRow, we do not create any binding
                if (dataItem != this.ParentRow)
                {
                    displayMemberBinding = column.GetDisplayMemberBinding();

                    if (displayMemberBinding == null)
                    {
                        if (dataGridContext == null)
                        {
                            throw new InvalidOperationException("An attempt was made to create a DisplayMemberBinding before the DataGridContext has been initialized.");
                        }

                        if (!DesignerProperties.GetIsInDesignMode(this))
                        {
                            var propertyDescription = ItemsSourceHelper.CreateOrGetPropertyDescriptionFromColumn(dataGridContext, column, (dataItem != null) ? dataItem.GetType() : null);
                            ItemsSourceHelper.UpdateColumnFromPropertyDescription(column, dataGridContext.DataGridControl.DefaultCellEditors, dataGridContext.AutoCreateForeignKeyConfigurations, propertyDescription);

                            displayMemberBinding = column.GetDisplayMemberBinding();
                        }

                        column.IsBindingAutoCreated = true;
                    }
                }

                if (displayMemberBinding != null)
                {
                    m_canBeRecycled = DataCell.VerifyDisplayMemberBinding(displayMemberBinding);

                    BindingOperations.SetBinding(this, Cell.ContentProperty, displayMemberBinding);

                    var xmlElement = this.GetValue(Cell.ContentProperty) as XmlElement;
                    if (xmlElement != null)
                    {
                        // Convert binding to an InnerXML binding in the case we are bound on a XmlElement
                        // to be able to refresh the data in the XML.

                        //under any circumstances, a cell that is bound to XML cannot be recycled
                        m_canBeRecycled = false;

                        this.ClearDisplayMemberBinding();

                        var xmlElementBinding = new Binding("InnerXml");
                        xmlElementBinding.Source = xmlElement;
                        xmlElementBinding.Mode   = BindingMode.TwoWay;
                        xmlElementBinding.UpdateSourceTrigger = UpdateSourceTrigger.Explicit;

                        BindingOperations.SetBinding(this, Cell.ContentProperty, xmlElementBinding);
                    }
                }
                else
                {
                    this.ClearDisplayMemberBinding();
                }
            }
            else
            {
                this.ClearDisplayMemberBinding();
            }
        }