Blogs

The One With

  • WinForms – New WinRTLiveTileManager (coming soon in v2013 vol 1)

         

    With the release of Windows 8, Microsoft introduced us to a new kind of user interface: Live Tiles. This new UI metaphor provides a couple of benefits to developers: first they can update the tile on a regular basis to provide visible up-to-date information, and second they can better organize the main entry point into their apps. The user experience is much improved: users don't have to run the app to see the latest most important information and there is only one entry point into the app (the tile itself). In the past year, we even introduced a complete set of controls (TileControl) so you may expose this user interface in your own desktop apps.

    image

    Despite this, there is a bit of a disconnect between the Windows 8 Tiles on the Start Screen and your non-Modern-UI desktop apps. Bridging this disconnect is exactly where the new WinRTLiveTileManager comes in.

    The idea is simple, although the execution is a little more involved: implement a desktop app that can create and display (and update, of course) Live Tiles on the Start Screen, such that when the user clicks on them, the desktop app is invoked and will respond. To accomplish this, we will ship a fully-compliant Windows Store App, the Live Tile Manager.

    Live Tile Manager

    The Live Tile Manager will analyze the running desktop apps seeing if they support the Live Tile Manager interface. For each found, it will collect the one or more tiles exposed by the app and pin them to the Start Screen.

    Live Tile Manager

    It will also respond to clicks or touches on these tiles and route the event to the relevant app on the desktop.

    For example, here is a Live Tile on the Start  Scrren that has been created and is updated in real time from a desktop app:

    Win8 Live Tiles

    Let me know what you think…

    Cheers,

    Azret

  • WinForms Grid Control – Pixel Scrolling (coming soon in v2013 vol 1)

         

    This is a cool addition for the WinForms Grid Control; the Pixel Scrolling feature. We introduced it first in our WPF Grid and since then many customers requested to have in the WinForms Grid Control as well. This slick scrolling option is especially useful if you are building Touch Enabled apps. Here is small preview:

    WinForms Grid Control with Pixel Scrolling enabled

    Cheers

    Azret

  • WinForms Grid Control – Sparkline (coming soon in v2013 vol 1)

         

    The ability to embed a Sparkline into a Grid has been requested by many. Very pleased to announce that in the upcoming release of DXperience, we will introduce a new in-place editor called SparklineEdit.

    Sparkline - Line

    Fig. 1: Line

    Sparkline - Area

    Fig. 2: Area

    Sparkline - Bar

    Fig. 3: Bar

    Sparkline - Win/Loss

    Fig. 4: Win/Loss

    Values, or Points, for the line are specified using the Data property.

    Sparkline Editor

    Within the Grid Control, Sparkline editor is used just like any other in-place editor.

    Sparkline in a Grid

     

    Cheers

    Azret

  • WinForms Grid Control – New Designer (coming soon in v2013 vol 1)

         

    The DevExpress Data Grid is one of those controls, so powerful and so rich with features, that you could build an entire application with just one single grid in it. We have always tried to help with discoverability of all those options. If you remember, the Grid Designer groups features and options in a logical way so that they are easy to find, even if you might not know the exact property name that governs a specific Grid behavior. For the upcoming v2013.1 release, the designer received a make over, and the new look should give a better overview of all the possible customization options for the Data Grid.

    DevExpress Grid Control Designer

    Cheers,

    Azret

  • Image Gallery (coming soon in v2013 vol 1)

         

    As we approach the release of DXperience v2013 vol 1, I thought I’d “leak” some of what’s coming. One of the things that I often need when developing an Office Style application is good collection of Glyphs for my buttons. In v2013 vol 1, we will provide these images. Not only that, but we also implemented a new design-time Image Picker to make it easier for you to choose the appropriate image. This new design-time Image Picker is accessible by clicking on the image property:

     

    Alternatively, it can be invoked from a smart-tag:

    The Image Picker will retain all the existing functionality of the standard image picker that you might already be used to in Visual Studio

    and will add the Image Gallery onto a secondary tab.

    All the standard images, as you can see, are provided both in 16x16 and 32x32 sizes, as well as their Gray Scale variants:

    The pickers will work for both, the standard Glyphs as well as ImageLists.

    Cheers,

    Azret

  • 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

  • DXperience 12.2 Office Inspired Apps : Part IV

         

    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 created a Project Manager App where we can display and manage different kinds of projects and their inter dependencies.

    In this article let’s add the ability to track project Tasks. We’ll display and manage our tasks in a similar way that you may find in Microsoft Outlook and we’ll be using a Data Grid Control to do this with stunning results.

    Form Layout and Data Binding

     

    Let’s start by dropping a Data Grid Control from the Toolbox, onto a form.

    After the Grid is aligned properly, bind it to the same appointmentsBindingSource that the schedulerStorage component is using. This way the data will be in sync.

    This is really all there is to it. Very simple. Notice after you run the app that not only did the Grid pick all the columns, defined in the data source, but it also correctly determined the in-place editor for each column type.

    Let's customize the Grid even further to take advantage of many other in-place editors that are shipped DXperience 12.2.

    Task Grid Customization

    You might have noticed the Outlook Style Grouping box when you ran the app. This building functionality could be turned on or off by OptionsView.ShowGroupPanel property.

    While in design mode, drag out columns off the grid that you don’t want to be shown by default and leave only: Start Date, End Date, Description, Resource Id, Percent Complete, and Custom Field 1. The remaining columns would still be available in the Column Customization window.

    To change an in-place editor for a cell or to assign a new one, simply select a column at design time, and choose an editor from the drop down list. The property that we would need for this is ColumnEdit.

    For example, the Percent Complete could be shown with a visual progress indicator, so we’ll assign a ProgressBar editor for that column.

    To make it look like this:

    Similarly, for the Resource Id column, let’s assign a LookupEdit, this will allow us to map the Id of the resource stored in the database to its readable description.

    Once the LookUpEdit editor is created, set its DataSource property to resourcesBindingSource.

    DisplayMember to Description - this is the column value that will show and the ValueMember property to Id.

    Finally, change the column's caption to Resource and let's see how this looks at runtime.

    What's Next?

    There is few little tweaks that we still want to make to the app, stay tune for the next part.

  • DXperience 12.2 Office Inspired Apps : Part III

         

    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 created a Project Manager App where we can display and manage different kinds of projects and their inter dependencies.

    In this article we will build on that, and give the end user the ability to define and manage resources. Let's begin!

    New DXperience Form

    We'll start by creating a new Form based on the template provided by DXperience 12.2. Let’s name it “ResourcesForm

    By using the DXperience 12.2 template our form will automatically adhere to the currently selected App Skin.

    Let’s add a Ribbon command to invoke the new form.

    Bring up the Form1.cs designer and select the Home tab in the Ribbon control. Right-click the Appointment Ribbon group and click Add Button.

    Assign appropriate values for Caption, Glyph, and LargeGlyph, and use drag-and-drop to position it at the beginning of the group.

    Now handle the ItemClick event to invoke the form

    private void defineResourcesButton_ItemClick(object sender, ItemClickEventArgs e) {
       
    using (ResourcesForm resourcesForm = new
    ResourcesForm()) {
            resourcesForm.ShowDialog();
        }
    }

    Form Layout with XtraLayoutControl

    Now that we have a way to show our form, let’s lay our control out with the help of the XtraLayoutControl. The XtraLayoutControl was designed to drastically simplify form layout management. All controls within the layout manager are “vectorized” so that you don’t have to spend time on pixilation and size adjustment. All the alignment and positioning are automatically handled for you.

    Open up the ResourcesForm.cs designer and drop the LayoutControl from your toolbox and dock it to full:

    Bring in one TreeList,

    two TextEdits, a ColorPickEdit and a PictureEdit.

    You just drag-and-drop the layout items to position them how you like:

    You can hold the Shift button and click the captions for all four of the layout control items on the right and then group them all as one.

    Do the same for the TreeList.

    Now that all of the editors are in place, we would need to add the command buttons for manipulating the resources and for accepting the changes.

    After you drag them from the toolbox, open the layout Customization form, using the context menu, and add an empty space element to separate the button groups.

    Go through all of the items and give them proper descriptions.

    Go ahead and fire up the application in the debugger. We now have a properly laid out form for defining our hierarchical resources. The form can be resized and the elements inside will automatically be adjusted without having to do any additional work.

    Binding to Data

    Now let's work on data-binding the controls so our resources are displayed correctly. Select the Smart Tag for the TreeList and set the data source to Other Data Sources | Project Data Sources | DXProjectManagerDataSet | Resources

    private void ResourcesForm_Load(object sender, EventArgs e) {
        // TODO: This line of code loads data into the       
        // 'dXProjectManagerDataSet.Resources' table.   
        this.resourcesTableAdapter.Fill(this.dXProjectManagerDataSet.Resources);
    }

    In the Properties window (with the treeList1 still selected), set the KeyFieldName to Id and the ParentFieldName to ParentId, enable the OptionsBehavior | DragNodes  and disable the OptionsBehavior | Editable.

    The tree list is now configured, let’s bind the editors. Select the first editor on the right and expand DataBindings section in the Properties window.

    Click the EditValue drop down and select resourcesBindingSource and then the Description. Use the same steps to bind the remaining edit controls to Color, CustomField1, and Image. Additionally, for the ColorPickEdit set the Properties.StoreColorAsInteger to True and for the PictureEdit, set the Properties.PictureStoreMode to ByteArray.

    Run the app and you will see the resources displayed with their details shown on the right.

    Now that we can see the data, let's make it possible to modify and save it.

    Modifying Resources

    Add the following event handlers for the Add and Delete buttons:

    private void addButton_Click(object sender, EventArgs e) {
        DXProjectManagerDataSet.ResourcesRow newResource = dXProjectManagerDataSet.Resources.NewResourcesRow();
        dXProjectManagerDataSet.Resources.AddResourcesRow(newResource);    
        resourcesBindingSource.MoveLast();
        descriptionEdit.Focus();
    } 
    
    private void deleteButton_Click(object sender, EventArgs e) {
        resourcesTree.DeleteSelectedNodes();
    }

    The code above is pretty self-explanatory. The Add button handler creates a new row, adds it to our dataset, and focuses both the new row and the description editor. The Delete handler uses the TreeList control to delete the selected data row.

    Persisting Data

    Let's wire up the last two buttons. Set the DialogResult property of the Cancel button to Cancel and handle the click event of the OK button with the following code:

    private void okButton_Click(object sender, EventArgs e) {
        resourcesBindingSource.EndEdit();
        resourcesTableAdapter.Update(dXProjectManagerDataSet);
        DialogResult = System.Windows.Forms.DialogResult.OK;
    }

    Go ahead and run the project to see this in action!

    Finishing Up

    The last thing we need to do is check to see if the user clicked OK on our new dialog and, if so, refresh the data on the main screen. In the Form1.cs code, modify the Click event handler for the Define Resources bar button added to the Ribbon previously:

    private void defineResourcesButton_ItemClick(object sender, ItemClickEventArgs e)
    {    
        ShowResourceEditor();
    } 
    
    private void ShowResourceEditor() {
        using (ResourcesForm resourcesForm = new ResourcesForm()) {
            if (resourcesForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) {
                schedulerControl.BeginUpdate();
                resourcesTree.BeginUpdate();
                try {
                    resourcesTableAdapter.Fill(dXProjectManagerDataSet.Resources);                
                    resourcesBindingSource.ResetBindings(false); 
                }
                finally {
                    resourcesTree.EndUpdate();
                    schedulerControl.EndUpdate();
                }
            }
        }
    }

    Download Source Code

    What's Next?

    In the next article we'll use the XtraGrid control to incorporate a list of tasks on our main screen that synchronizes with the scheduler control.

  • DXperience 12.2 Office Inspired Apps : Part II

         

    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 the first article we created a fully functional Calendaring app. Let’s continue on and see what we need to do to enable the Gantt View feature of the Schedule Control.

    Hierarchical Resources

    One of the features of the Gantt View is the support for hierarchical resources. To this end, the DXperience 12.2 includes the Resources Tree Control for displaying Scheduler resources in a hierarchy. Open up the designer for Form1 in Visual Studio. Select the XtraNavBar and replace it with ResourcesTree control from the Toolbox.

    Click the smart tag for the Resources Tree. As you can see, it is already automatically bound to the scheduler control on the form. (Scheduler was detected when the control was parented to the form)

    The Resources Tree supports multiple columns as it is build on top of our Tree List. To define them, click the Smart Tag and run the Designer.

    We need a reference to the XtraTreeList assembly. Right-click the project in the Solution Explorer and click Add Reference.

    Click Start on the project to see the results. As you can see, the resources are now shown in a tree control on the left.

    Appointment Dependencies

    Go ahead and create a few appointments under each resource.

    Then, right click on one of them:

    Notice that the Create Dependency option is grayed out for the newly created appointments. To enable it, all we have to do is propagate the appointment id. One of the simplest techniques is fetching the DB id from the data adapter. And since we use an identity (auto-inc) column for the primary key we can do like so:

    private void Form1_Load(object sender, EventArgs e) {

        ...
        // Get the auto-inc value from SQL Server
        appointmentsTableAdapter.Adapter.RowUpdated += appointmentsTableAdapter_RowUpdated;
    }
     
    private int insertedId;
    private void appointmentsTableAdapter_RowUpdated(object sender, SqlRowUpdatedEventArgs e)
    {
        if (e.Status == UpdateStatus.Continue && e.StatementType == StatementType.Insert)
        {
            // Store the inserted ID so we can update the underlying appointment 
            // in schedulerStorage_AppointmentsInserted
            insertedId = (int)e.Row["UniqueId"];
        }
    }

     

    Now assign the new id to the appointment object:

    private void schedulerStorage_AppointmentsInserted(object sender, PersistentObjectsEventArgs e)
    {
        CommitTask();
        // Set the auto-inc value from SQL Server within the XtraScheduler appointment
        // this is needed, for instance, to create dependencies for newly inserted appointments
        // othrwise the option will be disabled
        schedulerStorage.SetAppointmentId((Appointment)e.Objects[0], insertedId);
    }

    With these changes in place, we can now create the dependencies for newly created appointments.

    Binding Dependencies to Data

    In the same way we bound the Appointment and Resource data sources, we now need to bind the Dependency data source. On the designer for Form1.cs, bring up the Smart Tag for schedulerStorage and assign it from our data set.

    Verify the field mappings and we’re almost done.

    Persisting Changes

    The last thing to do is to make sure that our dependencies are persisted to the database. For this, we’ll handle the following events on the schedulerStorage component: AppointmentDependenciesChanged, AppointmentDependentciesDeleted, and AppointmentDependenciesInserted.

    All three can be handled with the same code:

    private void schedulerStorage_AppointmentDependenciesChanged(object sender, PersistentObjectsEventArgs e)
    {
        CommitTaskDependency();
    }
     
    private void schedulerStorage_AppointmentDependenciesDeleted(object sender, PersistentObjectsEventArgs e)
    {
        CommitTaskDependency();
    }
     
    private void schedulerStorage_AppointmentDependenciesInserted(object sender, PersistentObjectsEventArgs e)
    {
        CommitTaskDependency();
    }
     
    private void CommitTaskDependency()
    {
        taskDependenciesTableAdapter.Update(dXProjectManagerDataSet);
    }

    And we're done!

    What's Next?

    Download the Source Code

    While our project works well, there's currently no way to actually define resources within the application. The next article in this series will cover creating UI for defining hierarchical resources using drag-and-drop. Stay tuned!

  • DXperience 12.2 Office Inspired Apps : Part I

         

    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.

    Let me introduce you to the products by building (together with you), a real-world project management app. We’ll start with the Gantt View of the XtraScheduler, Ribbon and a Data Grid. The end result will be a fully functional, albeit simple, project management app with a slick Windows® 8 style user interface:

    Gantt View

    Database Schema

    Let’s start of by defining the the data structures that we’re going to need. We’ll use the Microsoft® SQL Server as our back end. This is where all our appointments and tasks will be stored.

    Fire up the SQL Server Management Studio and create a new database: “DXProjectManager

    We need tree tables: Appointments, Resources and TaskDependencies. See Gantt View DDL specification for more details.

    CREATE TABLE [dbo].[Appointments] (

         [UniqueId] [int] IDENTITY (1, 1) NOT NULL ,

         [Type] [int] NULL ,

         [StartDate] [smalldatetime] NULL ,

         [EndDate] [smalldatetime] NULL ,

         [AllDay] [bit] NULL ,

         [Subject] [nvarchar] (max) NULL ,

         [Location] [nvarchar] (max) NULL ,

         [Description] [nvarchar](max) NULL ,

         [Status] [int] NULL ,

         [Label] [int] NULL ,

         [ResourceId] [int] NULL ,

         [ResourceIds] [nvarchar](max) NULL ,

         [ReminderInfo] [nvarchar](max) NULL ,

         [RecurrenceInfo] [nvarchar](max) NULL ,

         [PercentComplete] [int] NULL,

         [CustomField1] [nvarchar](max) NULL

    ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

    GO

    CREATE TABLE [dbo].[Resources] (

         [Id] [int] IDENTITY (1, 1) NOT NULL ,

         [IdSort] [int] NULL ,

         [ParentId] [int] NULL ,

         [Description] [nvarchar] (max) NULL ,

         [Color] [int] NULL ,

         [Image] [image] NULL ,

         [CustomField1] [nvarchar](max) NULL

    ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

    GO

    CREATE TABLE [dbo].[TaskDependencies](

         [Id] [int] IDENTITY(1,1) NOT NULL,

         [ParentId] [int] NULL,

         [DependentId] [int] NULL,

         [Type] [int] NOT NULL,

    GO

    New DXperience WinForms Project

    The next step is to create a new Visual Studio project. DXperience 12.2 ships with multiple ready-to-use Project Templates and Wizards that create all the user interface elements for you.

    From File | New | Project, select Templates and then DevExpress: Visual C# | WinForms.

    File New Dialog

    Notice how the wizards are split by a solution theme

    · Word Inspired Application: This project wizard let’s you build apps with a fully functional Rich Text Editor. Learn More Here.

    · Outlook Inspired Application: Using the Scheduler Control, this wizard allows you to build powerful calendaring solutions. Learn More Here

    · Data Analysis Application: With this wizard, you can build Business Intelligence, reporting and analytics apps using the DevExpress PivotGrid Control. Learn More Here

    · Windows Forms Application: This wizard allows you to mix and match different UI elements. And this is the one we are going to use.

    DXperience 12.2 ships with a ton of build-in and ready-to-use Application Skins. We can pre-define the skin we want right from the wizard or let the user select one of their liking afterwards - at runtime.

    DXperience Project Wizard

    Click the drop down arrow next to the Client Area and choose the Scheduler Control. There are three templates available:

    · Simple: This template will use the Scheduler Control without auxiliary navigation options.

    · Range Control: Along with the primary Scheduler Control, a Range Control will be included for easy date range selection.

    · Date Navigator: This template gives you full calendar control to navigate through the calendar.

    DXperience Project Wizard

    Once you click Create and then run your project, you will see a functional scheduling/calendaring app.

    Scheduling/Calendaring Application

    You can navigate through dates using the Date Navigator on the right. You can create new appointments using context menus or using the Appointment tab in the Ribbon. You can drag-and-drop appointments around, and even drag them onto the Date Navigator on the right. You can use the Home and View tabs in the Ribbon to manipulate the XtraScheduler Control in many ways. All of this functionality is already built into the controls and requires not coding on your part.

    The only thing left to do is to bind it to the data tables that we’ve defined earlier.

    Binding to Data

    Following the binding the XtraScheduler article found in the online documentation or this quick how to video, click the Smart Tag on the schedulerStorage component and add Project Data Source for the Appointments.

    Data Source Smart-tag

    Select Database

    Then Dataset and click Next…

    Connect to the “DXProjectManager” database. (If that’s what you named it)

    And select our tables: Appointments, Resources, and TaskDependencies.

    After this, the new data set has been imported and we can assign the individual tables to the scheduler.

    All of the fields are automatically detected from the naming convention and are mapped correctly.

    Scheduler Mapping Wizard

    You probably have noticed a CustomField1 in our database schema. Here is where we can map it to appointments:

    Scheduler Mapping Wizard

    Repeat the data binding for the Resources in the same way

    Add both CustomField1 and IdSort to the Custom Field list. The IdSort field is necessary to support the hierarchical resources feature of the Gantt View.

    That's it for binding data. If you right-click the designer and click View Code (or press F7) and look at the Form1_Load event handler, you'll see that the data wizards already added code to fill our data sets.

    private void Form1_Load(object sender, EventArgs e)
    {
        // TODO: This line of code loads data into the 'dXProjectManagerDataSet.Resources' table.
        // You can move, or remove it, as needed.
        resourcesTableAdapter.Fill(dXProjectManagerDataSet.Resources);
        // TODO: This line of code loads data into the 'dXProjectManagerDataSet.Appointments' table.
        // You can move, or remove it, as needed.
        appointmentsTableAdapter.Fill(dXProjectManagerDataSet.Appointments);
    }

    In order to see this working, open SSMS and add a couple of rows to the Resources table with descriptions Deployment and Testing.

    Once you run the app from Visual Studio, Group by Resource and you should be able to see your two resources: Deployment and Testing, displayed above the scheduler control.

    Persisting Changes

    To persist changes made using the scheduler control, it is necessary to handle the following events on the schedulerStorage component: AppointmentsChanged, AppointmentsDeleted, AppointmentsInserted.

    They can each be handled with the same code. The code will simple tell the underlying table adapters to save any changes in their datasets:

    private void schedulerStorage_AppointmentsChanged(object sender, PersistentObjectsEventArgs e)
    {
        CommitTask();
    }
    
    private void schedulerStorage_AppointmentsDeleted(object sender, PersistentObjectsEventArgs e)
    {
        CommitTask();
    }
    
    private void schedulerStorage_AppointmentsInserted(object sender, PersistentObjectsEventArgs e)
    {
        CommitTask();
    }
    
    private void CommitTask()
    {
        appointmentsTableAdapter.Update(dXProjectManagerDataSet);
    }

    And that's it!

    The scheduler application now allows for creating, manipulating and deleting appointments and having those changes persisted back to a SQL Server database. We have a fair start on a great Windows 8 style user interface. And all of this with just a few lines of code!

    Download the Source Code Part I

    Stay tuned as we continue to build this app.

Next page »
More from DevExpress
Live Chat
Have a pre-sales question?
Need assistance with your evaluation?
We are here to help.
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, require pre-sales assistance, or want help with your order, write to us at info@devexpress.com or call us at
+1 (818) 844-3383.