Telerik RadGridView – Updating DataTemplate For GridViewImageColumn

This is a quick tip for people doing Silverlight development with the Telerik control set. Particuarlly if you are using the RadGridView.

If you are updating a GridViewImageColumn, a lot of the examples out there say to set the GridViewCellBase.ContentTemplate by indexing on the cell collection. Don’t do this. It appears to arbitrarly updated other columns. Even when they are the wrong column type which is random. So if you are doing this:

[csharp]
GridViewRowItem xGridViewRow = RadGridView.CurrentCell.ParentRow;
GridViewCellBase cell = xGridViewRow.Cells[1];
cell.ContentTemplate = “Selecting Some DataTemplate”;           
[/csharp]

Iterate the cell collection instead and test whatever; header, type, really whatever you want. It’s more consistent. For example, to test the column type:

[csharp]
GridViewRowItem xGridViewRow = RadGridView.CurrentCell.ParentRow;
foreach (GridViewCellBase x in xGridViewRow.Cells.Where(x => x.Column is GridViewImageColumn))
{
x.ContentTemplate = “Selecting Some DataTemplate”;    
}
[/csharp]

 

Share

Invoking The RMS Bulk Protection Tool Remotely

I don’t understand why this was so hard, but it really is. And honestly who wants to use this tool directly on the server? It is more useful when you can bake it into client applications, in my case a VSTO add-in. Furthermore, the Microsoft site says this will work on XP, this is not the case since it will just throw Skipped, file type not supported. I don’t know what that’s about. Furthermore, if you try to invoke the encryption routines on the box while pointing to a network share hosting the application, like this:

[csharp]
var start = new ProcessStartInfo
{
WorkingDirectory=Whatever
Arguments = @” /encrypt \\server\shareimencrypting\ Rights.xml”,
FileName = @”RmsBulk.exe”,
WindowStyle = ProcessWindowStyle.Normal,
CreateNoWindow = false,
UseShellExecute = false
};
using (Process p = Process.Start(start))
{
p.WaitForExit();
}
[/csharp]

It will not work since it can’t hydrate the template file. Returns an error like “you do not have access to the template file or it does not exist”. Or something to that effect.  So, the only real way to do is to execute the task remotely. Since the standard output from the tool is pretty important for interaction purposes (tells supported file types and gives a report of failed / succeeded decryption routines, that pretty much means WMI is out the door since it won’t out a return. So, PSExec comes to the rescue! Or maybe something else this was just what the SP MVP group said would be the path of least resistance.

Long and short of it is, to execute it remotely make two local executables that reside in the shared RMSBulk tool directory (or as long as the wrapper classes for the IRM protector are relative to the tool), respectively:

[csharp]
var start = new ProcessStartInfo
{
Arguments = @” /encrypt \\server\share\ Placitum_Rights.xml”,
FileName = @”RmsBulk.exe”,
WindowStyle = ProcessWindowStyle.Normal,
CreateNoWindow = false,
UseShellExecute = false
};
using (Process p = Process.Start(start))
{
p.WaitForExit();
}
[/csharp]

And for the decryption:

[csharp]

var start = new ProcessStartInfo
{
Arguments = @” /decrypt \\server\share\”,
FileName = @”RmsBulk.exe”,
WindowStyle = ProcessWindowStyle.Normal,
CreateNoWindow = false,
UseShellExecute = false
};
Process p = Process.Start(start);
p.WaitForExit();

}
[/csharp]

Then in your client app, make the appropriate PSExec calls.

For the encryption:

[csharp]
ProcessStartInfo startEncrypt = new ProcessStartInfo
{
WorkingDirectory = @”
“,
FileName = @”
\PsExec.exe”,
WindowStyle = ProcessWindowStyle.Normal,
CreateNoWindow = false,
Arguments = @”\\ -u username -p password -w “”C:\Program Files (x86)\AD RMS Bulk Protection Tool”” “”C:\Program Files (x86)\AD RMS Bulk Protection Tool\Encrypt.exe”””,
UseShellExecute = false
};

Process process = new Process();

process.StartInfo = startEncrypt;
process.Start();
process.WaitForExit();
process.Close();
[/csharp]

For the decryption:

[csharp]
var startDecrypt = new ProcessStartInfo
{
WorkingDirectory = @”

FileName = @”
\PsExec.exe”,
WindowStyle = ProcessWindowStyle.Normal,
CreateNoWindow = false,
Arguments = @”\\ -u username -p password -w “”C:\Program Files (x86)\AD RMS Bulk Protection Tool”” “”C:\Program Files (x86)\AD RMS Bulk Protection Tool\Decrypt.exe”””,
UseShellExecute = false
};

Process process = new Process();
process.StartInfo = startDecrypt;
process.Start();
process.WaitForExit();
process.Close();
[/csharp]

And you can get around 99% of the limitations of the tool. It’s pretty cool when you combine it with FCI, then really get fancy by ad-hoc provisioning plain-text indexing to support encrypted searching routines.

Share

Returning The SharePoint Start Workflow Link

Building the “Start Workflow” link is pretty straight forward. I am pretty sure there are better ways to do it, but here is an approach when you have to build the link using a string return. How it works is pretty straightforward. Consuming a SPListItem and SPWorkflowAssociation parameter, the SPListItem exposes the ParentList and ID properties and the SPWorkflowAssociation provides the InstantiationUrl and Id properties. The only field level stuff is I was passing a finish url in the query string (_finalurl in the below). When the link is built, it is cleaned up using the inherent SPHttpUtility.UrlKeyValueEncode method.

[csharp]
private string _finalurl;

public static string QueryStringAppend(string url, string args)
{
if (string.IsNullOrEmpty(url))
{
return url;
}
var num = url.LastIndexOf(“?”);
switch (num)
{
case -1:
return (string.Format(“{0}?{1}”, url, args));
}
return num == (url.Length – 1) ? url + args : string.Format(“{0}&{1}”, url, args);
}

protected string BuildWorkflowStartLink(SPListItem listItem, SPWorkflowAssociation workflowAssociation)
{
var builder = new StringBuilder();
builder.Append(SPHttpUtility.UrlPathEncode(string.Format(“{0}/{1}”, Web.Url, workflowAssociation.InstantiationUrl), true));
builder.Append(“?List=”);
builder.Append(listItem.ParentList.ID.ToString());
builder.Append(“&ID=”);
builder.Append(listItem.ID.ToString());
builder.Append(“&TemplateID=”);
builder.Append(workflowAssociation.Id.ToString(“B”));
string url = _finalurl ?? Request.QueryString[“Source”];
url = QueryStringAppend(url, string.Format(“{0}={1}”, FinishIdName ?? “ID”, listItem.ID));
if (!string.IsNullOrEmpty(url))
{
builder.Append(“&Source=”);
builder.Append(SPHttpUtility.UrlKeyValueEncode(url));
}
return builder.ToString();
}
[/csharp]

:)

Share