Tag Archives: code

ListViewEx – Auto resize selected column

What do you do when you get fed up having to write the same code over and over again? Write a base class for it… of course.

I regularly use the WinForms ListView control and often want to specify a specific column (in detail view) that must auto resize when the whole control resize. Therefore I created the following class that does all that (and more stuff) to make life easier.

public class ListViewEx : ListView
    {
        public ListViewEx()
            : base()
        {
            DoubleBuffered = true;
            View = View.Details;
            resizeTimer.Tick +=  resizeTimer_Tick;
        }

        [Description("Use one column to auto resize in detail view")]
        public bool AutoResizeColumnEnabled { get; set; }
        [Description("Column index of auto resize column")]
        public int AutoResizeColumnIndex { get; set; }
        public event MethodInvoker EnterKeyPressed;
        public event MethodInvoker DeleteKeyPressed;
        protected override void OnKeyPress(KeyPressEventArgs e)
        {
            if (e.KeyChar == '\r')
                if (EnterKeyPressed != null)
                {
                    EnterKeyPressed();
                    e.Handled = true;
                }
            base.OnKeyPress(e);
        }
        protected override void OnKeyDown(KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Delete)
                if (DeleteKeyPressed != null)
                {
                    DeleteKeyPressed();
                    e.Handled = true;
                }
            base.OnKeyDown(e);
        }
        private Timer resizeTimer = new Timer() { Interval = 100, Enabled = false };
        private void resizeTimer_Tick(object sender, EventArgs e)
        {
            resizeTimer.Enabled = false;
            try
            {
                if (AutoResizeColumnEnabled && View == System.Windows.Forms.View.Details &&
                    AutoResizeColumnIndex > -1 && this.Columns.Count > AutoResizeColumnIndex)
                {
                    int columnsWidth = 0;
                    Application.DoEvents();
                    for (int i = 0; i < this.Columns.Count; i++)
                    {
                        if (i != AutoResizeColumnIndex)
                            columnsWidth += this.Columns[i].Width;
                    }
                    this.Columns[AutoResizeColumnIndex].Width = this.ClientSize.Width - columnsWidth - 2;
                }
            }
            catch { }
        }
        protected override void OnResize(EventArgs e)
        {
            resizeTimer.Enabled = false;
            resizeTimer.Enabled = true;
            base.OnResize(e);
        }
    }

Now all you have to do is set the AutoResizeColumnEnabled property to true and specify a column index for AutoResizeColumnIndex and there you go. Easy hey?

Should I handle Exceptions or not?

I’ll start this post with a statement or answer that might seem controversial.

The answer is ‘NO’

Why? Let me explain. If your code has reached a state where an Exception has been thrown it means you have already missed something (possible) important that should have been addressed. Sure, throwing (excuse the pun) a ‘try… catch’ around every block of code is nice and all – and you should do it anyway (for other reasons) but it is no excuse for writing bad code.

More details

One reason I say these things I recently (re)discovered myself… again is that ‘Performance’ in an application can greatly be influenced by exceptions since the whole process of encountering/throwing an exception in code is a slow thing. When you have code that relies on catching an exception in order to handle an (possibly) expected condition of some variables it is a sign that you are doing it wrong… It may not be a big issue if the affected code is called only once in a blue moon but once it is in a section that is called repeatedly and is expected to perform at speed it becomes a huge issue.

Have a look at this code. It will run fine but and actually be usable but…

try
{
   SomeType tp = SomeObject.SomeVar;
}
catch // null reference exception or something expected the first time
{
  SomeObject = new SomeObjectType();
  ...
}

Now look at a better way

if (SomeObject == null)

SomeObject = new SomeObjectType();

SomeType tp = SomeObject.SomeVar;

...

This code will actually run faster and does not rely on an Exception to handle something that should be done right to start with.

Ok, there you have it…

Adding performance counters to your application (C#)

Nothing about this is exactly new or ground breaking but few developers (enterprise) these days add proper monitoring abilities to their apps. We (now that I mostly do administration and management of other peoples apps) that has to support these things don’t come equipped with x-ray eyes or ESP pills so knowing how the the internals of ‘your’ works is an issue…

Classically developers tend to use stuff like log file, event log and so on to ‘see’ what is going on inside their apps. However, these things also pick up a lot of noise so they usually get turn off for production use but that still leaves us with the requirements that we want to know ‘what your app is doing all the time’ – when we want to track it. Ok, to make a long story shorter, there is such a thing like performance counters that can help us to know if your app is performing or not. What they are and what they can do for you you can go read up on MSDN, Google etc.

Now, it appears most developers are scared of these things – or just too lazy to implement them. I’ve created a little helper class that makes it at least a little easier to implement – without all the worries about what happens if things blow up etc. It is written is such a way that if itself ‘breaks’ it should not break the rest of the app (don’t contribute to a bigger problem).

Setting it all up.

Creating a ‘Category’ is the first step in setting up a performance counter. Once it is created you don’t have to recreate it again (unless you go and delete it which would be rather stupid). The following routine do just that.

PerformanceCounterCategory InitializeCategory(string category, CounterCreationData[] creationData, string instance = "")
        {
            PerformanceCounterCategory pcc = null;
            if (!PerformanceCounterCategory.Exists(category))
            {
                if (instance.Length > 0)
                    pcc = PerformanceCounterCategory.Create(category, category, PerformanceCounterCategoryType.MultiInstance, new CounterCreationDataCollection(creationData));
                else
                    pcc = PerformanceCounterCategory.Create(category, category, PerformanceCounterCategoryType.SingleInstance, new CounterCreationDataCollection(creationData));
            }
            else
                pcc = new PerformanceCounterCategory(category);
            return pcc;
        }

All this does is create the category for you if it doesn’t exist yet or else just returns the existing one. All you specify is the name and the definitions of the counters you want to use. Optionally you can specify an ‘instance name’ which is handy if you have multiple instances of the same set of ‘things’ you want to ‘monitor’. The default is a single instance (e.g. like a global instance). Keep in mind that a single category can only have counters of one of two types – either single instance or multi-instance counters. This cannot be changed unless the whole category is deleted and recreated again.

The next step is to create run-time ‘instances’ of the counters.

PerformanceCounter InitializePerfCounter(string categoryName, string counterName, string instanceName = "")
        {
            PerformanceCounter counter = null;
            try
            {
                if (instanceName.Length > 0)
                {
                    if (IsCategoryMultiInstance(categoryName))
                        counter = new PerformanceCounter(categoryName, counterName, instanceName, false);
                    else
                        RaiseWarningMessage(string.Format("Performance category '{0}' is not set up for multiple instances! ({1})", categoryName, counterName));
                }
                else
                {
                    if (!IsCategoryMultiInstance(categoryName))
                        counter = new PerformanceCounter(categoryName, counterName, false);
                    else
                        RaiseWarningMessage(string.Format("Performance category '{0}' is not set up for single instance use! ({1})", categoryName, counterName));
                }
                if (counter != null)
                {
                    counter.BeginInit();
                    counter.RawValue = 0;
                    counter.EndInit();
                }
            }
            catch (Exception ex)
            {
                RaiseErrorMessage(string.Format("Error initializing performance counter '{0}'!\r\n{1}", counterName, ex.ToString()));
            }
            return counter;
        }

There are a couple of sub-routines not listed yet. Please just ignore for now – they will be included in the attached sample code.

Next step is just how to use them – setting the values. I tend to only use two types of counters – a ‘rate of’ and absolute values. The ‘rate of’ type of counters are typically used to track the number of events or sum of something per second while absolute values track the actual value of something as it is ‘now’ at that moment of tracking – e.g. CPU % usage.

void SetCounterValue(PerformanceCounter counter, long value)
        {
            try
            {
                if (counter == null)
                {
                    RaiseWarningMessage("Performance counter not set up or installed!");
                }
                else
                {
                    counter.RawValue = value;
                }
            }
            catch (Exception ex)
            {
                RaiseErrorMessage(string.Format("Increment performance counter error! : {0}\r\n{1}", counter.CounterName, ex.ToString()));
            }
        }
void IncrementCounter(PerformanceCounter counter)
        {
            IncrementCounterBy(counter, 1);
        }
void IncrementCounterBy(PerformanceCounter counter, long incBy)
        {
            try
            {
                if (counter == null)
                {
                    RaiseWarningMessage("Performance counter not set up or installed!");
                }
                else
                {
                    counter.IncrementBy(incBy);
                }
            }
            catch (Exception ex)
            {
                RaiseErrorMessage(string.Format("Increment performance counter error! : {0}\r\n{1}", counter.CounterName, ex.ToString()));
            }
        }

Events
In order to provide all this functionality without ‘breaking’ anything else I make use of ‘events’ e.g. RaiseWarningMessage and RaiseErrorMessage. The calling class/code don’t have to make use of the events but of course that would make troubleshooting a bit harder if needed. The code for this is fairly simple:

        public event MessageRaisedDelegate ErrorRaised;
        internal void RaiseErrorMessage(string message)
        {
            if (ErrorRaised != null)
            {
                ErrorRaised(message);
            }
        }
        public event MessageRaisedDelegate WarningRaised;
        internal void RaiseWarningMessage(string message)
        {
            if (WarningRaised != null)
            {
                WarningRaised(message);
            }
        }

Implementation
It is possible to use the utility class ‘as is’ but I would recommend doing the following to provide ‘cleaner’ code. Inheriting from the class ‘PerfCounterUtilBase’ (not shown in above code) and implementing all the specific performance counter functionality ‘you’ need is a better way to so it. The following is just example code to initialize the performance counter category and counters you want to use:

void InitializePerformanceCounters()
        {
            string lastErr = "Create performance counter category error!: {0}";
            try
            {
                CounterCreationData[] creationData = new CounterCreationData[]
                    {
                        new CounterCreationData("Clicks/Sec", "Clicks per second", PerformanceCounterType.RateOfCountsPerSecond32),
                        new CounterCreationData("Total X value/Sec", "Sum of X values per second", PerformanceCounterType.RateOfCountsPerSecond32),
                        new CounterCreationData("Total Y value/Sec", "Sum of Y values per second", PerformanceCounterType.RateOfCountsPerSecond32),
                        new CounterCreationData("Last X value", "Last X value", PerformanceCounterType.NumberOfItems32),
                        new CounterCreationData("Last Y value", "Last Y value", PerformanceCounterType.NumberOfItems32)
                    };
                InitializeCategory(Category, creationData, Instance);

                lastErr = "Initialize performance counter(s) error!: {0}";
                clicksPerSecond = InitializePerfCounter(Category, "Clicks/Sec", Instance);
                xValuePerSecond = InitializePerfCounter(Category, "Total X value/Sec", Instance);
                yValuePerSecond = InitializePerfCounter(Category, "Total Y value/Sec", Instance);
                lastXValue = InitializePerfCounter(Category, "Last X value", Instance);
                lastYValue = InitializePerfCounter(Category, "Last Y value", Instance);
            }
            catch (Exception ex)
            {
                RaiseErrorMessage(string.Format(lastErr, ex.Message));
            }
        }

Then you can simply have specific methods like these to use in your own code:

public void IncClicks()
        {
            IncrementCounter(clicksPerSecond);
        }
        public void IncXValues(long value)
        {
            IncrementCounterBy(xValuePerSecond, value);
        }
...

In ‘your’ code you simply do this then:

pcu = new PerfCounterExampleImplemetation();
pcu.ErrorRaised += new MessageRaisedDelegate(pcu_ErrorRaised);
pcu.WarningRaised += new MessageRaisedDelegate(pcu_WarningRaised);
pcu.Category = txtCategory.Text;
pcu.Instance = txtInstance.Text;
pcu.InitializePerformanceCounters();
...
void pcu_ErrorRaised(string message)
        {
            MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

void SomeMethod()
        {
            long val = GetSomeValue();

            if (pcu != null)
            {
                pcu.IncClicks();
                pcu.IncXValues(val);
                ...
            }
        }

Now go have fun…

Example code: ShowPerfCounterUtils

VS2012 Express for Desktop

I’ve been waiting for this for a while so I was glad when they finally released this. Now for some initial feedback.

First off, the download was reasonable – size and speed wise. The installation was, lets just say ok – as I had to reboot since it had to update some libraries that were is ‘use’ at the time. Registration was also not too bad – since I have an old existing Hotmail/Live account where more of the details were already populated. Running it for the first time is where the shock comes in… it is as ugly as hell (reminds me death, all grey and boring). Unfortunately the same would apply to any of the other Express and even full versions of VS2012.

VS2012 Express For Desktop development

Functionality wise it provides just the very basics – not that you can expect anything more. Since I haven’t installed the ‘full’ express version I cannot comment on any other functionality that version might have. Anyway, The only templates worth mentioning is the Windows Forms, WPF and Console ones. Again, one cannot expect anything more of this release. Interestingly enough, when creating a new project the framework version cannot be changed on the ‘create project’ dialog screen. You can only change this ‘after’ the project has already been created.

One nice thing is that you can still create custom toolbars with ‘external’ commands – I use it to run a source backup tool I created some time ago. Another thing to remember is that this tool can be installed in Windows 7, unlike the full Express version that can ONLY be installed on Windows 8. The Web express version can also be installed on 7 (plus the TFS Express version).

If you excuse the way it looks (wearing shades to protect your eyes) then this tool is not that bad… Just wish they allowed old fashioned ‘themes’ to change the look and feel of the entire editor. Ah well, it is an ‘Express’ product… Fortunately you can import your VS 2010 color and font settings to get all your customizations back (even though it does moan about a whole bunch of settings that are not applicable to this edition which you can ignore)

In order to try it out you can follow this link.

Update:
If you like to change the overall theme and don’t like the built-in Light or Dark there are some more options if you look at this blog entry.

HTMLWriter 1.7

Just a quick refresh on my HTMLWriter utility library. Some minor changes/additions:

1. Added support for the NOBR tag

2. Improved the special character functions including ignoring the ‘&’ sign when needed.

Latest version here.

Passing a ‘Method’ as parameter in C#

This is actually nothing new but sometimes you might still need a quick reference for to remember how to do this quickly… Say you have a generic class that does something like generating a report and display it somehow (or save or whatever the class do) and want all the ‘calling classes’ to just pass the ‘Method’ that it must ‘run’ in order to generate the report. Yes there are probably nice and fancy tools these days that could also do it if you have the mulla for it…

A solution is to use Anonymous methods that has been with C# (.Net) since version 3 of something.

Reporter r = new Reporter();
r.Report = delegate
{
string stuff = "example report yada yada yada";
return stuff;
}
r.Show();

The generic class that provides the ‘generic’ functionality can then look something like this using a defined delegate so it knows what output it will receive when ‘running’ the method.

public delegate string RefreshActionDelegate();
class Reporter
{
    public RefreshActionDelegate Report { get; set; }

    public Show()
    {
       if (Report != null)
       {
          string theContent = Report();
          DoSomethingWithContent(theContent);
       }
    }
}

This is just a quick example but it shows how you can use the main ‘generic’ class from multiple places each time just passing a different ‘Method’ with its own functionality.

Formatting C# code in WordPress post

If you are like me working with C# a lot and trying to post articles on your WordPress site you might like this: Alex Gorbatchev’s SyntaxHighlighter

Example source code listing

[ sourcecode language=”csharp” ]
void Stuff
{

int moreStuff = 0;

}
[ /sourcecode ]

Would look like this:

void Stuff
{
    int moreStuff = 0;
}

I haven’t tested it with all possible language features but at least it is a start!

Linq – group by multiple fields

Seems this is an issue that multiple people have asked around at several occasions.

The question is how to use a Linq query where you want to group on more than one ‘field’

Turns out it is really not that hard. Thanks to ‘Anonymous’ methods that was also introduced ‘yay back’ it is as simple as the following example. Lets say you have a list of values like these:

Person 1: Age = 25, Gender = M, HighScore = 123
Person 2: Age = 21, Gender = F, HighScore = 99
Person 3: Age = 27, Gender = M, HighScore = 140
Person 4: Age = 19, Gender = M, HighScore = 131
Person 5: Age = 25, Gender = M, HighScore = 119
Person 6: Age = 22, Gender = M, HighScore = 108
Person 7: Age = 27, Gender = M, HighScore = 152
Person 8: Age = 21, Gender = M, HighScore = 98
Person 9: Age = 22, Gender = M, HighScore = 101
Person 10: Age = 25, Gender = M, HighScore = 167
Person 11: Age = 22, Gender = F, HighScore = 105
… etc

To get a simple report on average high score by Age and Gender you’ll have to use a query like this:

foreach(var entry in (from p in Persons
group p by new {  Age = p.Age, Gender = p.Gender } into g
orderby g.Key.Age, g.Key.Gender
select new
{
Age = g.Key.Age,
Gender = g.Key.Gender,
Avg = g.Average(pavg=>p.HighScore)
} ))

{

Console.WriteLine(“Age: {0}, Gender: {1}, Avg: {2}”, entry.Age, entry.Gender, entry.Avg);

}

Perhaps it might have simpler if you could simply have stated : “group p by p.Age, p.Gender” but unfortunately this is not supported. Then again this allows you to be more creative in defining the anonymous type so you can manipulate the data even more. Perhaps in the next version of Linq… if there is ever one…

 

Loading custom resources

The idea to use ‘custom’ resources in a .Net app might not make sense for all – and there may be times when it does not make sense at all since .Net apps (using VS.Net) have a built-in editor to manage embedded resources for an app. But… {here it comes} there could be some more flexibility to do it yourself like the ‘resource files’ does not have to be all located in the same directory (from a source point of view) and you can choose whether you want to include the files separately from the main executable when distributing the app.

First off, to you have to add a file (the resource) to the project – either by using the ‘Add new Item’  or ‘Add Existing Item’ context menus. Then under ‘Properties’ of the file ‘Build Action’ to ‘Embedded Resource’. Optionally you can set the ‘Copy to Output Directory’ but for this blog entry it won’t be used. Take note of the relative directory name (to the project’s root) since that will become part of the name of the resource – including the exact ‘case’ of the letters. For example, adding a text file named ‘CreateTables.sql‘ under a project directory ‘SQL‘ would result in a resource name ‘<Default namespace>.SQL.CreateTables.sql‘. Yes that is correct, the default namespace of the project is prepended to the full resource name.

Now to use the resource file (actually only the content since the file name has no use inside the project) you can use the following code:

public static string GetResourceByName(string name)
{

Stream s = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(name);
System.IO.StreamReader sr = new StreamReader(s);

return sr.ReadToEnd();

}

string sql = GetResourceByName(‘myNamespace.SQL.CreateTables.sql‘);

One small note: this example code does no error checking.

You can make the resource name a constant inside the project or create an enum using something like a string value attribute to match the enum entries to a string or something. Also, this example assumes the content is a text file but you can use the same principle of any type of content (like images, audio, video or whatever).

Revisited – XML File as database

I’ve again relooked at the idea of using a plain XML file as a source of a ‘small’ database. The previous attempt resulted in me going down the path of using datasets (typed and non-typed).

This time I started with a set of very simple classes (.Net/C# classes) that when you serialize them to XML it looks very much like a small data store/structure I also happened to use for another import/export genealogical database app I created.

Effectively through the use of ‘Generics’ I am able to create a simple ‘base’ class with which any such small in-memory database can be created/used/persisted to and from disk again. At the ‘lowest’ level I have a class that only does 3 things: Create the data store, load from disk/file and then save to disk/file. It makes use of a small utility class that handles serialization to (xml) files.

public interface ISmallDataStore
{

void CreateNewDataStore();
void LoadDataStore(string source);
void SaveDataStore(string destination);

}

public abstract class SDSXMLFileBase<T> : ISmallDataStore where T: class
{

private string sourceFilePath;
internal T DataContainer;

#region ISDS Members
abstract public void CreateNewDataStore();
abstract internal void SetRelationObjects();
abstract internal void RefreshCacheObjects();

public void LoadDataStore(string source)
{

sourceFilePath = source;
DataContainer = SerializationUtils.DeserializeXMLFile<T>(source);
SetRelationObjects();
RefreshCacheObjects();

}
public void SaveDataStore(string destination)
{

sourceFilePath = destination;
SerializationUtils.SerializeXMLToFile<T>(destination, DataContainer);

}
#endregion

}

Two abstract methods are added to facilitate functionality that will be explained later (SetRelationObjects and RefreshCacheObjects). They are optional and but I needed them for specific reasons.

The next ‘layer’ is a class that implements ‘DataContainer’ with data structures you want to use as the data store. These data structures are what is going to be saved/serialized. The following is small example of what it looks:

public class SampleSDSImplementation : SDSXMLFileBase<SampleTDataContainer>
{

public override void CreateNewDataStore()
{

DataContainer = new SampleTDataContainer();

}

}

Through the use of serialization attributes you can define the way the resulted xml would look that is stored. In my example the class SampleTDataContainer is effectively the data store and its fields are decorated with the attributes like XmlElement, XmlAttribute etc.

The following is a small excerpt from a sample class:

[Serializable(), XmlType(“data”)]
public class SampleTDataContainer
{

[XmlElement(“p”)]
public List<Person> Persons = new List<Person>();
[XmlElement(“m”)]
public List<Marriage> Marriages = new List<Marriage>();

}

[Serializable(), XmlType(“p”)]
public class Person
{

[XmlAttribute(“id”)]
public int Id { get; set; }
[XmlAttribute(“fn”)]
public string FirstName { get; set; }
[XmlAttribute(“sn”)]
public string Surname { get; set; }

}

A basic output of the (xml) file will look something like this:

<?xml version=”1.0″ encoding=”utf-16″?>
<data>

<p id=”1″ fn=”Anakin” sn=”Skywalker” … />
<p id=”2″ fn=”Padmé” sn=”Amidala” … />

<m id=”1″ mno=”1″ hid=”1″ wid=”2″ … />

</data>

Now that is all good and well for very basic stuff but what about a few more advanced requirements, like auto generating the ‘id’s, having ‘references’ between the objects (the Marriage class will have two references to Person (husband and wife), Person will have two (father and mother) and even reverse referencing (Person having a list of Marriage objects..).

Setting up those references in code is easy but once it has been serialized and then deserialized you get all kind of funnies. For example, An instance of a Person class might have a reference to a marriage and that Marriage instance has a reference to the same Person instance (the first time when you set it up in the code). Next time when the data is loaded from file (deserialized) the Marriage instance reference will not pont to the same instance as the Person instance (and vice versa). Ok this is a generic explanation of the issue but hopefully you get the drift…  Well, this is where one of those 2 methods I mentioned in the original base class comes in – SetRelationObjects. To ensure all referencing objects (at run-time) are actually referencing the correct objects you can do something like this:

internal override void SetRelationObjects()
{

foreach (Marriage m in DataContainer.Marriages)
{

if (m.HusbandId > 0 && m.Husband == null)

m.Husband = DataContainer.Persons.FirstOrDefault(h => h.Id == m.HusbandId);

if (m.WifeId > 0 && m.Wife == null)

m.Wife = DataContainer.Persons.FirstOrDefault(w => w.Id == m.WifeId);

}
foreach (Person p in DataContainer.Persons)
{

if (p.FatherId > 0 && p.Father == null)

p.Father = DataContainer.Persons.FirstOrDefault(f => f.Id == p.FatherId);

if (p.MotherId > 0 && p.Mother == null)

p.Mother = DataContainer.Persons.FirstOrDefault(f => f.Id == p.MotherId);

//Reassign union objects since deserialization created new/separated instances.
for (int i = 0; i < p.Marriages.Count; i++)
{

Marriage m = p.Marriages[i];
p.Marriages[i] = DataContainer.Marriages.FirstOrDefault(u => u.Id == m.Id);

}

}

}

The fields for things like (Person) Father and (Person) Mother was not shown in the class listing but you can probably guess what they should look like. These fields are ‘NOT’ serialized per se but rather handled by adding a (int) FatherId and (int) MotherId set of fields that ‘ARE’ serialized. It both makes it easier to read and smaller to store in the xml file. When deserializing only the ‘id’ fields are restored letting the SetRelationObjects method correct the referencing just after load. There may be other ways to do these kind of things but I choose this one as it suits me at the moment.

When designing classes for serialization it helps to know a couple of things about Xml serialization attributes and hidden methods. Lets say you want to have a public field in your class (like the Father/Mother ones) that you do not want exposed by serialization you can use a public bool ShouldSerialize<FieldName>() method inside the class. e.g.

public bool ShouldSerializeFatherId()
{

return FatherId > 0;

}
public bool ShouldSerializeMotherId()
{

return MotherId > 0;

}

[XmlAttribute(“fid”)]
public int FatherId { get; set; }

[XmlAttribute(“mid”)]
public int MotherId { get; set; }

private Person father = null;
[XmlIgnore]
public Person Father
{

get { return father; }
set
{

if (value != null)
{

father = value;
FatherId = father.Id;

}
else

FatherId = 0;

}

}
private Person mother = null;
[XmlIgnore]
public Person Mother
{

get { return mother; }
set
{

if (value != null)
{

mother = value;
MotherId = mother.Id;

}
else

MotherId = 0;

}

}

Helper methods for interacting with the data

It is possible that you can use the data container as is and directly call methods on the Person objects but that means you could be duplicating a lot of code or functionality each time you use it. To help with this I added a few simple helper methods in the class that implements the base class (SampleSDSImplementation). For example:

public Person AddPerson(string firstName, string surname)
{

int nextPersonId = 1;
if (DataContainer.Persons.Count > 0)

nextPersonId = (from p in DataContainer.Persons select p.Id).Max() + 1;

Person newPerson = new Person() { FirstName = firstName, Surname = surname };
newPerson.Id = nextPersonId;
DataContainer.Persons.Add(newPerson);
return newPerson;

}

public Person FindSinglePersonById(int id)
{

return DataContainer.Persons.FirstOrDefault(p => p.Id == id);

}

As an example of how to use it look at the following:

string dataStoreLocation = System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.Desktop), “TestSDS.xml”);
SampleSDSImplementation sdsSample = new SampleSDSImplementation();
sdsSample.CreateNewDataStore();

Person vader = sdsSample.AddPerson(“Anakin”, “Skywalker”);
vader.IsMale = true;
vader.History = “The baddy of the story”;
vader.NickName = “Darth Vader”;
vader.PlaceOfBirth = “Tatooine”;
vader.PlaceOfDeath = “Death star 2”;

Person padme = sdsSample.AddPerson(“Padmé”, “Amidala”);
padme.DateOfDeath.Year = 2005;
padme.PlaceOfDeath = “Polis Massa”;
sdsSample.AddMarriage(vader, padme, 1, null, “Naboo”, null, “Mustafar”);

Person luke = sdsSample.AddPerson(“Luke”, “Skywalker”);
luke.IsMale = true;
luke.ChildNo = 1;
luke.NickName = “Master Luke”;
luke.PlaceOfBirth = “Polis Massa”;
luke.Father = vader;
luke.Mother = padme;

sdsSample.SaveDataStore(dataStoreLocation);

Conclusion

This is a simple way to build a little database (don’t fool yourself that you can easily build huge databases with this hehe) with which you can run a simple system that requires small database that can fit into memory.

See example project here: SDSTest