|
There is System.Windows.Forms.FolderBrowserDialog in .NET 1.1 and up. For applications targeting .NET 1.0, you'll have to create a look-alike or encapsulate the SHBrowserForFolder API. There are several articles here on the CodeProejct site that discuss the latter option. The component I mentioned first is very easy to use, just like the OpenFileDialog and SaveFileDialog components.
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
I have questions about paging
Because paging may play important role in distributed application
And according to ".NET Data Access Architecture Guide" at MSDN there are three options to
Implement paging
1-Use the Fill method of the SqlDataAdapter to fill a DataSet with a range of results from a query.
2-Use ADO through COM interoperability and use a server-side cursor.
3-Implement data paging manually by using stored procedures
the article discuss this options
Each method have its advantage and disadvantage in performance and scalability and other things
the question is
What option you use in your Distributed Application and Why ?
If you have another method what is this method at what is it's advantage over those methods
thanks in advance
|
|
|
|
|
It greatly depends. Over what medium is it distributed? Does each client share in the processing of specific chunks of data?
If this application is deployed over the Internet using a DataSet is good because it is both serializable (which is good for both XML Web Services and .NET Remoting) and disconnected (better throughput). If each client processes parts of this data, you'll need something to delegate to the clients which rows they should be working on, or fill a DataSet with only the data they should process.
If your clients are on a LAN with the server as opposed to a WAN, the second method might be good because the server cursor will make sure that each client is accessing sequential data in a distributed manner. For an Internet application - as I mentioned above - the rate of data exchange will potentially be high which will result in congestion. You'll also have to take lengths to ensure that any data you in any object you send is serializable to transport via XML Web Services or .NET Remoting. If you use raw sockets, serialization isn't a problem but you might have problems using sockets (for instance, securing them if they need to be secured and bi-di communications can be combersome.
As far as stored procedures go, you'll still need something to track which block of records to delegate to the next client. A Singleton object exposed through .NET Remoting could help and it won't even have to worry about serializing data if you just pull it using a SqlDataReader or something. If this is a WAN- or Internet-deployed application, a SqlDataReader won't work, and even if it did it would create a high rate or smaller chunks of data which could lead to congestion and timing issues.
Depending on your answers to the first two questions, I hope the following paragraphs are of some help to you.
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
Thanks Heath , Guillermo
i agree with you but i have a comment about using Ado server side cursor
as heath mentioned some of its advantage i see that keeping long time open connection
with the database server and the number of the round trips between the client and server
may be unaccepted and may be this solution violate the philosophy of ado.net
what i want to say make this last solution.
what is your opinions ?
TO Heath :
i posted another quetsion about paging decision at sql,ado.net forum may you take a look?
|
|
|
|
|
I completely agree with Heath. All depends on how you are planning to deploy your application.
I'm just finishing a distributed application, and the enviroment I'm using is a LAN, so the customer wanted online notifications of data update.
What I did was build a service that listen to all modifications done by the clients, and fire events when the update is complete, so all the clients listen to those events and react depending on the data they are showing at the moment.
I used disconected data (DataSet and DataTable).
A simple Client / Server architecture, but it works perfect and fast in a LAN enviroment.
Free your mind...
|
|
|
|
|
I have constructed a COM object in VB6 that exposes various methods to handle custom files. This object works very well when I use it from a normal VB6 project, but when I use it through COM Interop in a C# application a strange error appear:
Inside one of the functions in the COM dll I use the FileExists method on a FileSystemObject. When this method is called from the C# code FileExists returns false, even though the file exists. When the same method is called with the same filename as parameter in VB everything works.
Anyone who have any idea of what I am doing wrong?
Rickard
|
|
|
|
|
You should debug both projects (start debugging the C#/.NET client in VS.NET and then start your VS6 and attach to the process) and see what string is getting passed to the COM object. The behavior shouldn't really change from caller to caller except when parameters differ. A different value might be getting marshaled to your COM object than what you're passing from your C# code.
My initial thought is that there is a Unicode vs. ASCII problem with string encodings. .NET stores Unicode strings internally and your VB6 control might not be expecting that. See the VB6 StrConv function for information pertaining to converting from/to Unicode strings.
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
Good tip! I had actually start to think in those lines!
Thanks!
Rickard
|
|
|
|
|
The COM dll is written in Visual Basic. Could you describe to me how I can attach to this process and debug it using VB6? I can't find any attach to process in my VB6..
Rickard
|
|
|
|
|
I solved it!
Found a good article on this URL
http://support.microsoft.com/?kbid=811658
Rickard
|
|
|
|
|
Hi,
I have now debugged my application and the string seems to be alright, but it
still doesn´t work, or actually it worked for a while, but suddenly
the same error occured again.
Could this be some kind of access problem?
Could it make a difference in I run the com in process or out of process?
Rickard
|
|
|
|
|
No, it would be an access problem if one client could access it via your COM component but another client couldn't, unless they were running with different credentials (something you have to manually do through several steps). This sounds more like a marshaling problem as I mentioned before.
Your COM component can only run as an out-of-process server if it is a stand-alone executable (.exe), so that's not even a valid case.
Since it worked before, you're obviously doing something right. Since it changed, you should figure out what changed. Two compiled applications don't magically change. If this is a marshaling problem, make sure you understand that Windows 9X/ME (Windows) use ASCII while Windows NT/2000/XP(/future versions of Windows) (Windows NT) use Unicode. I can't remember exactly how VB handles strings, but you can code your .NET applications to P/Invoke methods using either ASCII or Unicode depending on the OS type, which it will automatically do for you (see CharSet.Auto ). I don't remember exactly how VB deals with the different OSes. Find out how that works and make sure your .NET application marshals the string accordingly appropriately on either of the Windows OS system type.
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
One other quick thought, not likely but you might check permissions and the creditials being used.
Rocky <><
www.HintsAndTips.com
|
|
|
|
|
Thanks, will keep this in mind.
Rickard
|
|
|
|
|
Hi,
I have now debugged my application and the string seems to be alright, but it
still doesn´t work, or actually it worked for a while, but suddenly
the same error occured again.
Could this be some kind of access problem?
Could it make a difference in I run the com in process or out of process?
Rickard
|
|
|
|
|
I have created my own Rebar Control and I am having issues on Windows 2000 machines.
When creating the handle it throws an Win32Exception with the error "Invalid window class name". It works fine on Windows XP machines.
The following is my CreateHandle method and CreateParams property. Any ideas?
protected override void CreateHandle()
{
if (!RecreatingHandle)
{
// Initialize Cool Bar Common Control
INITCOMMONCONTROLSEX initCommonControls = new INITCOMMONCONTROLSEX(); // I set Size field in constructor
initCommonControls.Flags = InitCommonClasses.COOL_CLASSES | InitCommonClasses.BAR_CLASSES;
SafeInterop.InitCommonControlsEx(initCommonControls);
}
base.CreateHandle(); // <-- Exception thrown here
}
protected override CreateParams CreateParams
{
[SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
get
{
CreateParams createParams = base.CreateParams;
createParams.ClassName = Interop.REBARCLASSNAME;
createParams.Style |= (int)(CommonControlStyles.NORESIZE | CommonControlStyles.NODIVIDER | CommonControlStyles.NOPARENTALIGN);
if (_Borders)
{
createParams.Style |= (int)RebarStyles.BANDBORDERS;
createParams.Style |= (int)(RebarStyles.VARHEIGHT | RebarStyles.AUTOSIZE);
return createParams;
}
}
}
|
|
|
|
|
You must make sure that your window class is registered using RegisterClass(Ex) API. InitCommonControls does this for classes defined in the common controls library, but any custom classes must be registered by you.
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
I found out what is was. The INITCOMMONCONTROLSEX structure had the size and flags fields the wrong way, so the call to InitCommonControlsEx was failing. It's just weird that it worked fine Windows XP, sometimes is really bad for developing on, because it hides errors.
|
|
|
|
|
Hey guys!
How can i mix events in C#?
I want make a function what only runs when the mouse button is pressed, and the mouse's moving.
MS Visual Studio.NET 2003
C#
|
|
|
|
|
Here's an idea: How about in the OnMouseDown set a flag to say the mouse is pressed, in the OnMouseUp reset the flag back to its initial state. Then in the OnMouseMove event you can check the status of the flag to determine if the button is pressed or not.
--Colin Mackay--
EuroCPian Spring 2004 Get Together[^]
|
|
|
|
|
Hello:
Look at the next C++ code:
1) Defining map
const int cols=15;
struct stTot {
string strDesc;
double fTots[cols];
} myTot;
map<int, stTot> mpLis;
map<int, stTot>::iterator it;
2) Loading map
int iCnt = 0;
myTot.strDesc = (LPCTSTR)some_string;
for (int v=0; j<cols; myTot.fTots[j++]=0);
mpLis[iCnt] = myTot;
3) Extracting data from map
it = mpLis.find(some_value)
for (f=0;f<cols;f++)
{
monto_n3[f] += monto_pf[f];
(*it).second.fTots[f] = monto_pf[f];
}
In spite of some things that could be optimized in this code, it looks “elegant and powerful”, question is: How can I do this in C# so it looks elegant and powerful also?
I know that C# has System.Collections.Hashtable but it does not seem to solve the previous code. Who can surprise me?
Many, many thanks if you answer me.
Best regards
Eduardo Gironas.
|
|
|
|
|
Please do not re-post - continue the original thread.
What you're code is using is an enumerator. The Hashtable and other collections support this, too. See Hashtable.GetEnumerator , which returns an IDictionaryEnumerator . Other collections and lists (those that implement IEnumerable , which ICollection and IList do, so any of their implements do as well) return an IEnumerable .
If the Hashtable doesn't work for you, there are plenty of other collections and lists in System.Collections and System.Collections.Specialized that can. If you don't like the provided implementations, write your own ICollection , IList , or IDictionary implementation.
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
Heath:
Many thanks for your answer.
The real problem is with the structure:
struct stTot {
string strDesc;
double fTots[cols];
} myTot;
I cannot replicate this in C#. I tried many alternatives but I do not really know how to use it (the structure) during the Hashtable loading and recovery of data. A non elegant solution is to join every field that is in the mentioned structure into an string variable and then split them during recovery.
Best regards
|
|
|
|
|
public struct myTot
{
public string strDesc;
public double[] fTots;
} As you can see, there are a few limitations due to either the language specifications or the .NET Framework.
As far as putting this in a collection or Hashtable , the default, non-specialized implementations take objects as both keys and values. Ever class or value type (which a struct is) derives from System.Object , so you can put a struct in a Hashtable :
myTot tot = new myTot();
tot.strDesc = "blah";
tot.fTots = new double[] {1.2, 3.4};
Hashtable t = new Hashtable();
t["key1"] = tot;
Console.WriteLine(((myTot)t["key1"]).strDesc); Read the documentation for the classes in System.Collections about enumerations, collections, lists, and dictionaries. For instance, to enumerate through all the values of a dictionary using the keys, you could do the following:
IEnumerator e = t.Keys.GetEnumerator();
while (e.MoveNext())
{
Console.WriteLine("{0}: {1}", e.Current, t[e.Current]);
} You could also use the foreach keyword for a shortcut:
foreach (object key in t.Keys)
{
Console.WriteLine("{0}: {1}", key, t[key]);
}
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
I have a windows form application that i'd like to be able to send startup parameters to tell it what settings file to load say:
myApp.exe /settings.xml
how would a do this?
|
|
|
|