 |
|
 |
i made some updates for VS2005 exe.config file
private void ConfigEditor_Load(object sender, System.EventArgs e)
{
}
public CustomClass LoadConfiguration(string configurationFile)
{
CustomClass customClass = new CustomClass();
try
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(configurationFile);
XmlNodeList applicationSettingSections = xmlDoc.SelectNodes("configuration/configSections/sectionGroup/section");
for (int j = 0; j < applicationSettingSections.Count; j++)
{
string sectionName = applicationSettingSections[j].Attributes["name"].Value;
XmlNodeList settingsList = xmlDoc.SelectNodes("configuration/applicationSettings/" + sectionName + "/setting");
if (settingsList.Count != 0 && settingsList != null)
{
for (int i = 0; i < settingsList.Count; i++)
{
XmlNode settingNode = settingsList[i];
XmlAttribute atrribName = settingNode.Attributes["name"];
XmlAttribute attribType = settingNode.Attributes["serializeAs"];
XmlAttribute attribDescription = settingNode.Attributes["description"];
if (atrribName != null && attribType != null)
{
if (attribDescription == null)
{
attribDescription = atrribName;
}
string value = settingNode.FirstChild.InnerText;
string typeString = GetTypeString(attribType.Value);
Type propType = Type.GetType(typeString);
customClass.AddProperty(atrribName.Value, value, attribDescription.Value, sectionName, propType, false, false);
}
}
}
}
xmlDoc = null;
}
catch (Exception ex)
{
throw ex;
}
return customClass;
}
private string GetTypeString(string typeName)
{
if (typeName.StartsWith("System."))
{
switch (typeName) {
default:
break;
}
}
else
{
typeName = "System." + typeName;
}
return typeName;
}
public void SaveConfiguration(string configurationFile, CustomClass customClass)
{
try
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(configurationFile);
xmlDoc.Save(configurationFile + "_bak");
PropertyDescriptorCollection props = customClass.GetProperties();
RepopulateXmlSection(xmlDoc, props);
xmlDoc.Save(configurationFile);
}
catch (Exception ex)
{
throw ex;
}
}
private void RepopulateXmlSection(XmlDocument xmlDoc, PropertyDescriptorCollection props)
{
List<string> list = new List<string>();
for (int i = 0; i < props.Count; i++)
{
if (!list.Contains(props[i].Category))
list.Add(props[i].Category);
}
for (int j = 0; j < list.Count; j++)
{
string sectionName = list[j];
XmlNodeList nodes = xmlDoc.SelectNodes("configuration/applicationSettings/" + sectionName + "/setting");
for (int i = 0; i < nodes.Count; i++)
{
XmlNode node = nodes[i];
CustomClass.DynamicProperty property = (CustomClass.DynamicProperty)props[node.Attributes["name"].Value];
if (property != null)
{
node.FirstChild.InnerText = property.GetValue(null).ToString();
if (property.Description != property.Name)
{
if (node.Attributes["description"] != null)
{
node.Attributes["description"].Value = property.Description;
}
}
}
}
}
}
|
|
|
|
 |
|
 |
Is there some new version out there? Alternatives?
|
|
|
|
 |
|
 |
any updates for .net 4.0 ?? any versions ?
AE
|
|
|
|
 |
|
 |
Just found waht i was looking to build.
Thanks man. Great Stuff.
void izmoto(char* szKwazi);
|
|
|
|
 |
|
 |
First off, nice job. I quickly realized that no thought was given to child nodes within the app.config since the contents of were not put into the grid. Is there a particular reason why this was not done or were you simply providing a quick example of how your app could be used and extended?
|
|
|
|
 |
|
 |
If only the editor can handle child nodes, especially when saving, coz the flat properties are "disconnected" from the XML tree nodes.
The Pragmatic Programmer
|
|
|
|
 |
|
 |
I had looked at several of the similar apps/examples (XML Grid, etc.). This was not only the best, it was exactly what I needed to work with!
Thanks!
"Never leave your Wingman!"
|
|
|
|
 |
|
 |
how to mask element ??
exemple key = password , value = xxxxxx
|
|
|
|
 |
|
 |
Apologies, but I'm missing something here...
Followed the instructions to include the dll in my project etc..
Added the code.
But when I click on my button.. the event handler works fine. But the editor cannot find the config file.
Then I copied the DotBits.Configuration.exe.config file into my bin\debug directory ... and it can find and open that one just fine .. how do I tell the editor which file to open?
My config file is TestApp.exe.config...
This is something obvious isn't it? Sorry
vida
-- modified at 10:11 Monday 23rd January, 2006
|
|
|
|
 |
|
 |
Does the class support string arrays? If so, how would I do this?
|
|
|
|
 |
|
 |
This is a very cool editor, however, I have a question. After I added a "description" tag to my xxx.config file, the editor can open and read/update the .config file, but when I try and read a section in using the COnfiguration.GetConfig("mysection") syntax, it throws an exception on the extra attribute field - how does one correct this?
|
|
|
|
 |
|
 |
Is there anyway to set which UITypeEditor will be used for a property? It would be nice to be able to specify the attribute for a property that indicates it should use the FileNameEditor for example.
|
|
|
|
 |
|
 |
I have the same question but at a more generialized level. I need to build data driven property browsers (eventually from an XML Schema) so I have borrowed Anthony's CustomClass and am using it to build the class at runtime. I want to go one step further and be able to define the editor for a property to be a dialog box of my own design. I assume that I will need to define my own type and make the GetEditor method to return my editor. Being new to C# I'm lost in the ICustomTypeDescriptor and ExpandableObjectConverter stuff.
If I ever figure it all out I'll let you know.
Thom Lemon
|
|
|
|
 |
|
 |
Hi Thom
Not sure if these will help - but thee are the links I used at the time. I confess having got what I needed out of it I didn't go as far as defining a custom type or editor.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/vsnetpropbrow.asp
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/usingpropgrid.asp
Hope this helps.
Best regards,
Tony
|
|
|
|
 |
|
 |
Thanks for a great tutorial.
In order to provide a custom editor, what I did:
1) Modify class DynamicProperty
1.1 Add a class variable System.Drawing.Design.UITypeEditor editor;
1.2 Overwrite GetEditor
public override object GetEditor(Type editorBaseType)
{
// make sure we're looking for a UITypeEditor.
//
if (editorBaseType == typeof(System.Drawing.Design.UITypeEditor))
{
// create and return one of our editors.
// Check propType
// Please change ConfigSettings.PathEditor to suit your namespace
if (propType == typeof(ConfigSettings.PathEditor))
{
if (editor == null)
{
editor = new PathEditor();
}
return editor;
}
}
return base.GetEditor(editorBaseType);
}
1.3 Add type into the .config file, like this
1.4 Make a new class
using System;
using System.Windows.Forms;
using System.Drawing.Design;
using System.ComponentModel;
using System.IO;
namespace ConfigSettings
{
#region PathEditor
///
/// Summary description for PathEditor.
///
public class PathEditor: UITypeEditor
{
///
/// Show the dialog.
///
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
FolderBrowserDialog dialog = new FolderBrowserDialog();
if (value != null && value.ToString().Length > 0)
{
try
{
string path = Path.GetFullPath(value.ToString());
if (!Directory.Exists(path))
throw new InvalidOperationException();
dialog.SelectedPath = path;
}
catch (Exception err)
{
MessageBox.Show(string.Format("'{0}' is not a valid directory: {1}", value, err.Message), "Not a directory" );
}
}
if (dialog.ShowDialog() == DialogResult.OK)
value = dialog.SelectedPath;
return value;
}
/// Return the editor style.
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.Modal;
}
}
#endregion PathEditor
}
Hope this help.
An Dang
|
|
|
|
 |
|
 |
What class does GetEditor belong to in this context? I tried this example but get a build error because the compiler says "no suitable method found to override" on "GetEditor". Maybe I'm missing a using statement?
|
|
|
|
 |
|
 |
I tried to use the tool with real life config file that uses nested configSections and all I managed to see is just appSettings.
I simplified the file as in the example below and it looks like the same problem exists.
One level key/value settings update work just fine. Any ideas regarding "configSections"?
Config example:
<?xml version="1.0" encoding="Windows-1252"?><configuration> <configSections> <section name="DataPump" type="System.Configuration.NameValueSectionHandler, system, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=blahblah, Custom=null" /> </configSections> <appSettings> <add key="ApplicationName" value="DataPump" /> <add key="testparam" value="test value 2" /> </appSettings> <DataPump> <add key="DataPump key" value="DataPump value" /> </DataPump></configuration>
With deep respect,
JackDotNet.
|
|
|
|
 |
|
 |
Hi
Thanks for the feedback.
If you want to read the DataPump section you'll need to change the parameters in the LoadConfiguration() method.
You'll see that it looks for three sections only - appSettings, and our own 'house standard' sections - CommonConfiguration, and ApplicationConfiguration.
Hardcoding our names was a shortcut and suited our applications here.
Ideally I should check for each section found in the configuration node - ignoring configSections, system.web etc or any section that doesn't present add, key, value attribute nodes. Will try to do this in an update.
If DataPump is a typical key value section then it should work fine if you change the line below.
Change the line:
if (sectionList[y].Name == "appSettings" || sectionList[y].Name == "ApplicationConfiguration" || sectionList[y].Name == "CommonConfiguration")
to include "DataPump" (you can remove our two) and from what I've seen above this should be OK.
If you were creating a nested set of keys below DataPump then that would be a different problem and one that would required extending the application to support expandable sub sections on the property grid. A bit more work than we could justify for our needs at the moment but something that could be done.
Hope this helps.
Best regards,
Tony
|
|
|
|
 |
|
 |
Have just sent an updated project zip to CodeProject (not sure when they will post it) - fixes the strong name key location problem, and also looks for any section with add, key, value elements - so your DataPump section should load out of the box.
Also fixes a minor Xml issue - comments should really be within the section and not outside of it.
Regards,
Tony
|
|
|
|
 |
|
 |
Actually, it's not a big deal to make it flexible, i.e. not restricted by any section assumptions. With slight modification LoadConfiguration function may do this: XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(configurationFile); XmlNodeList nodeList = xmlDoc.SelectNodes("//section/@name"); //this will choose all the sections, regardless of fact if it's nested or not foreach (XmlNode section in nodeList) { XmlNodeList settingsList = xmlDoc.SelectNodes("//" + section.InnerText + "/add"); // this will grab the settings in the chosen in "foreach" section // getting attributes for(int i = 0; i < settingsList.Count; i++) { XmlAttribute atrribKey = settingsList[i].Attributes["key"]; XmlAttribute attribValue = settingsList[i].Attributes["value"]; XmlAttribute attribDescription = settingsList[i].Attributes["description"]; // etc., just as in your code till customClass.AddProperty(... } } I run it with pretty complicated config - 2 nested groups, 3 sections (see below) - works fine Config file: <?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <sectionGroup name="GroupOne"> <section name="mySectionOne" type="System.Configuration.NameValueSectionHandler,System" /> <sectionGroup name="GroupTwo"> <section name="mySectionTwo" type="System.Configuration.NameValueSectionHandler,System" /> <section name="mySectionTree" type="System.Configuration.NameValueSectionHandler,System" /> </sectionGroup> </sectionGroup> </configSections> <GroupOne> <mySectionOne> <add key="key1" value="value1" /> </mySectionOne> <GroupTwo> <mySectionTwo> <add key="key2" value="value2" /> </mySectionTwo> <mySectionTree> <add key="key3" value="value3" /> </mySectionTree> </GroupTwo> </GroupOne> <appSettings file="relative file name"></appSettings>
</configuration> It doesn't cover the whole thing though, like web.config, where the data isn't in the key/value form, but for all the rest it's just fine Regards, JackDotNet
|
|
|
|
 |
|
 |
Nice article
It seems the demo project is looking for your key file though, removing the value for AssemblyKeyFile in Assembly.cs fixed it.
"Cryptographic failure while signing assembly
-- 'Error reading key file 'D:\Projects\DotBits\Configuration\Configuration.snk' -- The device is not ready."
|
|
|
|
 |
|
 |
Thanks for the feedback.
You can remove the key entry as you've done - or update it to point to the new location, wherever you've unzipped the project. I'll remove it from the next update.
Thanks again,
Tony
|
|
|
|
 |
|
 |
Creating D:\Projects\DotBits\Configuration on my local machine and building project inside worked fine for me.
This application is something I expected to be done by MS, there is obvious need for this functionality.
Thanks a lot to the author !!!!!!!!
|
|
|
|
 |