Tuesday, December 22, 2009

Get User Permissions on TFS team project

This code is based on the listing in http://social.msdn.microsoft.com/Forums/en/tfsadmin/thread/9f977d37-23d8-4b07-a5dd-6cdc6d9dc6a6

Requires 2 parameters: windows user id, and team project name
Returns a List of groups in the team project that the user has permissions for


public static List <string> GetAccountPermissions(string account, string projectName)
{
    List <string> groupList = new List <string>();
    String serverUri = @"http://serverName:8080/";
    // connect to the server
    TeamFoundationServer server = new TeamFoundationServer(serverUri);
    // get ICommonStructureService (later to be used to list all team projects)
    ICommonStructureService iss = (ICommonStructureService)server.GetService(typeof(ICommonStructureService));
    // get IGroupSecurityService (later to be used to retrieve identity information)
    IGroupSecurityService2 gss = (IGroupSecurityService2)server.GetService(typeof(IGroupSecurityService2));
    ProjectInfo[] allTeamProjects = iss.ListProjects();
    // iterate thru the team project list
    foreach (ProjectInfo pi in allTeamProjects)
    {
    // ProjectInfo gives you the team project's name, status, and URI.
        String teamProjectName = pi.Name;
        if (pi.Name == projectName)
        {
            Identity[] allProjectGroups = gss.ListApplicationGroups(pi.Uri);
            // iterate thru the project group list and get a list of direct members for each project group
            foreach (Identity projectGroup in allProjectGroups)
            {
                Identity pg = gss.ReadIdentity(SearchFactor.Sid, projectGroup.Sid, QueryMembership.Direct);
                foreach (String groupMemberSid in pg.Members)
                {
                    Identity m = gss.ReadIdentity(SearchFactor.Sid, groupMemberSid, QueryMembership.None);
                    if (m.AccountName == account)
                    {
                        groupList.Add(pg.DisplayName);
                    }
                }
            }
        }
    }
    return groupList;
}

Thursday, December 17, 2009

Check String For Null

It's easy to forget but C# has a handy method to check if a string is null or empty:

If(!String.IsNullOrEmpty(str))
...do something

Wednesday, December 9, 2009

Get List of Allowed Values in TFS Work Item Field

This is how you can obtain programmatically a list of allowed values in a TFS Work Item field (in the example below, in Priority field in Bug template):

TeamFoundationServer tfs = new TeamFoundationServer("myTFServer");

WorkItemStore wis = (WorkItemStore)tfs.GetService(typeof(WorkItemStore));

Project teamProject = wis.Projects["myTeamProjectName"];

WorkItemType wit = teamProject.WorkItemTypes["Bug"];

 

FieldDefinition fd = wit.FieldDefinitions["Microsoft.VSTS.Common.Priority"];

AllowedValuesCollection avc = fd.AllowedValues;

 

foreach (var row in avc)

{

Console.WriteLine(row);

}

Monday, November 16, 2009

Get Current Date and Time in C#

DateTime.Now.ToShortDateString() + " "+ DateTime.Now.ToShortTimeString()

Friday, October 16, 2009

SQL Reporting Matrix Tips

Create a Percent Column in a Matrix

1) Create 2 text boxes in a column
Re: http://www.simple-talk.com/sql/reporting-services/advanced-matrix-reporting-techniques/









2) The first column will contain the standard sum expression : = Sum(Fields!DetaiField.Value)
DetailField is a placeholder for the field that you count on.

3) The second column will contain the following:
= Sum(Fields!DetaiField.Value)/
Sum(Fields!DetaiField.Value,"matrix_RowGroup")

Substitute the name of your row group for "matrix_RowGroup"
What we do here is sum up the count in the default scope divided by the total of items in a row.

4) The last step is to enclose the last expression into FormatPercent function:

FormatPercent(Sum(Fields!DetaiField.Value)/
Sum(Fields!DetaiField.Value,"matrix_RowGroup"))


Show a Variance Instead of a Total in the Subtotal Column

If you have a 2-column matrix, and you want to show a variance instead of the subtotal, you could use the following expression:

=Iif (inScope("matrix_ColumnGroupName"), Sum(Fields!DataField.Value),
Sum (IIF(Fields!ColumnName.Value = "Closed",
Fields!DataField.Value, Fields!DataField.Value * -1)))

First, you define an expression for the column data fields: Sum(Fields!DataField.Value).
The second part of the IIF function defines an expression for the Subtotal column. The value of the second data column becomes negative which allows us to obtain the variance instead of a sum. The expression assumes that the first column is named "Closed".

An example:

Date\State

Closed

Pending

Variance
8/17/2009 317 22 295
8/18/2009 5215 816 4399
9/14/2009 5526 503 5023
9/16/2009 49 3 46

Create a Variance Percentage Column

If instead of the variance you want to show a variance percentage, you need to use the following expression in the subtotal column created earlier:

FormatPercent (Sum (IIF(Fields!State.Value = "Closed", Fields!DataField.Value, Fields!DataField.Value * -1))/ Sum(Fields!DataField.Value)))

What you do here is obtain a variance value first, then a simple sum of all data fields in the row, and then divide the first value by the second.

Wednesday, August 26, 2009

Change Control Size Automatically with Form Size Change

Here is how you can change a form control size automatically when the form size is changed by user.
Declare a class variable that will hold the value of the current form size, and set its value in the contructor.

Size curSize;
public Form1()
{
InitializeComponent();
curSize = this.Size;
}

To capture form size change, use the ClientSizeChanged event handler with the following code:

private void Form1_ClientSizeChanged(object sender, EventArgs e)
{
    int heightDif = Size.Height - curSize.Height;
    int widthDif = Size.Width - curSize.Width;
    yourControlName.Height += heightDif;
    yourControlName.Width += widthDif;
    //store the current size until the next time this event is raised
    curSize = this.Size;
}


Friday, July 24, 2009

Capture the Enter key on WinForm Text-box

If you want to to capture the Enter key when you finish entering data in a .NET Framework WinForm text-box, and imitate clicking on a button, you should attach a KeyDown event to the text-box first.



In the KeyDown event handler code, use the following:

private void Text1_KeyDown(object sender, KeyEventArgs e)
{
    if (e.KeyCode == Keys.Enter)
       this.Close();
If you have a button on the form with DialogResult property set to OK, closing the form will be equal to clicking that button.

However, in this case, a simpler solution is to set the form's AcceptButton property to the name of your OK button. This will have the same effect.

Tuesday, June 30, 2009

Remove List Elements That Exist in Another List

Problem:

We have two lists:


List bannedList = new List { "one", "three", "seven" };
List myList = new List { "one", "two", "three", "four", "five", "six" };


We need to keep only those entries in myList that are not contained in bannedList.

First of all, the conventional C# 1.0 approach to this problem:

List listDistinct = new List();
foreach (string elem in myList )
{
if (!bannedList.Contains(elem))
{
listDistinct.Add(elem);
}
}


Now, let's use lambda expressions to arrive at a much shorter syntax.

List listDistinct= myList .FindAll (elem => !bannedList.Contains(elem));
listDistinct.ForEach(elem=>Console.WriteLine(elem));
The result is:
two
four
five
six

By the way, if the first statement returns a List, you can chain template methods as follows:

myList.FindAll (elem => !bannedList.Contains(elem))
.ForEach(elem=>Console.WriteLine(elem));


But the easiest approach that does not involve creating a third list is to use the RemoveAll template method:

myList.RemoveAll(elem => bannedList.Contains(elem));

Thursday, June 11, 2009

Easy Syntax to Print List Elements

Create a list.
List <string> myList = new List <string> { "a", "b", "c", "d"};

a list-printing delegate :
Action <string> print = elem => { Console.WriteLine(elem);};

a statement:
myList.ForEach(print);



Friday, May 8, 2009

Get Rid of a Blank Row When Exporting to Excel

When you export a GridView to Excel using C# code similar to this:

Response.ClearContent();
Response.ContentType = "application/excel";
Response.AddHeader("content-disposition", "attachment; filename=data.xls");

Response.ContentEncoding = System.Text.Encoding.Unicode;
Response.BinaryWrite(System.Text.Encoding.Unicode.GetPreamble());
this.EnableViewState = false;

System.IO.StringWriter strWriter = new System.IO.StringWriter();
HtmlTextWriter htmlTextWriter = new HtmlTextWriter(strWriter);

gv.RenderControl(htmlTextWriter);

htmlTextWriter.Close();
strWriter.Close();

Response.Write(strWriter.ToString());
HttpContext.Current.ApplicationInstance.CompleteRequest();

You end up with the first row being blank in Excel.

To fix this problem, you need to override the Render (HtmlTextWriter writer) method:

protected override void Render(HtmlTextWriter writer)
{
}

Wednesday, April 29, 2009

Create a Checked Listbox with Key/Values Pairs

Sometimes, there is a need to display one set of strings in a checked listbox and use a different one in your code. For example, a user selects 'Washington', and you want the code to use 'WA'.
If that's the case, a Dictionary object will suit your needs. First, let's start with building a Dictionary:


public Dictionary<string, string> dicStates = new Dictionary<string, string>
        {
            { "Washington", "WA"},
            {"New York", "NY"},
            {"Texas", "TX"}
        };


Strings to be displayed in the checked listbox become dictionary keys, and strings to be used in your code become dictionary values.

Then, in your form constructor you populate the CheckedListBox:
foreach (var item in dicStates )
{
    clb1.Items.Add(item.Key);
}



To capture user-selected values, use the following code:


foreach (var key in clb1.CheckedItems)
{
    string val = string.Empty;
    dicStates .TryGetValue(key.ToString(), out val);
}


The string val will hold the Dictionary value - WA, NY or TX depending on the user selection.

Friday, April 3, 2009

Files and Directories

To get information about a directory, first you need to create a DirectoryInfo object:
string strPath = @"C:\Temp\Test1"
DirectoryInfo dInfo = new DirectoryInfo(strPath);

dInfo.Name gets the directory name (Test1)
dInfo.Parent gets the parent directory name (Temp)
dInfo.FullName gets the full path (C:\Temp\Test1)


Create a directory if it does not exist:

if (!dInfo.Exists)
dInfo.Create();


To get an array of subdirectories use:
DirectoryInfo[] subDirInfo = dInfo.GetDirectories();

Get File Size:

FileInfo fileInfo = new FileInfo(strPath);
Console.WriteLine(fileInfo.Length);


Get a directory name from a file name:

FileInfo fileInfo = new FileInfo("C:\\MyFolder\\MyFile.exe");
Console.WriteLine(fileInfo.DirectoryName);

To change file timestamp after FileStream write use the following methods

File.SetCreationTime(filepath, DateTime);
File.SetLastWriteTime(filepath, DateTime);


Surround Commas with Double Quotes

This is how you surround commas with double quotes.
string str = "This, is, a string, with multiple, commas";
str = str.Replace(",", "\",\"");
The result will look like this:

This"," is"," a string"," with multiple"," commas

Thursday, April 2, 2009

Method to Surround Substrings with Single Quotes

If you have a long string containing substrings delimited by commas, you may need to surround each piece with single commas.
For example: trains, planes, automobiles.
In such a case, this method may come in handy:

public static string delimitString(string str){
string[] arr = str.Split(',');
StringBuilder sb = new StringBuilder();
foreach (string s in arr)
{
sb.Append("'" + s.Trim() + "',");
}
sb.Length--;
return sb.ToString();
}

The resulting string will look like this: 'trains', 'planes', 'automobiles'

Thursday, March 26, 2009

DataTable Manipulation

Here are some interesting ways to manipulate a DataTable.

First, to get the number of columns in a DataTable you can use the following code:

int colCount = myDataTable.Columns.Count;

To add a new column to a DataTable, you could use the following code:

myDataTable.Columns.Add(new DataColumn("myColumnName"));

To add a new row to the DataTable, use this:

myDataTable.Rows.Add(myDataTable.NewRow());



Read all the values in the DataTable: for (int r = 0; r < myDataTable.Rows.Count; r++ )
 {
     for (int c = 0; c < colCount; c++)
     {
     Console.WriteLine("row: {0} col: {1} value: {2}", r, c, myDataTable.Rows[r][c]);
     }
 } 


This is how you could find a row in the DataTable:
DataRow[] dRow = myDataTable.Select ("myNumericColumnName=123);

DataRow[] dRow = myDataTable.Select ("myStringTypeColumnName='abc'");


This method is much faster than going through each row and examining a column value.


Here is how you could add data from one DataTable to another one. The DataTables have  the same unique id field:

foreach (DataRow dr in myDataTable.Rows)
{
     //Find a corresponding row in the second DataTable
     DataRow[] drs = secondDataTable.Select("ID=" + dr["ID"].ToString());    
      if (drs.Length > 0)   
            dr["myField"] = drs[0]["myField"];
}