|
|
Hello all,
I'm new to C# and am looking for some guidance with serialization of dialog data. I have created a simple app that produces a data product based on the settings entered by the user on a single form. For now I have created a simple serializable class containing member vars that correspond to the various controls on the form. Just prior to calling Serialize( ) I manually set the member vars in the class to the corresponding values of the controls on the form. Like-wise, I manually set the values of the controls to the member vars of the class after calling Deserialize( ). There has to be a better way…
I guess another fundamental issue for me is that I’m not used to dealing directly with the control – I’m more used to having a separate member variable that automatically gets stuffed with the value of the control (like MFCs DoDataExchange( )). Is there a slick way of doing this without writing a bunch of code (for example without adding code to the Validated event of every control on the dialog)?
Thanks for your help,
Newbie_T
|
|
|
|
|
A better way would be to data-bind your controls to a DataTable , which is part of a DataSet which serializes nicely into an XML document (also see the XmlDataDocument for faster access to the XML document itself, but which can return you a DataSet if you need it later, like for data-binding purposes).
Start by reading Data Binding and Windows Forms[^] in the Visual Studio product documentation.
You can add a new DataSet schema to your project just like you'd add a new class. It's an XML Schema that is used to generate a strongly typed DataSet , where all of the tables, columns, relationships, and keys are defined when you instantiate it (otherwise you have to do this programmatically, and binding because a manual operation because the designer can't infer what can be bound). Use the "Data" section of the toolbox to add a DataSet, and select your DataSet -derived class when prompted.
Now go to each control and find the "Bindings" category. You can use the "Advanced" ... button to bind. While it's generally a better practice to bind to a DataSet and set the DataMember property of a control to the name of the table (like for a DataGrid , to better facilitate data navigation and multiple table views), not every control implements a DataMember property. When data-binding controls all controls should use the same binding context (which means the exact same combination of the data object and the data member, and they need not be a DataSet or DataTable , but any IList or IListSource implementation).
When your form loads (so override OnLoad and don't forget to call base.OnLoad after deserializing your data) you use your DataSet field and call DataSet.ReadXml , for example. When closing (so override OnClosing , and again don't forget to call base.OnClosing when appropriate - almost always call the base implementation when overriding) use DataSet.WriteXml .
To make sure you write to the right file, use an absolute path since the current working directory for your application could be different depending on how the application was launched. For the best user experience, write to a directory they would have write access to, and that wouldn't set preferences for all users, unless that's what you wanted.
For example:
string path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
path = Path.Combine(path, "My App");
Directory.CreateDirectory(path);
path = Path.Combine(path, "settings.xml"); If you wanted to save the settings relative to the application, be sure to use the application's startup path (the directory that contains the EXE):
string path = Application.StartupPath;
path = Path.Combine(path, "settings.xml"); This really is similar to what you would do for MFC, only that your binding to an object rather than having to implement the data transfer to some object yourself. And instead of archiving that object (using a CArchive or some custom solution), you're serializing it. The DataSet provides methods to serialize and deserialize more easily than for more serializable objects, too.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
Now I like to use C# program to modify tnsnames.ora content using
the related methods provided by system lib.
For example, after a client accepts the related values , such as
"zgafc", "109.52.8.8", "1521" and "db.source", then the client can modify (or insert) the file "tnsnames.ora", as following :
ZGAFC =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 109.52.8.8)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = db.source)
)
)
then the client can access the db by "zgafc" in client program.
that's to say, if the client just install the oracle client, and do not
config the source in client, however, it can access the appointed database
after the client accept the values related to connection.
If we can find the methods, we can create the database source in client by program, rather than config the datasource in client by manual.
|
|
|
|
|
Hello,
When the user of my app selects some rows from an open excel file and
drag-n-drops them onto my form, I need to be able to parse those rows and
fill arrays that would match the original selected Excel rows.
Is there any way the I can populate an array with data from CSV's that are just droppped
onto the form?
I tried parsing each line myself, using some regular expressions I found
online, but they would fail if a cell in the Excel row contained quotes or
commas.
What I have right now is a streamreader which reads the dropped info. As long as there are more lines, I read the line, split it using comma as the delimeter, and fill an array. This works great if there are no commas or quotes within the excel cells. If there are, I cant just split the string on commas because I cant tell the difference between "real" commas and the delimeters.
I see that when you drag-n-drop Excel rows onto say Wordpad, it gets it right (regardless of what is in the Excel row). I would like to be able to do the same (just fill arrays instead of displaying the data).
Any help is GREATLY appreciated!
Thanks
-Flack
|
|
|
|
|
You need to parse the CSV data correctly. That means anytime you encounter a quote you don't slip on commas (or tabs, whatever the delimiter may be) until you reach another quote. It's a pretty basic state machine. While you could use regular expressions, it would be much easier to just read-in the entire line and parse the string character by character keeping track of what characters you've read (using the rules I mentioned above) and splitting at the right time.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
I tried using that logic but it didn't work. Let me give you an example of one of the lines that is messing me up.
The row contains these values from A1 to H1. Each line is a cell:
<br />
A1: "TE,ST"<br />
B1: ""<br />
C1: "<br />
D1: ,<br />
E1: ,<br />
F1: ,<br />
G1: "<br />
H1: "<br />
I drag that row onto my form and drop it. Now, when I set up and read from the stream I get this string to represent that row:
"""TE,ST""","",",",",",",",",","
If I hit a quote and keep reading until I hit another quote, I would get "" as the first element (when its really "TE,ST"). Also, single quotes (such as C1) are displayed as a single quote, and commas (D1 - F1) are displayed as ",". I cant just use quotes. How would I know if "," represents a "real" comma or its a quote char and the comma is the delimeter?
Should I not be using a stream to read in the data?
If you get a chance, write a small app to see what I mean. Drag the row I described. It'll probably be more clear than my explanation.
Any other ideas?
Thanks for the help,
-Flack
|
|
|
|
|
You can pick different clipboard formats (which are used both for copy and paste, and drag and drop functionality). Use ClipSpy[^] to see what other formats are available (they are string names) and see what data each contains. There may be an easier format for you to parse.
Applications will typically store many different formats for data each associated with a different clipboard format. You can pick whichever you like, and it's common to have a few fallbacks if an application doesn't pack a certain format into the IDataObject (which is actually a different implementation for both native and managed code, but represents the same thing).
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
Thanks for the help. I decided to try to get the values I need from the dropped Excel as XML.
However, when I try to iterate through the XML and extract the values I need, I'm not getting anything.
Here is a sample XML that I got form Excel:
<?xml version="1.0" ?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns ="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40">
<Styles>
<Style ss:ID="Default" ss:Name="Normal">
<Alignment ss:Vertical="Bottom" />
<Borders />
<Font />
<Interior />
<NumberFormat />
<Protection />
</Style>
</Styles>
<Worksheet ss:Name="Sheet1">
<Table ss:ExpandedColumnCount="4" ss:ExpandedRowCount="1">
<Row>
<Cell>
<Data ss:Type="String">"TE,ST"</Data>
</Cell>
<Cell>
<Data ss:Type="String">""</Data>
</Cell>
<Cell>
<Data ss:Type="String">"""</Data>
</Cell>
<Cell>
<Data ss:Type="String">",,"</Data>
</Cell>
</Row>
</Table>
</Worksheet>
</Workbook>
Here is the code I tried to use to read it. (This is in my DragDrop event):
if (e.Data.GetDataPresent("Xml Spreadsheet") == true)
{
System.IO.Stream stream = e.Data.GetData("Xml Spreadsheet") as System.IO.Stream;
XmlTextReader message = new XmlTextReader(stream);
XPathDocument doc = new XPathDocument(message);
XPathNavigator navigator = doc.CreateNavigator();
XPathNodeIterator it = navigator.Select("Worksheet/Table/Row/Cell/Data");
while(it.MoveNext())
{
textBox1.Text += it.Current.Value;
}
}
This code doesnt work. The iterator returns a count of zero. Can you tell me what I am doing wrong? Is the xml doc not created correctly or is my expression used in the Select call incorrect?
Thanks for all of your help so far.
-Flack
|
|
|
|
|
And you won't get anything that way. The XML fragment includes a namespace which you must reference or else your XPath statement won't resolve the XML elements. Those XML elements (and attributes, for that matter, though most attributes are not namespace-qualifed) are defined by a namespace.
Unfortunately in the code you're using you cannot add an XmlNamespaceManager anywhere (oddly enough), so you might try setting XmlTextReader.Namespaces to false . This disables namespace support, but what that means from a programming standpoint I'm not really sure. I've never used this technique, before.
Normally, when you'd use something like XmlDocument.SelectNodes you'd first instantiate an XmlNamespaceManager from the XmlDocument.NameTable , add namespaces (with whatever prefixes you want; the prefixes themselves don't have to be the same as what's in the XML document), then select using an XPath expression utilizing the prefixes that match up with the same namespaces that qualifies any elements and attributes as necessary.
A word of caution, too: Excel - beginning with XP, IIRC - only started using XML as a clipboard format. Older Excel versions do not so if you intend supporting older versions of Excel either by interop'ing with an older typelib or not using new functionality from the newer typelib (since COM, when implemented correctly - and Office is a shining example of those rules, does not change published interfaces and typically remains backward compatible) you should not use the XML clipboard format.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
Hello
i am unable to call Uninstall method during Uninstallation..
what all I did that i made 2 seperate projects for both Install and Uninstall and add respective DLLs in INSTALL and UNINSTALL custom Actions,this is the code which i use for Uninstall and this is saved as seperate .dll file which then used in Custom Actions->Uninstall section
public override void Uninstall(System.Collections.IDictionary savedState)
{
//Remove XML FIle
MessageBox.Show("i am in Uninstall","Config File");
if(File.Exists("c:\\_config.xml"))
{
File.SetAttributes("c:\\_config.xml",FileAttributes.Normal);
File.Delete("c:\\_config.xml");
MessageBox.Show("File is Deleted","Config File");
}
base.Uninstall(savedState);
RegistrationServices regsrv=new RegistrationServices();
if (!regsrv.UnregisterAssembly(this.GetType().Assembly))
{
throw new InstallException("Failed To Unregister for COM");
}
}
UNinstaller is not calling this method at all,kindly guide me,right now i am not sure that whether i need 2 seprate Dlls for 2 different custom actions(Install and Uninstall) or by putting both overridden methods in a single dll and then call them in "Install" and "Uninstall" Sections of Custom Actions?
|
|
|
|
|
You should keep your installer all in the same assembly. Not only is this a better design that uses less space and is more easily maintained, but it's also necessary because into that savedState dictionary is data that is serialized (using the SOAP formatter) with Type information, which means that the fully-qualified type name (namespace + class), the assembly it's in, and the assembly information like the version and public key token, are all serialized. Since you defined your installer in a separate assembly, that Type information would not match. When the dictionary is deserialized the formatter would throw an exception.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
Heath
Thanks for reply..
let me clarify you that Install method has been working fine,as i mentioned in my previous post that i made an assembly dll and associated it with Install Custom action,i now put Uninstall method in same project/assembly where Install method is,for testing i ran InstallUtil utility on my dll and it successfully called both Install and Uninstall method,like
i called Installutil Registry.dll and Installutil /u Registry.dll and they are bringing up respective method properly..
Heath,can you be a bit more elaborative?specially,which CustomAction should I use to call Uinstall method?
Thanks
-A
|
|
|
|
|
Actually, I believe you should elaborate. The way your first post reads seems to say that you had two projects for one installer assembly. And mentioning "CustomAction", I assume you're trying to get an assembly to run from within a Windows Installer project? You didn't mention Windows Installer before. Please be specific in your details of the problem; otherwise, it's difficult to help you.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
I am sorry if there was some confusion..let me try to elaborate step by step
1)I added a class library project in my Solution(.sln) and wrote both Overriden versions of Uninstall and Install and built them in form of dll(e.g:mySetup.dll) assembly
2)in the Setup Project,which is also in same solution,i added my mySetup.dll in FileSystem-><i>Application Folder
3)After that i associated that mySetup.dll in Custom Actions(Install and Uninstall) and built the Setup project.
the setup is calling Overriden Install method but not Uninstall method
as you mentioned I assume you're trying to get an assembly to run from within a Windows Installer project?
i think "Yes" because the assembly is called when the Setup.msi file is executed.
Hope i explained a bit better,sorry for my ignorance
-A
|
|
|
|
|
Make sure that for everywhere you use the assembly with the Installer class derivative you have the property "InstallerClass" set to "True". This property can be found in the PropertyGrid when you have your custom action selected.
How are you determining that when you uninstall the MSI package that your Uninstall method isn't executing? Custom actions are difficult to debug (it's one of the things I do at Microsoft), and do keep in mind that the install state files are often left behind.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
Heath Stewart wrote:
Make sure that for everywhere you use the assembly with the Installer class derivative you have the property "InstallerClass" set to "True". This property can be found in the PropertyGrid when you have your custom action selected.
this class` InstallerClass property is true thatswhy it prompts a MessageBox which i had added for testing
Heath Stewart wrote:
How are you determining that when you uninstall the MSI package that your Uninstall method isn't executing?
i added a messageBox ,like i did in Install class but unlike Install method,its not coming up..
Heath Stewart wrote:
Custom actions are difficult to debug (it's one of the things I do at Microsoft), and do keep in mind that the install state files are often left behind.
yes here you seem right because when i remove prorgram,it doesn`t remove program folder,my Installer assembly(mySetup.dll as i mentioned in last post) and ALL assemblies which are used to run my application
though i set Permenant propety of all classes to True but still it never wipes out everything at all..
i had been going thru some usenet disucssions thread and the guys were talking
about using Orca utility to read MSI file or using MsiExec but i coudn`t understand them..
-adnan
|
|
|
|
|
Ok,i tried the setup on Enduser PC and there it called the Uninstall method,
as Heath said,it could because dlls installed on my machines were due to Gacutil and Regasm rather than by using Setup itself ..
but i am not sure about this because the guy who tested my application said that he stil finds assemblies in GAC which are supposed to be removed upon Uninstallation
hOwever,it throws an exception as well..
got an exception occured while unistalling, this exception will be ignored and the unistall will continue. However the application might not be fully unistalled after the uninstall is complete --> object refereance not set to an instance of an object
my code is given below:
public override void Uninstall(System.Collections.IDictionary savedState)
{
MessageBox.Show("File is Deleted during Uninstall","Uninstall Phase");
//Remove XML FIle
if(File.Exists("c:\\_config.xml"))
{
File.SetAttributes("c:\\_config.xml",FileAttributes.Normal);
File.Delete("c:\\_config.xml");
MessageBox.Show("Existed File is Deleted","Config File Uninstallation");
}
base.Uninstall(savedState);
RegistrationServices regsrv=new RegistrationServices();
if (!regsrv.UnregisterAssembly(this.GetType().Assembly))
{
throw new InstallException("Failed To Unregister for COM");
}
}
please keep in mind tht code is throwing Un-handled Exception which i mentioned above..
and I dont know how to debug all this:
Thanks
-adnan
|
|
|
|
|
As someone who works on patches for the .NET Framework, let me assure you that the GAC support in MSI does not always work. You'd be better off using custom actions to install into and uninstall from the GAC.
Using Orca is something I do practically every day, but unless you're familiar with MSI it wouldn't really help. Making sure your MSI package is authored correctly is the first step. You should not be using regasm.exe or gacutil.exe in your custom actions because the latter isn't even installed with the .NET Framework (but in the SDK), unless you carry them in your payload and that, too, is not recommended. Everything regasm.exe and gacutil.exe do you can do using installer classes, which you appear to be doing, at least, for component registration.
On that note, make sure that you fix your clases and interfaces with a unique GuidAttribute value, and that you do NOT use auto-generated classes interfaces. Define your interfaces explicitly so that changes in method and property order to not screw-up eary- (VTBL) or late-binding (dispatch IDs) clients. Also never change a published interfaces. I've been developing OLE and COM controls for as long as I can remember and .NET/COM interop is my forté.
If you don't fix your GuidAttribute s for classes and interfaces, when you register new assemblies (or unregister the old using the new assemblies) the registry will not be cleaned up.
Read Exposing .NET Components to COM[^] for more details.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
Hello:
I’ve a web form containing a web user control and a place holder, this web user control have 2 buttons, when user push 1st button I’m loading a 2nd web user control into place holder of web form. When user push 2nd button of 1st web user control I destroy 2nd web user control and place into place holder a 3rd web user control.
This last web user control has a button, several text box and a label. When user puh button I need to show soemthing into label, but when user push button, this web user control simply vanish.
If I recreate web user control programatically I have not way to recover data into textbox and into label.
I’ll appreciate some ideas to attain it.
A.L.
|
|
|
|
|
Try the ASP.NET[^] forum. I know that your question has been asked and answered before, so be sure to search the forum first by click "Search comments" directly above the message board.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
hi,
i am planning a project where i need to play videos as textures on simple 3d surfaces!
i know this is possible with direct3d and vmr9! but are these available with c#??
i know direct3d is available via managed directx but is vmr9???
if not, is it possible to use unmanaged direct3d and vmr9 with c#??
i have googled a lot but i couldn't find any answer!
by the way, where can i read about the exact limits of managed directx vs unmanaged in c#??
thx & greets
matthias
|
|
|
|
|
I'm not sure what VMR9 is, but you can learn more about Managed DirectX 9 at http://msdn.microsoft.com/directx[^], as well as download the SDK.
Apparently your search was too restrictive. Always start off with basic terms. There are many DirectX articles involving P/Invoking and writing RCWs (Runtime Callable Wrappers) in C# for use in .NET here on Code Project which is indexed by all the major search engines (and then some).
Just use the text box at the top of every page underneath the logo for a direct approach to searching the site, though. Try starting with, quite simply, "DirectX".
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
VMR9 = Video Mixing Renderer 9 (part of directshow, but can also be used as texture at dx3d)
i have read a lot at msdn...but it didn't help! for example: there is no information about what can and what cant be done using managed vs unmanaged dx!! the only thing i know, is that managed dx is about 2-5% slower than unmanaged....i can live with that! but what about the vmr9...i have read at an article posted 2002 that it was not available in managed dx...but now we have 2005!! is there any updates on that??
i already have the dx9 sdk...but the documentation seems to be focused on c++!
i have to take a decition wheather to use c# for my project or to learn c++ !! sorry, but all i read at msdn seems like marketing bla bla to me!!
|
|
|
|
|
Actually there's quite a bit of information on MSDN about the differences, like the article Introducing the New Managed Direct3D Graphics API in the .NET Framework[^]. The biggest difference between using your own interop assembly and using Managed DirectX 9.0 is that Managed DirectX is written from the ground up to be much more friendly for .NET development. Using a simple interop assembly often means you have to add a lot of extra code - similar to your unmanaged C++ code - to make anything happen. That's the power of encapsulation. The performance loss would be about the same whether you used Managed DirectX vs. a native DirectX interop assembly/assemblies (which you can find several implementations of here on Code Project).
Unfortunately not everything was added to Managed DirectX, like DirectShow. The nice thing is - depending on how you look at it - Managed DirectX 9 can work seemlessly with native DirectX. You can still pass pointers (in the form of IntPtr s) to many methods as alternatives, and some methods and properties will even return you a pointer to native interfaces. With this in mind, you may have to interop VMR9 (which may already be done for you in one of the DirectX wrappers here on Code Project, or may at least give you some ideas for doing it).
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|