Friday, June 23, 2017

Driving Your Career

"Driving your career" is the name of a presentation I gave at the "ABI.New York – Women Entrepreneurship & Innovation Summit".

The inspiration for this presentation came from endless conversations I had with women in dev summits around visibility, sponsorship and networking which many of us find intimidating.

But while writing the presentation and consulting with my manager I learned on the three main career stage and was surprised to discover that in each stage we are not aware to the next stage until we are ready to move on to it.

For example: talented developers discover in early stages that they are given tasks to provide architecture, thinking this is the peak of their career, not aware to the great distance between designing a system to a real tech lead that also need to know how to provide right estimations, manage the work distribution and ramp up every new team-member.

With each career stage the responsibility is growing, but so is the impact we have on our customers' life.

Here is the recording of the presentation, I hope you'll enjoy it:

Sunday, January 29, 2012

netsh

Everytime I write a new WCF service that uses http, I find myself searching my memory for this simple but yet forgettable simple command:
netsh http add urlacl url=http://+:8080/IService/ user=\Everyone
Now I know where to find it ;-).

And for those who are not familiar with this command, netsh http add urlacl as the MSDN states: assigns the rights for a portion of the HTTP URL namespace to a particular group of users.

More information about netsh.

So now we have the permission to run the self hosted service locally.

Wednesday, January 25, 2012

CsvHelper

In the last six months I've been writing a couple of tools that reads some data from a csv file, calculate statistics on them and output the results to another csv file. The input file was usually generated by a website (AdWords/AdSense and so...) and the output file was supposed to be consumed by an sql bulk insert or just for view by excel.

All these requirement needed that I would be able to read and write proper csv files.

Using Josh Close's CsvHelper made this mission really simple. For example this is a basic reading code:

public IEnumerable<Input> Read(string fileName)
{
using(var fileReader = File.OpenText(fileName))
using(var csvReader = new CsvHelper.CsvReader(fileReader))
{
while (csvReader.Read())
{
var record = csvReader.GetRecord<Input>();
yield return record;
}
}
}

Notice the elegant ORM, just define the columns you wish to read in a data class and the reader will do all the mapping for you (If you wish to map the data yourself it is possible, and I even used it once for a generic reader, but why?).

And here is a writing example:

public void Write(string fileName, IEnumerable records)
{
using (var textWriter = File.CreateText(fileName))
using (var writer = new CsvWriter(textWriter))
{
foreach (var record in records)
{
writer.WriteRecord(record);
}
}
}


You can even control the column name and index with the CsvFieldAttribute:


public class Record
{
[CsvField(Name="very important data")]
public string SomeData { get; set; }

[CsvField(Index = 4)]
public int SomeNumericData { get; set; }
}


Cool, isn't it?

There are some things I wish to point:
1. CsvReader doesn't need to know about all the columns in the file, only the ones you wish to read (ActiveRecord, try to learn from this...:-)).
2. In the past encoding was not controled by the consumer of the lib. We had a problem with files comming from foreign servers with different encoding, but the CsvReader was using CultureInfo.CurrentCulture. Luckily this is no longer so, you can specify "UseInvariantCulture" in CsvConfiguration.
3. CsvWriter is always adding a NewLine at the end of each file. Because of our need in bulk insert validation, we needed to remove this line. Since I had some time back then I wroting this simple decorater over TextWriter, that only flushs the last line if it's not empty:

public class CustomTextWriter : TextWriter
{
private readonly TextWriter baseWriter;
private string lastLine;
private bool disposed;

public CustomTextWriter(string fileName)
{
baseWriter = new StreamWriter(fileName, false, Encoding.Unicode);
disposed = false;
}

public override Encoding Encoding
{
get { return Encoding.Unicode; }
}

public override void WriteLine(string value)
{
if (lastLine != null)
baseWriter.WriteLine(lastLine);
lastLine = value;
}

protected override void Dispose(bool disposing)
{
if(disposed)
return;
baseWriter.Write(lastLine);
baseWriter.Dispose();
base.Dispose(disposing);
disposed = true;
}
}


Well, I hope this has been helpful and that you might use it your self :-). If you do, you are more then invited to share in the comments section.

Tuesday, December 7, 2010

DataGridView Custom CheckBox Column

I lately had a need to a checkbox column in a DataGridView, but with custom images (plus, minus and a question mark). DataGridViewCheckBoxColumn images cannot be changed, so I had two options: Customize the OnPaint event, or recreate a new DataGridViewColumn.

I decided to go on the second option. I created a DataGridViewThreeStateCheckBoxColumn class(I prefer long names on abbreviations):

public class DataGridViewThreeStateCheckBoxColumn : DataGridViewImageColumn
{
public DataGridViewThreeStateCheckBoxColumn(ImageList images, bool isThreeState)
{
this.CellTemplate = new DataGridViewThreeStateCheckBoxCell(images, isThreeState, true);
}
}


And a DataGridViewThreeStateCheckBoxCell class:

public enum eState {Unknown = 0, Positive = 1, Negative = 2}
public class DataGridViewThreeStateCheckBoxCell : DataGridViewImageCell
{
private Dictionary StateToImage { get; set; }

private bool IsReadOnly { get; set; }

private eState cellState;
public eState CellState
{
get
{
return cellState;
}
set
{
cellState = value;
this.Value = StateToImage[cellState];
}
}

public DataGridViewThreeStateCheckBoxCell()
{
}

public DataGridViewThreeStateCheckBoxCell(ImageList images, bool isThreeState, bool isReadOnly)
{
StateToImage = new Dictionary { { eState.Unknown, images.Images["question-mark"] }, { eState.Positive, images.Images["plus"] } };
if(isThreeState)
StateToImage[eState.Negative] = images.Images["minus"];
CellState = eState.Unknown;
IsReadOnly = isReadOnly;
}

protected override void OnMouseClick(DataGridViewCellMouseEventArgs e)
{
if (IsReadOnly)
return;

// toggle the cell state
CellState = ((eState)(((int)CellState + 1) % StateToImage.Count));

base.OnMouseClick(e);
}
}


In may case I also need a way to notify the parent on state changes, to update a database. I did this by creating an event that the parent was able to register to.

Thursday, July 22, 2010

Overriding ExpandableObjectConverter::GetProperties

Today I was faced with a BrowsableAttribute problem:

I had a collection that I needed to be able to select from a PropertyGrid, but also be able to edit the items and their properties with a DataGridView. I wanted the PropertyGrid to show only the item name in an expandable control and to be able to edit all the items property in the DataGridView.

When using BrowsableAttribute I had a problem that each time I would have to set the value according to the requesting control. I solved this by overriding ExpandableObjectConverter::GetProperties. I went over the PropertyDescriptorCollection and removed each property I didn't want:

public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
{
PropertyDescriptorCollection collection = base.GetProperties(context, value, attributes);
PropertyDescriptor[] final = new PropertyDescriptor[1];
foreach (PropertyDescriptor descriptor in collection)
{
if (descriptor.Name == "ItemName")
final[0] = descriptor;
}
return new PropertyDescriptorCollection(final);
}

Now when binding the list to DataGridView I would see all the properties, and when expanding the list in PropertyGrid I would see only the Item Name Property.

Saturday, May 15, 2010

Capturing keyboard events in a form

When wishing to capture a keyboard event in winforms, one might encounter a problem that although you can register to capture the keyboard events, the events don't reach the parent form.

The simplest way is to override ProcessCmdKey and processing the message it receives.

I wonder this is so...

Wednesday, May 5, 2010

"Constructor on type 'System.String' not found"

This exception I got yesterday while trying to add an item to a collection in this string collection editor:
















I found no simple solution on the web, but after some thought had this solved by changing the property from a list to an array of strings. This changed the default editor to this simpler string collection editor that worked good enough for me: