How to apply custom icons to Your Ribbon Menu Controls

In this post we will be focusing on how to apply custom icons of your choice to the controls that you have created in the Ribbon Menu of Outlook.

You can use the imageMso property of the controls and put any of the default provided icons.Microsoft by default provide a vast set of icons for applying on the controls.You can find this list here.

But some times because of client requirements or any other reason we require to place our own custom icon like the company logo or anything. In this post we will be discussing on how to achieve it.

Addin

You have to save the custom icons that you want to show on the controls in your application resources then provide the loadImage attribute to the CustomUI of your ribbon file and then image tag in your individual controls.

<?xml version=”1.0″ encoding=”UTF-8″?>
<customUI xmlns=”http://schemas.microsoft.com/office/2009/07/customui&#8221; onLoad=”Ribbon_Load” loadImage=”GetImage” >
<ribbon>
<tabs>
<tab idMso=”TabMail”>
<group id=”MyPreferenceGroup”
label=”MyMenu”>
<button id=”btnPreferences” size=”large”  onAction=”btnPreferences_click” image=”Preference”/>
</group>
</tab>
<tab idMso=”TabNewMailMessage”>
<group id=”MyAttachGroup” label=”YOYO”>
<button id=”btnAttach” size=”large” onAction=”btnAttach_click” image=”Attach”/>
<button id=”btnSetting” size=”large” onAction=”btnSettings_click” image=”Settings”/>
</group>
</tab>
</tabs>
</ribbon>
</customUI>

Now you can see in the above code we have three buttons having image tags and in the custom UI tag we have loadImage=”GetImage” attribute.

Now on the server side of the ribbon we will implement the GetImage method.

public stdole.IPictureDisp GetImage(string strImageName)
{
try
{
switch (strImageName)
{
case Preference:
return PictureConverter.IconToPictureDisp(Properties.Resources.preferences_settings);
case Attach:
return PictureConverter.IconToPictureDisp(Properties.Resources.Attach);
case Settings:
return PictureConverter.IconToPictureDisp(Properties.Resources.Settings);
default:
return PictureConverter.IconToPictureDisp(Properties.Resources.preferences_settings);
}
}
catch (Exception ex)
{
LogWriter.LogErrorMessage(ex);
return PictureConverter.IconToPictureDisp(Properties.Resources.preferences_settings);
}
}

In the above method you can see based on the input means from which button(out of three) this call is made we are returning the corresponding image.

Now basically the icons stored in application resources will be of .ico extension but we need to convert them to the DISP, for this purpose we create a picture converter as shown below.

internal class PictureConverter : AxHost
{
private PictureConverter() : base(String.Empty) { }

static public stdole.IPictureDisp ImageToPictureDisp(Image image)
{
return (stdole.IPictureDisp)GetIPictureDispFromPicture(image);
}

static public stdole.IPictureDisp IconToPictureDisp(Icon icon)
{
return ImageToPictureDisp(icon.ToBitmap());
}

static public Image PictureDispToImage(stdole.IPictureDisp picture)
{
return GetPictureFromIPicture(picture);
}
}

So this is how one can apply icons of his choice on the Ribbon menu controls. If there are more controls then the cases in the switch statement will increase accordingly.

Hope this helps.

 

Initiate action when a new mailitem arrive in an Outlook folder

Some times we need to trigger an action when a new mailitem arrives in a Outlook Folder.

Requisite may be anything from notifying the user about the new Mailitem to manipulate the arriving mailitem.

We can achieve this functionality by registering the YourFolder_ItemAddevent of the required folder in the ThisAddIn_Startup event and then performing the required action in the YourFolder_ItemAdd event.

 

Following is the ThisAddIn_Startup method :

private void ThisAddIn_Startup(object sender, System.EventArgs e)
{

string folderPath =

Application.Session.
DefaultStore.GetRootFolder().FolderPath
+ @”\Outbox\My Outbox”;
Outlook.Folder quatFolder = GetFolder(folderPath);

_OutboxItems = quatFolder.Items;
_OutboxItems.ItemAdd += OutboxItems_ItemAdd;
Marshal.ReleaseComObject(quatFolder);

}

 

In the above method we have defined an event that will run whenever a item arrives in the My Outbox folder of Outlook.

private void OutboxItems_ItemAdd(object item)
{
if (item is MailItem)
{
Outlook.MailItem mailItem = item as Outlook.MailItem;

if (mailItem != null)
{

//Here you can do whatever is the required action that you want to perform

}

}

 

In the above method first we have checked that the incoming item is a mailIItem and then we can perform desired action.

We can manipulate the properties of the mailItem like attachments , To , CC , BCC and others.

We can notify the user about the same by showing a messagebox.

This is how we can trigger a code on the incoming mailItem on a Outlook Folder.

Adding a new folder in Outlook through C#

I guess most of us are familiar with Outlook addin’s . Add Ins make our work easier by providing some Out Of Box Features .

In this post we will be looking into how to create a new Folder in the outlook as and when our Plugin starts.

Open a Outlook addin project in your Visual Studio and open the ThisAddIn class.

ThisAddIn_StartUp method will be called every time you starts the plugin or addin.

private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
AddMyNewFolder();

}

Inside startup method call a folder creation method.

private void AddMyNewFolder()
{

Outlook.Folder folder =Application.Session.GetDefaultFolder(
Outlook.OlDefaultFolders.olFolderOutbox) as Outlook.Folder;
Outlook.Folders folders = folder.Folders;
try
{
if (folders.Count == 0)
{
Outlook.Folder newFolder = folders.Add(“Your Folder Name”, Type.Missing) as Outlook.Folder;
newFolder.Display();
}
}
catch (Exception ex)
{
MessageBox.Show(
“Could not add ‘Your Folder Name’”,”Add Folder”,
MessageBoxButtons.OK,MessageBoxIcon.Error);
}
}

 

In the above method you will be seeing that first we have created a parent folder object , in this case the Outbox , and then creating a child folder.

You can set the parent folder by choosing a option from Outlook.OlDefaultFolders .

If instead of a sub folder you want to create a parent folder then in that case manipulate

Outlook.Folders folders = folder.Folders;

As

Outlook.Folders folders = folder.Parent.Folders;

 

Plenty of custom functionality can be achieved through addins. Will be coming up with some others.

KENDO UI TIP 4 : Getting cell values by Column number In Kendo Grid

Many a times we place a hidden column in the kendo grid and use it’s value for performing certain operations.

You can basically place this column at any position on the columnList and retrieve it by it’s index like below:

 var row = $(this).closest(“tr”);

var yourColumnIndex=”1″;

var value=row.find(‘td:nth-child(yourColumnIndex)’).text();

Normally this logic works but if the grid is grouped by some columns then same number of empty columns with whom the grid is grouped will be inserted in the grid tbody at the very start.

Suppose the grid is grouped by two columns then two columns will be inserted at the starting.

In this scenario suppose we placed our hidden column at 1st place in the column list then practically it will be shifted to the first + (number of columns with which the grid is grouped) position.

so row.find(‘td:nth-child(yourColumnIndex)’).text(); will give us a wrong value.

Solutions:


There are two possible options for avoiding this situation:

1> Place the hidden column at the last position and try to retrieve it’s value like below:

var value=row.find(‘td:last’).text();

When we place the hidden column at the last position then it does not matter that how many columns are inserted at the starting as the last column will always be a last column.

2> Above solution is the best solution in most of the situations but what if we have to place more hidden columns.

In this case we will find out the number of columns with which the kendo grid is grouped and will add this number to the hidden column original position

var gridDataSource = $(‘#yourGrid’).data(‘kendoGrid’).dataSource;

var yourColumnIndex=1;

//checks wheather the grid is grouped
if (gridDataSource.group().length > 0) {

//gridDataSource.group().length will give the number of columns with which the grid is grouped
var value= row.find(‘td:nth-child(‘ + (yourColumnIndex + gridDataSource.group().length) + ‘)’).text();
}

Hope this helps. :)

 

Implementing MongoDB In MVC

First of all apologies for being away from a long time.

In this post we will be setting up MongoDB in an MVC application. Before starting on it I expect that the audience has good knowledge of MongoDB.

MongoDb is a schema free, scalable, high performance document database. When we say schema less it blows mind of many SQL developers. Schema independent feature of MongoDB provides flexibility to the developer to develop the schema as they progress with the application.

Prerequisite : MongoDB should be up and running in the system. Follow the Mongo installation steps if you are a newbie.

Now we require to create a new MVC Application . Open Visual Studio and create a MVC project in it ,I have given MongoDB as the name of the project.

For integrating the MongoDB in MVC application we need to include two below mentioned DLL’s that we can do through NuGet packages.

1> MongoDB.Bson.dll (MongoDB Bson dll , MongoDB deals in documents and the format of documents is Bson )

2> MongoDB.Driver.dll (MongoDB C# Driver)

After setting up the required dll in the MVC project references. We will move forward to create a database in Mongo and reference it for all the operations.

We will create two settings in the project properties Connection String and DataBase name so that they can be accessed globally in the app. Below is a pictorial Demonstration.

Image

I have given names to these settings as MongoConnString (“mongodb://localhost” is the default value for Mongo Connection String) and MongoDBName.

Now we will create a Context class in App_Start Folder of MVC project. We can get the database in the individual controllers also but creating a context class is always a good practice in Web applications.

 

MongoDB Context Class :


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using MongoDB.Driver;
using MongoDB.Properties;

namespace MongoDB.App_Start
{
public class MongoContext
{
public MongoDatabase mgDatabase;
public MongoContext()
{

var client = new MongoClient(Settings.Default.MongoConnString);
var server = client.GetServer();
mgDatabase = server.GetDatabase(Settings.Default.MongoDBName);

}

}
}

So this is the context class , Now where ever we need to perform operations with the database we will create an instance of this context class.

 

For the operations we will be needing a Model to deal with. Let’s create a Model named as Rental with few basic properties:


using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace MongoDB.Rentals
{
public class Rental
{
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
public string Description { get; set; }
public int NoOfRooms { get; set; }
public string ImageID { get; set; }

[BsonRepresentation(BsonType.Double)]
public Decimal Price { get; set; }
public Rental()
{

}

public Rental(PostRentals postRentals)
{
Description = postRentals.Description;
NoOfRooms = postRentals.NoOfRooms;
Price = postRentals.Price;
Address = (postRentals.Address ?? String.Empty).Split(‘\n’).ToList();

}

}
}

To deal with these rentals stored in the database we will create a interface in the Mongo context class and use it for the rental operations.

 

public MongoCollection<Rental> RentalCollection
{
get
{
return mgDatabase.GetCollection<Rental>(“RentalCollection”);
}
}

 

Controller :


 

In the controller first we will create a instance of the Mongo context class and then will use RentalCollection interface for any type of operations on Rentals i.e Retrieval, Deletion ,Creation and Updation.

For querying the collection of documents we can use Query which is an extension method of MongoDB.Driver.Builder.

Query has a lot and lot of options for the different mathematical conditions like LTE(Less then and Equal to), GTE,EQ and many others.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MongoDB.Rentals;
using MongoDB.App_Start;
using MongoDB.Bson;
using MongoDB.Driver.Builders;
using MongoDB.Driver;
using MongoDB.Driver.GridFS;

namespace MongoDB.Controllers
{
public class RentalsController : Controller
{

public readonly MongoContext context = new MongoContext();
//
// GET: /Rentals/

public ActionResult Index()
{
var rentals = context.RentalCollection.FindAll();
return View(rentals);
}

public ActionResult Post()
{
return View();
}

[HttpPost]
public ActionResult Post(PostRentals postRentals)
{
var rental = new Rental(postRentals);

//Inserting
context.RentalCollection.Insert(rental);

////Saving
//var objId = new ObjectId().ToString();
//rental.Id = objId;
//rental.Price = 40;
//context.RentalCollection.Save(rental);

//Updating
//var query = Query.EQ(“Description”, “jj”);
//var update = Update.Set(“Price”, “910″);
//context.RentalCollection.Update(query, update, UpdateFlags.Multi);
return RedirectToAction(“Index”);
}

public ActionResult Delete(string id)
{
var query = Query.EQ(“_id”, new ObjectId(id));
context.RentalCollection.Remove(query);
return RedirectToAction(“Index”);
}

}
}

 

So these actions defined in the controllers can be used to Show the Rentals, Update the Rentals and delete the Rentals.

We can also use LINQ with the Collections if we do not want to use the Inbuilt Query option.

So this is how we can set up MongoDB in MVC Application and perform the basic Database operations. Like everything else, there is a lot more to MongoDB then just this but this will get you started.

 

Upload File In MVC through GridFS of MongoDB

In this post we will be uploading a file in MVC through GridFS of MongoDB. Before going through the post it will be benefecial to have a knowledge of GridFS of MongoDB

Scenario :


 

We will be having a file uploader in our view where we will be uploading a file through GridFS MongoDB. For using MongoDB in MVC we have to set the MongoDB in our system and include the C# drivers of Mongo DB in our MVC project through NuGet package manager.

Razor Markup :


@using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = “multipart/form-data” }))
{

<div class=”form-group”>
<div class=”col-lg-10 col-lg-offset-2″>
<input type=”file” id=”fileUpload” name=”file” />

</div>

</div>

<div class=”form-group”>
<div class=”col-lg-10 col-lg-offset-2″>

<input type=”submit” value=”upload” class=”btn btn-default” />
</div>
</div>
}

 

Here as you can see we have created a form where we have placed a file control with name as “file” and a submit button to post the file to the action(With same name as of the razor view) in Mvc controller .

Mongo Context Class :


Create a context Class (MongoContext ) to get the Mongo Interface references in all the actions of all the controllers. Place this file in the App_Start folder and Initialize it anywhere.

public MongoDatabase mgDatabase;
public MongoContext()
{

var client = new MongoClient(Settings.Default.MongoConnString);
var server = client.GetServer();
mgDatabase = server.GetDatabase(Settings.Default.MongoDBName);

}

Controller Action For Uploading Files :


 

In the controller create an instance of the Mongo Context class that we created earlier.

//Assembly references

using MongoDB.App_Start;
using MongoDB.Bson;
using MongoDB.Driver.Builders;
using MongoDB.Driver;
using MongoDB.Driver.GridFS;

 

 

//Creating Instance of MongoDB context

public readonly MongoContext context = new MongoContext();

 

[HttpPost]
public ActionResult AttachImage(HttpPostedFileBase file)
{
var options =new MongoGridFSCreateOptions{
//Id=imageID, If we want to link the file with a document
ContentType=file.ContentType
};
context.mgDatabase.GridFS.Upload(file.InputStream, file.FileName, options);
return RedirectToAction(“Index”);
}

In the above action method we have input param of type HttpPostedFileBase with name file which is basically the name of the file control in the razor view.

We can use the Upload method of the GridFS to save the posted file. In the above upload Api we have a field option which is very usefull to provide the configs like the content type (Mime type) and if we have to connect this file with a Bson document we can link them as done in options.

Graphical Representation :

To view the chunks and files of this uploaded file we can use the RoboMongo.

fs.files :

g2

 

fs.chunks :

g1

 

In the image above the left side object is basically the fs.files and the right side objects are the chunks (fs.chunks) of the file.

The file_id in the chunks is referring to the file to which the chunks belong. n refers to the sequential chain of the chunks referring to the same file.

File info like the file name , total file size , content type and associated chunks size can be seen the file object.

This is how we can upload a file through GridFS collection of MongoDB in MVC.

 

GridFS In MongoDB

There is a Lot said and asked about GridFS . In this post we will be going to have a Insight into GridFS feature of MongoDB.

What Exactly Is GridFS :


 

GridFS is an inbuilt feature of MongoDB through which it provides a Virtual File System for Storing Files , associating them with Mongo Documents(BSON Documents) and retrieving them when required.

 

Question : Why can’t we simply use the Bson documents to store the file?

Size : GridFS is basically for storing the files which are greater in size then 16MB.

Sync : When you want to keep your files and metadata automatically synced and deployed across a number of systems and facilities.

Platform Agnostic : Files can be stored alleviating many concerns of local file systems like maximum size of files in local directory.

Chunk Read Access : Suppose at a point you need just a part of your file rather then the complete file. As sometimes we need to see only a part of the video instead of the complete one. GridFS provides the capability of retrieving only that chunks of the file which is needed. So GridFS can be used to recall sections of files without reading the entire file into memory thus enhancing the performance.

FailOver And BackUp : As GridFS stores file in documents it has baked in support for replication and backup.

So after having a brief Idea of why we need GridFS let’s dive into the internals:

GridFS Collection :


 

GridFS stores files in two collections:

  • chunks stores the binary chunks.
  • files stores the file’s metadata.

GridFS places the collections in a common bucket by prefixing each with the bucket name. By default, GridFS uses two collections with names prefixed by fs bucket:

  • fs.files
  • fs.chunks

You can choose a different bucket name than fs, and create multiple buckets in a single database.

Each document in the chunks collection represents a distinct chunk of a file as represented in the GridFS store. Each chunk is identified by its unique ObjectId stored in its _id field. Default Size of a chunk is 256KB which can be modified.

                                    Image

Elements inside these two entities will give you a better idea:

Image

 

In the chunks schema :

_id is the basic object id that is assigned to every chunk. file_id is the id of the file stored in fs.files which contain the metadata of the chunk. n is used for indexing and data contain the actual binary stream of data.

In the files schema :

We have different options which can be configured like chunk size and content type(For storing Mime type).

Metadata will contain the file info , MD5 will contain a hash which is useful to confirm that the chunks are stored correctly.

So this is how GridFS provides a storng , efficient and configurable way to handle big files in MongoDB.