|
You don't need to - and probably shouldn't - use both the Monitor and AutoResetEvent . Use one or the other.
The most likely problem is that you're locking the entire operation - this is virtually equivalent to doing these operations synchronously! Only lock when you need to. For example, unless you're synchronizing the same file between directories at the same time (and be careful, because the Changed event is fired exactly 3 times per changed file, no matter what the size), you can let the file copy operation occur in separate threads at the same time. Just lock when you need to write to the console or a file.
The timeout effect is occuring because the events are piling up and you're locking everything like I said above. You'll need to design your threads (using one of the methods I was talking about) so that the FileSystemWatcher can continue firing events without overloading the event queue so to speak.
-----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-----
|
|
|
|
|
Hello Heath,
I use the msmq Framework now. The Filewatcher sends a message for each event. So, I can Sequentially work through the Messages and call the third-party-API one call after the other without loosing events or get concurrent API calls (with a certain loss of performance I must admit, but conceptual, this API is one big bottleneck... no multithreading, etc. .)
The ReceiveHandler is locked with only a Monitor, as you said.
It works, greetings
Wolfram
|
|
|
|
|
How can i make a control be not confined within the borders of its parent window or parent control? Is that even possible? Example I have a listbox inside a textbox, and is trying to mimic the autocomplete feature. What I want is when the listbox appears it should be completely visible, extending over the borders of the textbox.
|
|
|
|
|
You can actually use the auto-complete services that Windows provides. Take a look at this article: http://www.codeproject.com/csharp/csdoesshell4.asp[^].
And, no, controls can't paint outside their containers. In the case of the auto-complete window, it is an actual popup window so it doesn't have a container to which it's confined. A popup window is positioned and displayed appropriately and communicates with the control with which it's associated. You could also see the Platform SDK documentation for the IAutoComplete interface for more information as well.
-----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 for the quick reply. I have actually read about that auto-complete service that Windows provides, but as I understood the dll required is found on XP and 2000 only. I might have clients who will still use windows 98 so Im trying to look for another option.
I guess I'm gonna go with the popup window route. Thanks again!
|
|
|
|
|
I'm writing a program that uses a TreeView control and a PropertyGrid. I've got several objects that users will be editing the properties of. What's supposed to happen is that the user will select an object from the tree, and then edit its properties in the grid.
I've been parsing the Node.FullPath property in my TreeView_AfterSelect function and then using that information to assign the correct object to the property grid. However, this is very time consuming.
It was suggested to me that a better way to do this might be to create my own child class of TreeNode, that contains a property that points to one of my objects. So... I created one base class that all of my other classes inherit from (SkinObject), created my child class of TreeNode (TreeNodePtr) and added a SkinObject property.
Now... how do I access that SkinObject property once inside my AfterSelect function? It doesn't seem as though a TreeNodePtr object is being passed in anywhere.
Any help with this would be greatly appreciated.
|
|
|
|
|
The TreeViewEventArgs.Node is what you're after. Since you derived a class from TreeNode , it's still your type (verify it with Node.GetType() ) but it's also a TreeNode - that's polymorphism. Just assign the Node property to your PropertyGrid 's SelectedObject property and you should see your SkinObject property. Don't even worry about casting it. For example, EVERY type in .NET derives from System.Object . While they are specific types, they are all objects and inherit the methods from Object (though some can be overridden):
object o = new TreeNode();
Console.WriteLine(o.GetType().FullName); You can further control the category, description, and many other design-time aspects of that property by using attributes in the System.ComponentModel namespace, like the CategoryAttribute and DescriptionAttribute .
-----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-----
|
|
|
|
|
Alright, I tried what you suggest, but here's the problem...
What I'm trying to do is assign the node's SkinObject object to the PropertyGrid. So something like prpSkinProps.SelectedObject = e.Node.SkinObject;
Unfortunately, when I try this, the compiler tells me that System.Windows.Forms.TreeNode doesn't have a property called SkinObject. Which it doesn't. Because TreeNodePtr does.
And obviously if I assign the Node itself to the Property Grid, then I see the properties of the Node, when what I want is the properties of the Node.SkinObject.
|
|
|
|
|
Instead, do:
prpSkinProps.SelectedObject = (e.Node as TreeNodePtr).SkinObject;
That way you're accessing it as a TreeNodePtr instead of a TreeNode.
|
|
|
|
|
Awesome. Works great. Thanks guys/gals.
|
|
|
|
|
I was about to tell you to cast. It's an important concept to understand when dealing with polymorphism.
There is actually a better way, though:
propertyGrid.SelectedObject = ((TreeNodePtr)e.Node).SkinObject; It's better because the as keyword acts as a cast that - if the cast is not successful - only returns null instead of throwing an InvalidCastException . This is better because it requires fewer instructions to perform and doesn't use a try-catch, which can be very expensive! Fortunately, even if the original TreeNode was not a TreeNodePtr , casting it will make it one so that an exception will not be thrown - SkinObject will be null, though, which will just reset the PropertyGrid . Either way, a simple cast is faster and will perform better.
-----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-----
|
|
|
|
|
Ok, I have a new, related, question...
I need to find out the exact type of the SkinObject that's being passed in to the AfterSelect function. Some of them have a property that others don't, and depending on which one is selectd, a button needs to be enabled or disabled.
I've been trying to use the typeof function to retrieve this, but it's not working. For instance if I try something like:
Type t = typeof(((TreeNodePtr)e.Node).SkinObject);
the compiler just tells me that typeof is expecting a type.
I've figured that I can just add another property to TreeNodePtr, like a boolean or something, and just set it to true or false when I'm creating the TreeNode, but I figure there has to be a more elegant solution to this.
Any ideas?
|
|
|
|
|
typeof is a compile-time function. You need to use Object.GetType (always returns the right Type of the object), so you'd want to use:
Type t - e.Node.GetType() For reference types, you can also check with the is keyword:
if (e.Node is SkinObject)
{
} And here I thought GetType would've been the obvious choice!
-----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-----
|
|
|
|
|
>And here I thought GetType would've been the obvious choice!
hehe... well, it would have been except that I had typeof fresh in my mind from writing my typeconverters. :P
|
|
|
|
|
I have a textbox inside a user control that I set up to be right aligned to start. Then when the textbox receives focus, I want it to align left. Then when focused is lost, I want it to restore itself back to right alignment. I can get it to align itself left when focus is given to the textbox. But, when the user tabs off the textbox, it erases the text and keeps focus on the textbox. I tied into the enter and leave events and also tried it on the gotfocus and lostfocus events but I don't understand why it is erasing the text and why it is not giving focus to the next control. Any ideas would be very helpful. Thanks
|
|
|
|
|
The problem is with the order of events. When using the keyboard, the events are fired in the following order:- Enter
- GotFocus
- Leave
- Validating
- Validated
- LosFocus
When you use the mouse or call the Focus method, the events are fired in the following order:- Enter
- GotFocus
- LostFocus
- Leave
- Validating
- Validated
So, if you handle the Enter and LostFocus events, what you want works when using the keyboard. If you use the likely pairs together (like Enter and Leave ), when you change the TextAlign property the handle for the text control is recreated. If it had the focus (which for keyboard events, it still does) the focus is again set to the TextBox . This is why you couldn't leave. The text disappearing is again related to the handle of the text control (which is actually a wrapper for the Edit common control) being created at the wrong time so that the text isn't being restore because it wasn't there when the handle was recreated.
The trick is to change the alignment at the correct time based on whether or not a mouse button was clicked:
myTextBox.Enter += new EventHandler(myTextBox_Enter);
myTextBox.Leave += new EventHandler(myTextBox_Leave);
myTextBox.LostFocus += new EventHandler(myTextBox_LostFocus);
private void myTextBox_Enter(object sender, EventArgs e)
{
myTextBox.TextAlign = HorizontalAlignment.Left;
}
private void myTextBox_Leave(object sender, EventArgs e)
{
if (Control.MouseButtons != MouseButtons.None)
myTextBox.TextAlign = HorizontalAlignment.Right;
}
private void myTextBox_LostFocus(object sender, EventArgs e)
{
if (Control.MouseButtons == MouseButtons.None)
myTextBox.TextAlign = HorizontalAlignment.Right;
} Seems pretty whacky, but it works.
-----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-----
|
|
|
|
|
Thank you very much. That worked
|
|
|
|
|
Here's my problem. I've added a Tree Control to my form. I've created my own child class of TreeNode (called TreeNodePtr), though, and I'm trying to use that. It's working fine, but everytime I change anything on the form in Design View, VS.NET changes all of the "new MyApp.TreeNodePtr(Test, "Test")" calls to things like (MyApp.TreeNodePtr)(System.Windows.Forms.TreeNode(Test, "Test").
I'm kind of new to this, but isn't this called a cast?
It's like the IDE knows I want to have a TreeNodePtr, but instead of just leaving it alone, it decides to cast it instead, and then it messes up all of my constructor calls.
|
|
|
|
|
Yes, it's a cast but there's really nothing you can do about it. The form and control designers do what they do. The only way to change it is to extend TreeView , create your own designer, and attribute your custom TreeView with the designer type you created. This isn't a trivial task, especially if you're new to .NET.
The other thing is to not use the designer! It's handy to initially layout controls on a form but it often becomes a hinderance. For example, I deal with a lot of localization but I hate how VS.NET does it. I rearrange quite a bit of code and move the ResourceManager out of InitializeComponents where VS.NET expects to find it. Since it doesn't, the designer breaks. I don't care though, because I stop using the designer long before that. It's the best way to truly learn what's going on instead of dragging-and-dropping your way to a simple application. Anyone can do that.
-----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-----
|
|
|
|
|
Hi,
i've created a web based setup project in VS.NET. Now everytime i start the setup.exe file, it downloads the msi package from the server. It would be nice if the setup.exe will check current installed version and only download if there is a new one on the server. Lets say a kind of update installation.
How to do that?
.:[Greetz from Jerry Maguire]:.
|
|
|
|
|
By buying a commercial Windows Installer development environment (like the user-friendly, yet completely customizable Wise for Windows Installer, or the very expensive InstallShield Developer) with a better bootstrapper (setup.exe), or by writing your own. See the Windows Installer SDK for information about that. It's not difficult, but it's important to remember that either you need to build your bootstrapper with each build, or have it download a configuration file (like the setup.ini file) that has the version information in it. The latter would definitely be easier than building and linking your own executable, but your bootstrapper will still need to know where to look (either by hardcoding a fixed URL for the setup.ini file or updating the .rsrc section of the executable with a more dynamic URL).
-----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-----
|
|
|
|
|
Hi
I have a listview lv with lv.View = View.List. It always shows the items with horizontal scroll & not vertical !
Is there a way I can set it to scroll vertically when the no of items is more in the lv that its size ?
Paul
|
|
|
|
|
Not without extending ListView and owner-drawing several things about the list-view control (ListView is just a wrapper for the list-view common control). I'm not sure you could even do this if you did go to all that work (and it is a lot!).
If it's really necessary, you might be better off looking for a third-party .NET control that can do it. Be sure it's that important, though, since this would be inconsistent with practically all other list views in Windows. It's important to remain consistent for useability unless absolutely necessary (read the Windows UI Guidelines for more details and reasoning for this if you don't already see the inherent importance of it).
-----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-----
|
|
|
|
|
Here is my problem:
The user selects a file.
Based on what the extension is, I need to get the viewer that is registered with the operating system for this file type.
And then I need to open the file with the viewer.
Do you know how to do that in C#?
Thanks a ton,
Elena
|
|
|
|
|
Process.Start("path/to/file.ext"); For fine-grain control, see the ProcessStartInfo class where you can specify a different verb other than "open" (or the default, which is "open" on Win98/ME machines) or redirect the standard IO streams.
-----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-----
|
|
|
|