Preserving Windows Forms resx Comments

One of the problems with auto-generated files is that if you make changes to them then your changes are lost the next time the file is re-generated. This happens with resx files for localized Windows Forms. If you set Form.Localizable to true and then edit the resx file directly then the next time Visual Studio rebuilds the resx file your changes are lost. One reason why you might want to edit the resx file is to add comments to the entries but obviously these comments will be lost. In fairness to Visual Studio a clear and strong warning is given when you attempt to edit a form’s resx file directly so it is difficult to make this mistake accidentally. However, the question remains "what if you wanted to preserve your comments between rebuilds of the resx file ?" This is achievable using the CopyComments method shown below. This method accepts an input resx and an output resx and copies the comments from the input resx to corresponding entries in the output resx. The idea is that prior to allowing Visual Studio to rebuild the resx file you take a copy of it. After Visual Studio has rebuilt the resx file (and the comments have been lost) you run this utility to copy the comments back into the ’main’ resx file.

public static Boolean CopyComments(string inputResX, string outputResX)
{
bool changesMade = false;

// populate a Hashtable containing the DataNodes in the output file
Hashtable output = new Hashtable();
using (ResXResourceReader reader = new ResXResourceReader(outputResX))
{
reader.UseResXDataNodes = true;
IEnumerator enumerator = reader.GetEnumerator();
while (enumerator.MoveNext())
{
DictionaryEntry entry = (DictionaryEntry)enumerator.Current;

ResXDataNode dataNode = (ResXDataNode)entry.Value;
output.Add(dataNode.Name, dataNode);
}
}

// search the Hashtable for equivalent DataNodes in the input file
using (ResXResourceReader reader = new ResXResourceReader(inputResX))
{
reader.UseResXDataNodes = true;
IEnumerator enumerator = reader.GetEnumerator();
while (enumerator.MoveNext())
{
DictionaryEntry entry = (DictionaryEntry)enumerator.Current;

ResXDataNode inputDataNode = (ResXDataNode)entry.Value;

if (output.ContainsKey(inputDataNode.Name))
{
ResXDataNode outputDataNode = (ResXDataNode)output[inputDataNode.Name];
if (!String.IsNullOrEmpty(inputDataNode.Comment) &&
outputDataNode.Comment != inputDataNode.Comment)
{
// update the output resx’s comments with the input resx’s comments
outputDataNode.Comment = inputDataNode.Comment;
changesMade = true;
}
}
}
}
if (changesMade)
{
// write the changes back to the output file
using (ResXResourceWriter writer = new ResXResourceWriter(outputResX))
{
foreach (DictionaryEntry entry in output)
{
writer.AddResource(entry.Key.ToString(), entry.Value);
}
writer.Generate();
writer.Close();
}
}

return changesMade;
}
}

Technorati Tags: Internationalization, Windows Forms,

Posted by: Guy Smith-Ferrier
Posted on: Monday, August 06, 2007 at 9:05 PM
Categories: Internationalization
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

Related posts

Comments