Showing posts with label xceed. Show all posts
Showing posts with label xceed. Show all posts

Making Xceed excel export use foreign key lookups

Why does print functionality use foreign key values and excel export doesn't? Because Xceed hates you.

There is a workaround by rolling your own excel export class that extends Xceed's ExcelExporter base class though.

Here is it: <download>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xceed.Wpf.DataGrid;
using Xceed.Wpf.DataGrid.Export;

namespace sfc.Controls.Custom
{
    public class CustomExcelExporter : ExcelExporter
    {
        private DataGridControl _dgc;

        public CustomExcelExporter(DataGridControl dgc)
            : base(dgc)
        {
            _dgc = dgc;
        }

        protected override void StartDataItemField(ExportContext exportContext, object fieldValue)
        {
            // Attempt to find the export column in the master section of the DataGrid
            var column = (Column)_dgc.Columns[exportContext.Column.FieldName];

            // If the column cannot be found in the master section, search the columns of the detail configurations
            if (column == null)
            {
                foreach (DetailConfiguration detailConfiguration in _dgc.DetailConfigurations)
                {
                    if ((column = (Column)detailConfiguration.Columns[exportContext.Column.FieldName]) != null)
                    {
                        break;
                    }
                }
            }

            if (column != null)
            {
                ForeignKeyConfiguration fkc = column.ForeignKeyConfiguration;

                // Check if the column being exported has a ForeignKeyConfiguration and export the mapped value if so
                if (fkc != null && fkc.ForeignKeyConverter != null)
                {
                    fieldValue = fkc.ForeignKeyConverter.GetValueFromKey(fieldValue, fkc);
                }
            }

            base.StartDataItemField(exportContext, fieldValue);
        }
    }
}

One gotacha I found when writing this is that if the foreign key lookup returns a null its going to corrupt your excel document.

How to know when the sort is changed on the Xceed WPF grid

There is no easy to use sort event on the on the Xceed WPF grid itself however there is a not so obvious way that you can detect when the sort is changed by wiring up the following code.

DataGridCollectionView view = grid.ItemsSource as DataGridCollectionView;
      if (view != null)
      {
            ((INotifyCollectionChanged)view.SortDescriptions).CollectionChanged -=
                                                      new NotifyCollectionChangedEventHandler(SortCollectionChanged);
}

      private void SortCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
      {
            //do stuff
      }

WPF Xceed Grid: How to prevent/disable validation for objects that implement IDataErrorInfo


From the Xceed documentation:

"Built-in support for IDataErrorInfo provides business-object level validation that can be used in combination with validation rules.

Unless the ValidationRules collection is cleared, it will always contain an ExceptionValidationRule and DataErrorValidationRule. If the DataErrorValidationRule is excluded from the collection of validation rules, validation errors reported by IDataErrorInfo will be ignored. "

The solution is to manually loop over the columns and clear the validators

    foreach(Column c in grid.Columns)
    {
                c.CellValidationRules.Clear();
    }

How to iterate over the rows and cells in an Xceed WPF DataGrid

I found this handy code on the Xceed forums today. See http://xceed.com/CS/forums/permalink/26496/26518/ShowThread.aspx#26518

            foreach (object item in thisDataGrid1.Items)
            {
                Dispatcher.BeginInvoke(new Action<object>(DoRow), DispatcherPriority.ApplicationIdle, item);
            }

        private void DoRow(object item)
        {
            Xceed.Wpf.DataGrid.DataRow row = this.DataGrid1.GetContainerFromItem(item) as Xceed.Wpf.DataGrid.DataRow;
            if (row != null)
            {
                foreach (Xceed.Wpf.DataGrid.DataCell c in row.Cells)
                {
                    if (c != null)
                    {
                        //Do something to the cell
                    }
                }
            }
        }