/// <summary>
 /// Create an XAML element describing the field.
 /// </summary>
 /// <param name="fieldDefinition">The CLR description of the field.</param>
 public FieldDefinitionElement(ReportField fieldDefinition)
     : base(DynamicReport.namespacePresentation + "FieldDefinition")
 {
     // Initialize the object.
     Add(new XAttribute("ColumnId", fieldDefinition.ColumnId));
     Add(new XAttribute("Description", fieldDefinition.Description));
     Add(new XAttribute("Width", fieldDefinition.Width));
 }
 /// <summary>
 /// Create an XAML element describing the column.
 /// </summary>
 /// <param name="reportColumn">The CLR description of the column.</param>
 public ColumnDefinitionElement(ReportColumn reportColumn, ReportField fieldDefinition)
     : base(DynamicReport.namespacePresentation + "ColumnDefinition")
 {
     // The 'Width' attribute defaults to the width specified by the FieldDefinition.
     Add(new XAttribute("ColumnId", reportColumn.ColumnId));
     if (reportColumn.Width != fieldDefinition.Width)
     {
         Add(new XAttribute("Width", reportColumn.Width));
     }
 }
 /// <summary>
 /// Handles a change to the Width property.
 /// </summary>
 /// <param name="dependencyObject">The object posessing the property that has changed.</param>
 /// <param name="dependencyPropertyChangedEventArgs">Information about the property change.</param>
 private static void OnWidthChanged(DependencyObject dependencyObject,
                                    DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
 {
     if (dependencyObject is ReportField)
     {
         ReportField fieldDefinition = dependencyObject as ReportField;
         if (fieldDefinition.PropertyChanged != null)
         {
             fieldDefinition.PropertyChanged(fieldDefinition, new PropertyChangedEventArgs("Width"));
         }
     }
 }
Exemple #4
0
        /// <summary>
        /// Removes the element at the specified index of the MarkThree.Windows.Controls.ReportColumnCollection.
        /// </summary>
        /// <param name="index">The location where the element will be removed.</param>
        public void RemoveAt(int index)
        {
            // The ColumnDefinition events need to be unhooked from this collection when it is removed.
            ReportField fieldDefinition = this.list[index];

            fieldDefinition.PropertyChanged -= new System.ComponentModel.PropertyChangedEventHandler(fieldDefinition_PropertyChanged);

            // The list and dictionary are updated at the same time to remove the element.
            this.list.RemoveAt(index);
            this.fieldDefinitionMap.Remove(fieldDefinition.ColumnId);

            // This will broadcast a notification that the collection has been modified.  This event is typically used to
            // apply the changes to a persistent version of the user preferences, such as an XAML document.
            RaiseEvent(new CollectionChangedEventArgs(ReportFieldCollection.CollectionChangedEvent, UndoAction.Create,
                                                      CollectionChangedAction.Remove, fieldDefinition));
        }
Exemple #5
0
        /// <summary>
        /// Determins whether the MarkThree.Windows.Controls.ReportColumnCollection contains the specified key.
        /// </summary>
        /// <param name="value">A key to a ColumnDefinition item.</param>
        /// <returns>True if the collection contains an item with the specified key, false otherwise.</returns>
        public bool Contains(object value)
        {
            // The hashtable is used to indicate if the given key exists in the collection.
            if (value is ReportField)
            {
                ReportField fieldDefinition = value as ReportField;
                return(this.fieldDefinitionMap.ContainsKey(fieldDefinition.ColumnId));
            }

            // The value can also be the key used to identify the field.
            if (value is string)
            {
                string columnId = value as string;
                return(this.fieldDefinitionMap.ContainsKey(columnId));
            }

            // No other object type can be found in this collection.
            return(false);
        }
Exemple #6
0
        /// <summary>
        /// Gets or sets the ColumnDefinition at the specified index.
        /// </summary>
        /// <param name="index">The index of the element.</param>
        /// <returns>The object at the given index.</returns>
        public object this[int index]
        {
            get
            {
                return(this.list[index]);
            }

            set
            {
                // The list and the dictionary must be udpated at the same time.
                ReportField fieldDefinition = this.list[index];
                this.list[index] = value as ReportField;
                this.fieldDefinitionMap[fieldDefinition.ColumnId] = value as ReportField;

                // This will broadcast a notification that the collection has been modified.  This event is typically used to
                // apply the changes to a persistent version of the user preferences, such as an XAML document.
                RaiseEvent(new CollectionChangedEventArgs(ReportFieldCollection.CollectionChangedEvent, UndoAction.Create,
                                                          CollectionChangedAction.Replace, value, fieldDefinition));
            }
        }
Exemple #7
0
        /// <summary>
        /// Removes the first occurence of the specified element from the MarkThree.Windows.Controls.ReportColumnCollection.
        /// </summary>
        /// <param name="value">The element to be removed.</param>
        public void Remove(object value)
        {
            // The XAML parser only recognizes the generic IList interfaces, so incoming values need to be qualified to be added to
            // this collection.
            if (value is ReportField)
            {
                // The ColumnDefinition events need to be unhooked from this collection when it is removed.
                ReportField fieldDefinition = value as ReportField;
                fieldDefinition.PropertyChanged -= new System.ComponentModel.PropertyChangedEventHandler(fieldDefinition_PropertyChanged);

                // The list and dictionary are updated at the same time to remove the element.
                this.list.Remove(fieldDefinition);
                this.fieldDefinitionMap.Remove(fieldDefinition.ColumnId);

                // This will broadcast a notification that the collection has been modified.  This event is typically used to
                // apply the changes to a persistent version of the user preferences, such as an XAML document.
                RaiseEvent(new CollectionChangedEventArgs(ReportFieldCollection.CollectionChangedEvent, UndoAction.Create,
                                                          CollectionChangedAction.Remove, fieldDefinition));
            }
        }
Exemple #8
0
        /// <summary>
        /// Inserts an element into the MarkThree.Windows.Controls.ReportColumnCollection at the specified index.
        /// </summary>
        /// <param name="index">The index of the new element.</param>
        /// <param name="value">The new element to be placed in the collection.</param>
        public void Insert(int index, object value)
        {
            // The XAML parser only recognizes the generic IList interfaces, so incoming values need to be qualified to be added to
            // this collection.
            if (value is ReportField)
            {
                // Column definitions are linked into the event handler for this collection so that any change to the individual
                // definition sets off a chain reaction of updates
                ReportField fieldDefinition = value as ReportField;
                fieldDefinition.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(fieldDefinition_PropertyChanged);

                // The list maintains the order for user interfaces and the dictionary is used for fast access to the column based
                // on the ColumnId.
                this.list.Insert(index, fieldDefinition);
                this.fieldDefinitionMap.Add(fieldDefinition.ColumnId, fieldDefinition);

                // This will broadcast a notification that the collection has been modified.  This event is typically used to
                // apply the changes to a persistent version of the user preferences, such as an XAML document.
                RaiseEvent(new CollectionChangedEventArgs(ReportFieldCollection.CollectionChangedEvent, UndoAction.Create,
                                                          CollectionChangedAction.Add, fieldDefinition, index));
            }
        }
Exemple #9
0
        /// <summary>
        /// Adds a MarkThree.Windows.Controls.ColumnDefinition to the end of the collection.
        /// </summary>
        /// <param name="value">The value to be added to the end of the collection.</param>
        /// <returns>0</returns>
        public int Add(object value)
        {
            // The XAML parser only recognizes the generic IList interfaces, so incoming values need to be qualified to be added to
            // this collection.
            if (value is ReportField)
            {
                // Column definitions are linked into the event handler for this collection so that any change to the individual
                // definition sets off a chain reaction of updates
                ReportField fieldDefinition = value as ReportField;
                fieldDefinition.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(fieldDefinition_PropertyChanged);

                // The list maintains the order for user interfaces and the dictionary is used for fast access to the column based
                // on the ColumnId.
                this.list.Add(fieldDefinition);
                this.fieldDefinitionMap.Add(fieldDefinition.ColumnId, fieldDefinition);

                // This table maps the data type to a field that can display that data type.
                foreach (Type type in fieldDefinition.Types)
                {
                    if (this.templateTypeColumnIdMap.ContainsKey(type))
                    {
                        this.templateTypeColumnIdMap[type] = fieldDefinition.ColumnId;
                    }
                    else
                    {
                        this.templateTypeColumnIdMap.Add(type, fieldDefinition.ColumnId);
                    }
                }

                // This will broadcast a notification that the collection has been modified.  This event is typically used to
                // apply the changes to a persistent version of the user preferences, such as an XAML document.
                RaiseEvent(new CollectionChangedEventArgs(ReportFieldCollection.CollectionChangedEvent, UndoAction.Create,
                                                          CollectionChangedAction.Add, fieldDefinition));
            }

            // This is here to satisfy the interface specification.
            return(0);
        }
Exemple #10
0
 public bool TryGetValue(string key, out ReportField value)
 {
     return(this.fieldDefinitionMap.TryGetValue(key, out value));
 }
Exemple #11
0
        /// <summary>
        /// Handles the mouse button being released over a column header.
        /// </summary>
        /// <param name="state">The thread initialization parameter.</param>
        protected override void OnMouseUp(MouseButtonEventArgs e)
        {
            // This gets the location of the mouse in document coordinates.
            Point mouseLocation = e.GetPosition(this);

            // Evaluate the state of the keyboard.  Key combinations involving the shift and control keys will alter the areas that
            // are selected.
            bool isShiftKeyPressed   = ((Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift);
            bool isControlKeyPressed = ((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control);

            // The mouse state indications what action should be taken when the mouse button is released.
            switch (this.mouseState)
            {
            case MouseState.ResizingColumn:

                // At the conclusion of the resizing operation a decision is made to remove or change the width of a column.  If
                // the size is reduced to zero (or less), this gesture is taken as a command to remove the column.  Any positive
                // value for a width will result in a column change command.
                double columnWidth = this.anchorColumn.Width + (mouseLocation.X - this.anchorPoint.X);
                columnWidth = columnWidth < 0.0 ? 0.0 : columnWidth;
                if (this.ResizeMouseMove != null)
                {
                    this.ResizeMouseMove(this, new ResizeColumnEventArgs(this.anchorColumn, columnWidth, true));
                }
                if (columnWidth <= 0)
                {
                    this.ReportGrid.Columns.Remove(this.anchorColumn);
                }
                else
                {
                    this.ReportGrid.Columns.SetColumnWidth(this.anchorColumn, columnWidth);
                }

                // This will hide the popup until it is needed again.
                this.columnWidthPopup.IsOpen = false;

                // This is a momentary button: the column heading will loose the selection state when the button is released.
                foreach (ReportCell reportCell in this.headerCells)
                {
                    reportCell.IsSelected = false;
                }

                break;

            case MouseState.ButtonDown:

                // This will sort the document by one or more selected columns.  The control key is used to select multiple columns
                // similar to the selection mode of Microsoft Office.  The first step to sorting is to find out which column in the
                // view has been selected for sorting.
                ReportColumn reportColumn    = this.ReportGrid.Columns.FindColumnAt(mouseLocation.X);
                ReportField  fieldDefinition = this.ReportGrid.Fields[reportColumn.ColumnId];

                // The 'SortTemplate' attribute is used to distinguish columns that can be selected (usually columns that have user
                // input can be selected) versus columns that can be sorted.
                if (!fieldDefinition.IsSelectable)
                {
                    // If the control key is kept pressed, then the selected sort columns will be combined.  Otherwise, any
                    // previously selected sort column is discarded.
                    if (!isControlKeyPressed)
                    {
                        while (this.sortOrder.Count > 1 && this.sortOrder[this.sortOrder.Count - 1].Column != fieldDefinition)
                        {
                            this.sortOrder.Remove(this.sortOrder[0]);
                        }
                    }

                    // The direction of the sorting in a column can be toggled each time it is selected.  This requires a test to
                    // make sure that the same column has been selected.  Of course, if there is nothing in the list of sorting
                    // columns, then the list is initialize with an ascending sort.
                    if (this.sortOrder.Count != 0)
                    {
                        // Find the last sort column in the sort specification.  If it matches the last column selected, then the
                        // order of the sorting is toggled.  If it doesn't match, then the column is added to the list of columns
                        // when the control key is pressed or used to initialize the list when the control key is not pressed.
                        SortItem sortItem = this.sortOrder[this.sortOrder.Count - 1];
                        if (sortItem.Column == fieldDefinition)
                        {
                            sortItem.SortOrder = sortItem.SortOrder == SortOrder.Ascending ? SortOrder.Descending :
                                                 SortOrder.Ascending;
                        }
                        else
                        {
                            if (!isControlKeyPressed)
                            {
                                this.sortOrder.Remove(sortItem);
                            }
                            this.sortOrder.Add(new SortItem(fieldDefinition, SortOrder.Ascending));
                        }
                    }
                    else
                    {
                        // This will initialize the list of sort columns when the list is empty.
                        this.sortOrder.Add(new SortItem(fieldDefinition, SortOrder.Ascending));
                    }

                    TeraqueCommands.SortReport.Execute(new SortEventArgs(this.sortOrder), this);
                }

                // This is a momentary button: the column heading will loose the selection state when the button is released.
                foreach (ReportCell reportCell in this.headerCells)
                {
                    reportCell.IsSelected = false;
                }

                break;

            case MouseState.DraggingColumn:

                // The action taken when the dragging operation is complete depends on whether a valid destination is selected or
                // whether the column is meant to be deleted.
                switch (this.destinationState)
                {
                case DropAction.Select:

                    // This will move the column from its current location to the desired location.
                    if (this.destinationPopup.Visibility == Visibility.Visible)
                    {
                        // When the column is removed from the list, all the columns that appeared after the removed column will be shifted to
                        // the left.  This will adjust the target index so that the column will be re-inserted into the list at the desired
                        // index after being removed.
                        int newIndex = this.destinationColumn == null ? this.ReportGrid.Columns.Count :
                                       this.ReportGrid.Columns.IndexOf(this.destinationColumn);
                        int oldIndex = this.ReportGrid.Columns.IndexOf(this.anchorColumn);
                        newIndex = oldIndex < newIndex ? newIndex - 1 : newIndex;
                        this.ReportGrid.Columns.Move(oldIndex, newIndex);
                    }

                    break;

                case DropAction.Delete:

                    // This will delete the column from the view.
                    this.ReportGrid.Columns.Remove(this.anchorColumn);

                    break;
                }

                // This is a momentary button: the column heading will loose the selection state when the button is released.
                foreach (ReportCell reportCell in this.headerCells)
                {
                    reportCell.IsSelected = false;
                }

                break;
            }

            // This resets the state of the mouse for the next operation.
            this.mouseState = MouseState.ButtonUp;

            if (this.headerPopup.IsOpen)
            {
                this.headerPopup.IsOpen = false;
            }

            // Hide the destination cursor when the mouse is released.
            if (this.destinationPopup.IsOpen)
            {
                this.destinationPopup.IsOpen = false;
            }

            // Release the Hounds, errr... mouse.
            Mouse.Capture(null);
        }