Thursday, March 29, 2012

Drag and drop from Excel to Windows Form Controls


As you know, Excel Application lets you drag cells in sheet. When you begin a drag operation, the Excel you drag from (the drop source), creates a COM object implementing the IDataObject interface, and puts some data into the object. The window you drag into (the drop target), then reads that data using IDataObject methods; that's how it knows what we are copying.

Following formats supported in .Net 3.5
  • Bitmap: Specifies a Windows bitmap format
  • CommaSeparatedValue: Specifies a comma-separated value (CSV) format, which is a common interchange format used by spreadsheets.
  • Dib: Specifies the Windows device-independent bitmap (DIB) format
  • Dif: Specifies the Windows Data Interchange Format (DIF), which Windows Forms does not directly use
  • EnhancedMetafile: Specifies the Windows enhanced metafile format
  • FileDrop: Specifies the Windows file drop format, which Windows Forms does not directly use
  • Html: Specifies text consisting of HTML data
  • Locale: Specifies the Windows culture format, which Windows Forms does not directly use
  • MetafilePict: Specifies the Windows metafile format, which Windows Forms does not directly use
  • OemText: Specifies the standard Windows original equipment manufacturer (OEM) text format
  • Palette: Specifies the Windows palette format
  • PenData: Specifies the Windows pen data format, which consists of pen strokes for handwriting software; Windows Forms does not use this format
  • Riff: Specifies the Resource Interchange File Format (RIFF) audio format, which Windows Forms does not directly use
  • Rtf: Specifies text consisting of Rich Text Format (RTF) data
  • Serializable: Specifies a format that encapsulates any type of Windows Forms object
  • StringFormat: Specifies the Windows Forms string class format, which Windows Forms uses to store string objects
  • SymbolicLink: Specifies the Windows symbolic link format, which Windows Forms does not directly use
  • Text: Specifies the standard ANSI text format
  • Tiff: Specifies the Tagged Image File Format (TIFF), which Windows Forms does not directly use
  • UnicodeText: Specifies the standard Windows Unicode text format
  • WaveAudio: Specifies the wave audio format, which Windows Forms does not directly use
When we copy data from Excel and drag in our application to drop on the controls following are the events which get fired on our control. Hence we need to override the following events in our application.
  • OnDragEnter(): Called when the cursor enters your window.
  • OnDragOver(): Called when the cursor moves inside your window.
  • OnDragLeave(): Called when the cursor leaves your window.
  • OnDrop(): Called when the user drops in your window.
When we drag the data in our application Excel has already created the COM object and it contain the data with comma separated values. This data need to be formatted before we use that in our application. We can validate this data in OnDragEnter()event .
In our application, if you are using inbuilt .Net component then verify it has AllowDrag property which can be set to true. And also it has above mentioned event to override. If you are using any third party control then it should have events to override the drag and drop functionality. Here i am using inbuilt .Net component TextBox and DataGridView.

#region "Grid Events"

private
void dataGridView1_DragDrop(object sender, DragEventArgs e)

{
if (e.Effect == DragDropEffects.Copy)

{
if (e.Data.GetDataPresent(DataFormats.CommaSeparatedValue))

{
string csvText = e.Data.GetData(DataFormats.CommaSeparatedValue, false).ToString();


if (!String.IsNullOrEmpty(csvText))

{
// write data to multiline text box as it is

textBox1.Text = GetFormattedData((MemoryStream)e.Data.GetData(DataFormats.CommaSeparatedValue, false));

DataTable dtable = GetDataTable((MemoryStream)e.Data.GetData(DataFormats.CommaSeparatedValue, false));


if (dtable != null)

{
dataGridView1.DataSource = dtable;
dataGridView1.Refresh();
}
}
}
}

this.Text = appTitle + " (DragDrop)";

}



private
void dataGridView1_DragEnter(object sender, DragEventArgs e)

{
if (!e.Data.GetDataPresent(DataFormats.CommaSeparatedValue))
{
e.Effect = DragDropEffects.None;
}
else
{
e.Effect = DragDropEffects.Copy;
}
this.Text = appTitle + " (DragEnter)";
}


private
void dataGridView1_DragLeave(object sender, EventArgs e)

{
this.Text = appTitle + " (DragLeave)";
}

private
void dataGridView1_DragOver(object sender, DragEventArgs e)

{
this.Text = appTitle + " (DragOver)";
}
#endregion "Grid Events"


Note :
  • If you are using Visual Studio 2010, this program will not work in debug mode. try to run the exe from bin.

Thursday, March 15, 2012

SharePoint 2010 AspMenu using custom XML file



The Sharepoint Menu control in Sharepoint 2010 is used to display a menu on page and is often used in combination with a SiteMapDataSource control for navigating a Web site. The Menu control supports the following features:
  • Data binding that allows the control's menu items to be bound to hierarchal data sources.
  • Site navigation through integration with the SiteMapDataSource control.
  • Programmatic access to the Menu object model to dynamically create menus, populate menu items, set properties, and so on.
  • Customizable appearance through themes, user-defined images, styles, and user-defined templates. 
Most of the blogs i read explains the SharePoint:asp Menu using only SiteMapDataSource But most of the time based on client requirement we need to add our own custom menus and sub menus. Here i made an attempt to create Sharepoint ASPMenu using xml file without SiteMapDataSource.


Requirement:
  • ContactUs XML : .xml file which will contain the menu structure. savethis file as ContactUs.xml. this need not to be same as below you can have your own structure of xml. here i am using following xml structure for my example. you need to take care the xmlpath which you will set for the DataSource Control in code behind hignhlighted in third point by Pink
<MenuItems>
<MenuItem MenuText="Contact Us" tooltip="Click here to go to contact us" desturl="#">
<MenuItem MenuText="The Site" tooltip="The Site" desturl="javascript:alert('The Site');">
</MenuItem>
<MenuItem MenuText="Portal Site" tooltip="Portal Site" desturl="javascript:alert('Portal Site');">
</MenuItem>
<MenuItem MenuText="EHD" tooltip="EHD" desturl="javascript:alert('Portal Site');">
</MenuItem>
</MenuItem>
</MenuItems>
  • WebPart / Control : copy the below code and past in html part of webpart. the most important thing here is the DataBinding which you can customize as per your requirement
<SharePoint:AspMenu ID="Contactmenu" runat="server" Orientation="Horizontal" >
<DataBindings>
<asp:MenuItemBinding TextField="MenuText" NavigateUrlField="destUrl" ToolTipField="tooltip" />
</DataBindings>
<LevelMenuItemStyles>
<asp:MenuItemStyle CssClass="ms-navheader" />
<asp:MenuItemStyle CssClass="ms-navitem" />
</LevelMenuItemStyles>
<LevelSubMenuStyles>
<asp:SubMenuStyle CssClass="ms-navSubMenu1" />
<asp:SubMenuStyle CssClass="ms-navSubMenu2" />
</LevelSubMenuStyles>
<LevelSelectedStyles>
<asp:MenuItemStyle CssClass="ms-selectednavheader" />
<asp:MenuItemStyle CssClass="ms-selectednav" />
</LevelSelectedStyles>
</SharePoint:AspMenu>


  • Web Part Code Behind: copy the following code and overwrite in page_load method of the control. This will render the XML.
protected void Page_Load(object sender, EventArgs e)
{

    if (!IsPostBack)
    {
        XmlDataSource xmlDataSource = new XmlDataSource();
        xmlDataSource.ID = "ContactUsXML";
        xmlDataSource.EnableCaching = false;
   
        // read the xml from file
        FileStream fs = new FileStream(@"D:\ContactUs.xml", FileMode.Open);
        StreamReader reader = new StreamReader(fs);
        xmlDataSource.Data = reader.ReadToEnd();
   
        fs.Close();
        fs.Dispose();
   
        //assigning the path to start read all MenuItem under MenuItems
        xmlDataSource.XPath = "MenuItems/MenuItem";
       
        //Finally, bind the source to the Menu1 control
        Contactmenu.DataSource = xmlDataSource;
        Contactmenu.DataBind();
    }
}


Following will be the o/p once you render the Web Part on page