Showing posts with label Code. Show all posts
Showing posts with label Code. Show all posts

Tuesday, February 2, 2010

PropertyGrid Control and Complex Type Object

For one of my last projects I decided to use the PropertyGrid Control, I assume it would be nice to use it as an editor for my complex type object.

Cheerful as I was it turn to be not such an easy mission, apparently the PropertyGrid Control can handle privitive types, collections and enums, but when it comes to complex type objects it need to be told what will be the way to edit them.

Here is the PropertyGrid as it was displayed originaly:








As you can see, the complex type “Manager” is not editable !!!

In order to make it editable it needs to be define with Editor Attribute, as such:

[Editor(typeof(MyUITypeEditor),typeof(UITypeEditor))]

In order to use this custom UITypeEditor, we’ll need to create two thins:
1. MyUITypeEditor - Based on the UITypeEditor.
2. UIMyClassEditorForm – The form that will be displayed whenever we’ll click the complex type for editing.

I really wanted this to be generic as I could so my UIMyClassEditorForm contains a PropertyGrid Control for editing the object pass through.

So now, when clicking the Manager property we should be abe to edit it and the screen will look like this:


Here is the source code:

Person.cs
public class Person
{
public enum City
{
NewYork,
TelAviv,
Rome
}

public Person() { }
public Person(string firstName, string lastName,int age, City myCity)
{
this.FirstName = firstName;
this.LastName = lastName;
this.Age = age;
this.MyCity = myCity;
this.Manager = new Person();
}

List children = new List();
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public City MyCity { get; set; }
public List Children
{
get { return children; }
}

[Editor(typeof(MyUITypeEditor),typeof(UITypeEditor))]
public Person Manager{ get; set; }

public override string ToString()
{
return string.Format("{0},{1}", FirstName, LastName);
}

}
MyProperyGridSampleForm.cs
public partial class MyProperyGridSampleForm : Form
{


public MyProperyGridSampleForm()
{
InitializeComponent();
}

private void EditPersonButton_Click(object sender, EventArgs e)
{
Person myTestEntity = new Person();
myTestEntity.FirstName = "John";
myTestEntity.LastName = "Smith";
myTestEntity.Age = 29;
myTestEntity.MyCity = Person.City.NewYork;
myTestEntity.Manager = new Person("Liron", "Leybovich", 33, Person.City.TelAviv);

propertyGrid1.SelectedObject = myTestEntity;
}
}
UIMyClassEditorForm.cs
public partial class UIMyClassEditorForm : Form
{
public object MyClass;
public IWindowsFormsEditorService _wfes;


public UIMyClassEditorForm()
{
InitializeComponent();
TopLevel = false;
}

private void UIMyClassEditorForm_Load(object sender, EventArgs e)
{
this.propertyGrid1.SelectedObject = MyClass;
}

protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
_wfes.CloseDropDown();
}

MyUITypeEditor.cs
public class MyUITypeEditor : UITypeEditor
{
public override UITypeEditorEditStyle GetEditStyle(
ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.Modal;
}


#region Edit Value
public override object EditValue(ITypeDescriptorContext context,
IServiceProvider provider,
object value)
{
IWindowsFormsEditorService wfes = provider.GetService(
typeof(IWindowsFormsEditorService)) as
IWindowsFormsEditorService;

if (wfes == null) { return value; }

UIMyClassEditorForm form = new UIMyClassEditorForm();

if (value != null)
{
form.MyClass = value;
}
else
{
form.MyClass = new object();
}

form._wfes = wfes;

wfes.DropDownControl(form);

return value;
}
#endregion

}

All the best….
Liron

Tuesday, January 19, 2010

How to update ShowInFileDlg programmatically


At some point in your SharePoint development life time you will probably need to update the ShowInFileDlg attribute of a Site Column.

If you will try to do that by a feature and update the XML with new Field's attributes values, the changes will only take effect on new instances, and will not effect on exsisting ContentTypes or Lists that use these Site Columns.

Programmatically updating the Site Column and the Content Type, the changes will be deployed to the children as well.

Here is a generic method for updating any attribute of the Field element and forcing the changes to the Content Type and its children:

public void UpdateFieldAttribute(string siteCollectionURL, string siteColumnName, string contentTypeName, string fieldAttributeName, string fieldAttributeValue)
{
SPSite site = null;
SPWeb web = null;
try
{
using (site = new SPSite(siteCollectionURL))
{
using (web = site.OpenWeb())
{

SPField siteColumn = site.RootWeb.Fields.GetField(siteColumnName);
XmlDocument fieldSchemaXml = new XmlDocument();
fieldSchemaXml.LoadXml(siteColumn.SchemaXml);
XmlNode fieldXmlNode = fieldSchemaXml.SelectSingleNode("Field");
XmlAttribute attr = fieldXmlNode.Attributes[fieldAttributeName];
attr.InnerText = fieldAttributeValue; ;

siteColumn.SchemaXml = fieldXmlNode.OuterXml;
siteColumn.Update(true);

SPContentType contentType = site.RootWeb.ContentTypes[contentTypeName];

contentType.Update(true, false); //Updating the content type is important or the changes will not be reflected
}
}
}
finally
{
if (web != null)
web.Dispose();
if (site != null)
site.Dispose();
}
}

Monday, August 27, 2007

Send Link By Email - Broken URL

For a few weeks, we are facing a problem when trying to send a link to a document from the document library (This occurs only for documents with a non English file name).
Clicking on the "Send To-> Send Link By Email" opens the new message window, but with a broken URL to the document.



Last night I cleared some time for this issue. After searching the MOSS javascripts I found the solution !!!
Within the C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\LAYOUTS\1037 Directory (1037 is for the Hebrew version) there is a js file named CORE.JS, inside is located the AddSendSubMenu function, this function generate the "Send" sub-menu that appear when clicking on a list item.

In order to solve the broken URL problem, find this line:
fileUrl=escapeProperly(httpRootWithSlash.substr(0, slashLoc))+currentItemUrl;

And replace it with this line:
fileUrl=escapeProperly(httpRootWithSlash.substr(0, slashLoc))+currentItemEscapedFileUrl;


Save the file, and now after clicking the "Send Link By Email" .....


I hope this solution will be of use for you....

Wednesday, August 8, 2007

MOSS List Event Receiver Register application

We developed an ItemEventReceiver to do somthing whenever a list item is added to a list.

In order to register this ItemEventReceiver to a list I created a WinForm application that should run on the MOSS and should register the ItemEventReceiver assembly to the list.

The application has the abbility to add the ItemEventReceiver assembly to any of the list item's available Event Types.

This is a quite simple application:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

using Microsoft.SharePoint;

namespace MOSSListEventRegister

{

public partial class MOSSListEventRegisterForm : Form

{

public MOSSListEventRegisterForm()

{

InitializeComponent();

}

private void MOSSListEventRegisterForm_Load(object sender, EventArgs e)

{

//Fill EventReceiverTypeCheckedListBox

EventReceiverTypeCheckedListBox.Items.Add("ItemAdded");

EventReceiverTypeCheckedListBox.Items.Add("ItemAdding");

EventReceiverTypeCheckedListBox.Items.Add("ItemAttachmentAdded");

EventReceiverTypeCheckedListBox.Items.Add("ItemAttachmentAdding");

EventReceiverTypeCheckedListBox.Items.Add("ItemAttachmentDeleted");

EventReceiverTypeCheckedListBox.Items.Add("ItemAttachmentDeleting");

EventReceiverTypeCheckedListBox.Items.Add("ItemCheckedIn");

EventReceiverTypeCheckedListBox.Items.Add("ItemCheckedOut");

EventReceiverTypeCheckedListBox.Items.Add("ItemCheckingIn");

EventReceiverTypeCheckedListBox.Items.Add("ItemCheckingOut");

EventReceiverTypeCheckedListBox.Items.Add("ItemDeleted");

EventReceiverTypeCheckedListBox.Items.Add("ItemDeleting");

EventReceiverTypeCheckedListBox.Items.Add("ItemUpdated");

EventReceiverTypeCheckedListBox.Items.Add("ItemUpdating");

}

private void RegisterButton_Click(object sender, EventArgs e)

{

SPSite site = null;

SPWeb web = null;

SPList myList = null;

try

{

site = new SPSite(SiteURLTextBox.Text);

web = site.OpenWeb();

myList = web.Lists[ListsNameComboBox.SelectedText];

for (int i = 0; i < EventReceiverTypeCheckedListBox.Items.Count; i++)

{

switch (EventReceiverTypeCheckedListBox.Items.ToString())

{

case "ItemAdded":

myList.EventReceivers.Add(SPEventReceiverType.ItemAdded, AssemblyNameTextBox.Text, ClassNameTextBox.Text);

break;

case "ItemAdding":

myList.EventReceivers.Add(SPEventReceiverType.ItemAdding, AssemblyNameTextBox.Text, ClassNameTextBox.Text);

break;

case "ItemAttachmentAdded":

myList.EventReceivers.Add(SPEventReceiverType.ItemAttachmentAdded, AssemblyNameTextBox.Text, ClassNameTextBox.Text);

break;

case "ItemAttachmentAdding":

myList.EventReceivers.Add(SPEventReceiverType.ItemAttachmentAdding, AssemblyNameTextBox.Text, ClassNameTextBox.Text);

break;

case "ItemAttachmentDeleted":

myList.EventReceivers.Add(SPEventReceiverType.ItemAttachmentDeleted, AssemblyNameTextBox.Text, ClassNameTextBox.Text);

break;

case "ItemAttachmentDeleting":

myList.EventReceivers.Add(SPEventReceiverType.ItemAttachmentDeleting, AssemblyNameTextBox.Text, ClassNameTextBox.Text);

break;

case "ItemCheckedIn":

myList.EventReceivers.Add(SPEventReceiverType.ItemCheckedIn, AssemblyNameTextBox.Text, ClassNameTextBox.Text);

break;

case "ItemCheckedOut":

myList.EventReceivers.Add(SPEventReceiverType.ItemCheckedOut, AssemblyNameTextBox.Text, ClassNameTextBox.Text);

break;

case "ItemCheckingIn":

myList.EventReceivers.Add(SPEventReceiverType.ItemCheckingIn, AssemblyNameTextBox.Text, ClassNameTextBox.Text);

break;

case "ItemCheckingOut":

myList.EventReceivers.Add(SPEventReceiverType.ItemCheckingOut, AssemblyNameTextBox.Text, ClassNameTextBox.Text);

break;

case "ItemDeleted":

myList.EventReceivers.Add(SPEventReceiverType.ItemDeleted, AssemblyNameTextBox.Text, ClassNameTextBox.Text);

break;

case "ItemDeleting":

myList.EventReceivers.Add(SPEventReceiverType.ItemDeleting, AssemblyNameTextBox.Text, ClassNameTextBox.Text);

break;

case "ItemUpdated":

myList.EventReceivers.Add(SPEventReceiverType.ItemUpdated, AssemblyNameTextBox.Text, ClassNameTextBox.Text);

break;

case "ItemUpdating":

myList.EventReceivers.Add(SPEventReceiverType.ItemUpdating, AssemblyNameTextBox.Text, ClassNameTextBox.Text);

break;

}

}

}

catch (Exception ex)

{

MessageBox.Show(ex.Message);

}

finally

{

if (site != null)

{

site.Close();

site = null;

}

if (web != null)

{

web.Close();

web = null;

}

}

}

private void GetListsButton_Click(object sender, EventArgs e)

{

SPSite site = null;

SPWeb web = null;

SPList myList = null;

try

{

ListsNameComboBox.Items.Clear();

site = new SPSite(SiteURLTextBox.Text);

web = site.OpenWeb();

foreach (SPList lst in web.Lists)

{

if (!lst.Hidden )

ListsNameComboBox.Items.Add(lst.Title);

}

}

catch (Exception ex)

{

MessageBox.Show(ex.Message);

}

finally

{

if (site != null)

{

site.Close();

site = null;

}

if (web != null)

{

web.Close();

web = null;

}

}

}

}

}