Blogs

The One With

DXperience 12.2 Office Inspired Apps : Part V

Building Microsoft® Office® Inspired apps is a snap with DXperience 12.2. From Reporting Controls, Data Grids and Tree Lists to Schedulers, Ribbons and App Skins, the DXperience 12.2 offers a complete set of user interface controls to get you from A to Z in no time.

In previous sections we’ve created a Project Manager App where we can display and manage different kinds of projects and their inter dependencies. We’ve also created a Microsoft® Outlook® Style Task List to manage the tasks using the Data Grid Control. Let’s continue customizing the Data Grid and synchronize it with the Scheduler.

Task Grid Customization

Adding an image column to the Grid, is just a matter of adding an in-place editor. We’ll follow the same steps described in the previous article. The only difference would be the column type for the grid. The DevExpress XtraGrid Control fully supports the Unbound Column Types, and this is what we’ll use for our image columns.

Let’s drop an ImageList component onto our form and add the glyphs:

And using the Run Designer, create new column. Call it colTaskImage and set the UnboundType to Integer

Now assign a new ImageComboBoxEdit editor to this column,

set SmallImages property to point to the ImageList component,

and finally add one item to the Items collection.

Providing data to unbound columns is done using the CustomUnboundColumnData event

private void tasksGridView_CustomUnboundColumnData(object sender, CustomColumnDataEventArgs e)
{
   
// Are we getting UnboundData or setting it?
    if
(e.IsGetData)
    {
       
// Make sure there's a row - may be appending a new appointment
        if
(e.ListSourceRowIndex < dXProjectManagerDataSet.Appointments.Count)
        {
           
// Is this our static task image column?
            if
(e.Column == colTaskImage)
            {
               
// Always return 0 - there's only one image for this column
                e.Value = 0;
            }
        }
    }
}

Go ahead and run the app to see it in action.

Integrating Grid with Scheduler

The last thing we're going to do is integrate the DevExpress XtraGrid control together with the XtraScheduler. We’ll start by adding the following lines to the Form1_Load event handler implementation:

// Subscribe to evens on the XtraGrid and SchedulerControl to synchronize their selections
SubscribeSelectionEvents();

// Subscribe to selection changed events on the XtraGrid and SchedulerControl
private void SubscribeSelectionEvents()
{
    schedulerControl.SelectionChanged += schedulerControl_SelectionChanged;
    tasksGridView.SelectionChanged += tasksGridView_SelectionChanged;
}

// Unsubscribe from selection changed events on the XtraGrid and SchedulerControl
private void UnsubscribeSelectionEvents()
{
    schedulerControl.SelectionChanged -= schedulerControl_SelectionChanged;
    tasksGridView.SelectionChanged -= tasksGridView_SelectionChanged;
}        

// SelectionChanged event for the SchedulerControl to synchronize with an XtraGrid
private void schedulerControl_SelectionChanged(object sender, EventArgs e)
{
    UnsubscribeSelectionEvents();
    tasksGridView.BeginSelection();
    try
    {
        tasksGridView.ClearSelection();
        for (int i = 0; i < schedulerControl.SelectedAppointments.Count; i++)
            SelectAppointmentInGrid(schedulerControl.SelectedAppointments[i]);
    }
    finally
    {
        tasksGridView.EndSelection();
        SubscribeSelectionEvents();
    }
}

// Select a scheduler appointment in the Tasks XtraGrid
private void SelectAppointmentInGrid(Appointment appointment)
{
    DataRowView rowView = (DataRowView)appointment.GetSourceObject(schedulerStorage);
    if (rowView == null)
    {
        return;
    }
    int dataSourceIndex = dXProjectManagerDataSet.Appointments.Rows.IndexOf(rowView.Row);
    int rowHandle = tasksGridView.GetRowHandle(dataSourceIndex);
    tasksGridView.SelectRow(rowHandle);
    tasksGridView.MakeRowVisible(rowHandle, false);
}

// SelectionChanged event for the XtraGrid to synchronize with a SchedulerControl
private void tasksGridView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    UnsubscribeSelectionEvents();
    try
    {
        DataRow[] gridRows = GetGridSelectedDataRows();
        AppointmentBaseCollection aptsToSelect = GetAppointmentsForDataRows(gridRows);
        SelectAppointmentsInScheduler(aptsToSelect);
    }
    finally
    {
        SubscribeSelectionEvents();
    }
}

// Get an array of DataRow corresponding to the selected rows in the XtraGrid
private DataRow[] GetGridSelectedDataRows()
{
    int[] rowHandles = tasksGridView.GetSelectedRows();
    DataRow[] rows = new DataRow[rowHandles.Length];
    for (int i = 0; i < rowHandles.Length; i++)
        rows[i] = tasksGridView.GetDataRow(rowHandles[i]);
    return rows;
}

// Get a colleciton of Appointment corresponding to an array of DataRow
private AppointmentBaseCollection GetAppointmentsForDataRows(DataRow[] rows)
{
    AppointmentBaseCollection appointments = new AppointmentBaseCollection();
    for (int i = 0; i < rows.Length; i++)
    {
        Appointment apt = appointmentRowHash[rows[i]] as Appointment;
        if (apt != null)
            appointments.Add(apt);
    }
    return appointments;
}

// Select each of the appointments in the collection in the SchedulerControl
private void SelectAppointmentsInScheduler(AppointmentBaseCollection appointments)
{
    if (appointments.Count <= 0)
        return;

    SchedulerViewBase view = schedulerControl.ActiveView;
    view.SelectAppointment(appointments[0]);

    schedulerControl.BeginUpdate();
    try
    {
        for (int i = 1; i < appointments.Count; i++)
            view.AddAppointmentSelection(appointments[i]);

    }
    finally
    {
        schedulerControl.EndUpdate();
    }
}

Next, handle the events FilterAppointment, AppointmentCollectionCleared, and AppointmentCollectionAutoReloading on the schedulerStorage as follows:

// Collection used to map XtraScheduler Appointments to DataRows
readonly Hashtable appointmentRowHash = new
Hashtable();

// Event handler that must be assigned on the schedulerStorage - used to build the above appointmentRowHash
private void schedulerStorage_FilterAppointment(object
sender, PersistentObjectCancelEventArgs e)
{
    DataRowView rowView = (DataRowView)schedulerStorage.GetObjectRow(e.Object);

   
//could be a recurrence with no row
    if (rowView == null
)
    {
       
return
;
    }

    DataRow row = rowView.Row;

   
if
(!appointmentRowHash.ContainsKey(row))
        appointmentRowHash.Add(rowView.Row, e.Object);
}

// Event handler that must be assigned to schedulerStorage - clear the appointmentRowHash
private void schedulerStorage_AppointmentCollectionCleared(object
sender, EventArgs e)
{
    appointmentRowHash.Clear();
}

// Event handler that must be assigned to schedulerStorage - clear the appointmentRowHash
private void schedulerStorage_AppointmentCollectionAutoReloading(object
sender, CancelListChangedEventArgs e)
{
    appointmentRowHash.Clear();
}

Now, update the ShowResourceEditor() method by adding the following lines:

// Required to update the mappings in appointmentRowHash
appointmentsBindingSource.ResetBindings(false);

Download the Full Source Code

Published Feb 12 2013, 09:00 PM by
Bookmark and Share

Comments

No Comments
LIVE CHAT

Chat is one of the many ways you can contact members of the DevExpress Team.
We are available Monday-Friday between 7:30am and 4:30pm Pacific Time.

If you need additional product information, write to us at info@devexpress.com or call us at +1 (818) 844-3383

FOLLOW US

DevExpress engineers feature-complete Presentation Controls, IDE Productivity Tools, Business Application Frameworks, and Reporting Systems for Visual Studio, along with high-performance HTML JS Mobile Frameworks for developers targeting iOS, Android and Windows Phone. Whether using WPF, Silverlight, ASP.NET, WinForms, HTML5 or Windows 8, DevExpress tools help you build and deliver your best in the shortest time possible.

Copyright © 1998-2014 Developer Express Inc.
All trademarks or registered trademarks are property of their respective owners