|
refer to the link below
http://support.microsoft.com/default.aspx?kbid=327823#1
using System;
using System.Windows.Forms;
public class MyTextBox :System.Windows.Forms.TextBox
{
// Override IsInputKey method to identify the Special keys
protected override bool IsInputKey( System.Windows.Forms.Keys keyData )
{
switch ( keyData)
{
// Add the list of special keys that you want to handle
case Keys.Tab:
return true;
default:
return base.IsInputKey(keyData);
}
}
}
Based on the sample above, I've managed to modify and fire KeyDown Event for textbox, combobox, checkbox, datetimepicker, etc...
except NUMERICUPDOWN.
how to make it work??
|
|
|
|
|
You should override OnTextBoxKeyPress on the NumericUpDown control as well. The existing code handles numbers and letters A-F if Hexidecimal is set to true . Override it and execute your code first, then call base.OnTextBoxKeyPress .
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I still can't make it work. Maybe I did some way wrong.
Actually, what I want is to create a customize NumericUpDown(nud) as a class component.
Then, when I create a winform, I can drag and drop the customized nud from toolbox into the winform.
In the winform, and where the nud is, a KeyDown event is binded to it. In the KeyDown Event, I would like to have the code below:
if(e.Keys == Keys.Tab || e.Keys == Keys.Enter)
{
// ...
// Do Something.... some checking here
// ...
//After the checking
//Then only I "manually" call SelectNextControl method
this.SelectNextControl(Control(sender), true, true, true, true);
}
I've put in the "Override IsInputKeys" code and the OnTextBoxKeyPress as well in the component class. When I run debugger, I noticed that Tab Key didn't go into OnTextBoxKeyPress.
Maybe you have to describe more in detail. Thanks.
|
|
|
|
|
I'm trying to create a plugin for an app I am building. I am trying to utalize CreateInstanceAndUnwrap. Been trying for days now, still with no luck. Heres my code:
Sorry its a little messy
AppDomain remote = AppDomain.CreateDomain("Remote DLL");
IPlugin plugin = (IPlugin) remote.CreateInstanceAndUnwrap(
PluginManager.strPath + @"\" + pluginList.SelectedItem,
"IPlugin");
plugin.loadAssembly(PluginManager.strPath + @"\" + pluginList.SelectedItem);
I read some demos of apps sorta like this that use Loader : MarshalByRefObject. But that only gives me a referance to the object not an instance. As you can see I'm trying to place the instence in its own AppDomain so I can unload it later.
Anyone have any suggestions, I'm litteraly pulling my hair out (and its quite painfull )
If you have an example that would be great, what my goal is -- to create the object from the DLL in the other app domain so I can call its functions.
The plugin dll is seralizable.
This is what IPlugin looks like:
public interface IPlugin
{
string Description {get;}
string Author {get;}
void Initalize();
void Render();
void SendData();
void Dispose();
}
The plugin I created looks like this:
public class Plugin : IPlugin
{
public string Author { get { return "Matthew Hazlett"; } }
public string Description { get { return "Testing the plugin"; } }
public void Initalize() {}
public void Render() {}
public void SendData() {}
public void Dispose() {}
public Plugin() { }
}
Matthew Hazlett
Windows 2000/2003 MCSE
Never got an MCSD, go figure...
|
|
|
|
|
Why not try:
ObjectHandle o;
IPlugin plugin;
Type t = Type.GetType("SomeAssembly.dll");
o = Activator.CreateInstance(t);
plugin = (IPlugin)o.Unwrap();
plugin.Render();
- Nick Parker My Blog
|
|
|
|
|
Thank you for your help, but it still will not work correctly. But at least its giving me a different error now:
An unhandled exception of type 'System.NullReferenceException' occurred in PluginHost.exe. It dies on this line o = Activator.CreateInstance(dll, t.ToString());
ObjectHandle o;
IPlugin plugin;
string dll = PluginManager.strPath + @"\" + pluginList.SelectedItem;
Type t = Type.GetType(dll);
o = Activator.CreateInstance(dll, t.ToString());
plugin = (IPlugin)o.Unwrap();
MessageBox.Show(plugin.Author);
I will keep at this and try to get it to work, thanks for pointing me in another direction. Also, if you have any further ideas please let me know.
Matthew Hazlett
Windows 2000/2003 MCSE
Never got an MCSD, go figure...
|
|
|
|
|
I'm still having issues, here is my fussionlog:
*** Assembly Binder Log Entry (3/8/2004 @ 9:12:15 PM) ***
The operation was successful.
Bind result: hr = 0x0. The operation completed successfully.
Assembly manager loaded from: C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\fusion.dll
Running under executable C:\Documents and Settings\hazlema.FRAGNET\My Documents\Visual Studio Projects\PluginHost\bin\Debug\PluginHost.exe
--- A detailed error log follows.
=== Pre-bind state information ===
LOG: DisplayName = IPortal, Version=1.0.1528.2599, Culture=neutral, PublicKeyToken=null
(Fully-specified)
LOG: Appbase = C:\Documents and Settings\hazlema.FRAGNET\My Documents\Visual Studio Projects\PluginHost\bin\Debug\
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = NULL
Calling assembly : PluginHost, Version=1.0.1528.37815, Culture=neutral, PublicKeyToken=null.
===
LOG: Processing DEVPATH.
LOG: DEVPATH is not set. Falling through to regular bind.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: Post-policy reference: IPortal, Version=1.0.1528.2599, Culture=neutral, PublicKeyToken=null
LOG: Attempting download of new URL file:///C:/Documents and Settings/hazlema.FRAGNET/My Documents/Visual Studio Projects/PluginHost/bin/Debug/IPortal.DLL.
LOG: Assembly download was successful. Attempting setup of file: C:\Documents and Settings\hazlema.FRAGNET\My Documents\Visual Studio Projects\PluginHost\bin\Debug\IPortal.DLL
LOG: Entering run-from-source setup phase.
Do you have any other ideas?
Matthew Hazlett
Windows 2000/2003 MCSE
Never got an MCSD, go figure...
|
|
|
|
|
Post some of the code that is failing.
- Nick Parker My Blog
|
|
|
|
|
Nick, thanks for your hellp.
I fixed it, works like a charm now!
Matthew Hazlett
Windows 2000/2003 MCSE
Never got an MCSD, go figure...
|
|
|
|
|
If you're getting a FileNotFoundException (in which the default error message is what you're getting), it's because the CLR cannot find your assembly that contains the Type. Nick's code was almost correct (Type.GetType("MyPlugin, MyAssembly") instead of what he wrote, which was just the assembly filename), but the assembly (MyAssembly.dll in this case) needs to be in a directory that can be resolved (or online with the necessary assembly binding information in the app's .config file).
See How the Runtime Locates Assemblies[^] in the .NET Framework SDK for more information.
There's also many articles here on CodeProject that discuss plugin architectures if you're having problems.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Thanks for the link.
Matthew Hazlett
Windows 2000/2003 MCSE
Never got an MCSD, go figure...
|
|
|
|
|
Heath Stewart wrote:
Type. Nick's code was almost correct
followed by a throw in a little and end it with a .
I guess you got me.
- Nick Parker My Blog
|
|
|
|
|
Look at my Plugin Manager article/code, it does it all there, with alot of work (that could probably be improved on).
Now lemme remember what the trick was? BAD MSDN DOCS!
snippet:
string assname = typeof(PluginManager).Assembly.FullName;
string typename = typeof(PluginManager).FullName;
pm = plugdom.CreateInstanceAndUnwrap(assname, typename,
true, BindingFlags.Default, null, this.objs, null, null, null) as PluginManager;
top secret
|
|
|
|
|
Yes, I read your artical a nice piece of work.
And you are right, the MSDN docs on this topic are horible !
Matthew Hazlett
Windows 2000/2003 MCSE
Never got an MCSD, go figure...
|
|
|
|
|
Got it to work using a subset of your example.
Thanks...
Matthew Hazlett
Windows 2000/2003 MCSE
Never got an MCSD, go figure...
|
|
|
|
|
My idea was to specifically allow changes at runtime without loading multiple versions of the same assembly, not sure if you wanted something like that.
top secret
|
|
|
|
|
I'm not looking for a solution to a problem; I want to know why .NET won't allow the following:
interface IFoo
{
void Invalidate();
}
class FooBar
{
private System.Windows.Form winForm;
private IFoo theFoo;
...
theFoo = winForm;
}
On the call theFoo = winForm , the compiler complains that an explicit cast is required. Why? winForm has an .Invalidate method, so why bother? Of course, an explicit cast generates a runtime error. Again, why? If a class implements all methods required by a particular interface without actually implementing the interface, why is an exception thrown? At the very least, an explicit cast should work (even though the compiler could verify and do implicit casts).
Could someone shed some light on why it is designed this way?
---------------------------
He who knows that enough is enough will always
have enough.
-Lao Tsu
|
|
|
|
|
I have two classes A and B , both of which have MyMethod() .
Now this is my problem:
A a = new B();
But the compiler complains that it is not possible even though they both have MyMethod() method.
Do you know why it is designed this way?
Don't forget, that's Persian Gulf not Arabian gulf!
Murphy: Click Here![^] I'm thirsty like sun, more landless than wind...
|
|
|
|
|
You're not making sense. Of course you can't do that conversion; classes A and B are not compatible even if they share a method (or even all methods).
However, an interface is supposed to work like that; ICloneable specifies a .Clone method, and all objects that implement ICloneable have a .Clone method. If I create my own interface IFoo that specifies a .Clone method, any class that is ICloneable should be convertible to IFoo.
Here's an example situation I ran into last night that brought about this question. I have a component that is passed either a Sys.Win.Forms.Form object or a Sys.Win.Forms.Control object. It is completely up to the consumer of my component whether to pass a Form or a Control . In my component class, the only thing I care about is that the passed object, either Form or Control, have a .Handle getter property and a .Invalidate() method. Because both Form and Control have these types, it would be ideal if I could create my own interface and store that type, like so:
interface IHandleWithInvalidate
{
IntPtr Handle{get;}
void Invalidate();
}
class myComponent
{
private IHandleWithInvalidate passedObject;
public myComponent(Form f)
{
this.passedObject = f;
}
public myComponent(Control c)
{
this.passedObject = c;
}
private void DoSomething()
{
this.passedObject.Invalidate();
IntPtr h = this.passedObject.Handle;
}
}
Alas, .NET won't let me do this. Instead, I have to keep 2 variables, and throughout my code, I have to check which one to use, nearly doubling the amount of code I have to write. For example, the above snippet would now look like this:
class myComponent
{
private Form passedForm;
private Control passedControl;
public myComponent(Form f)
{
this.passedForm = f;
}
public myComponent(Control c)
{
this.passedControl = c;
}
private void DoSomething()
{
if(this.passedForm != null)
{
this.passedForm.Invalidate();
IntPtr h = this.passedForm.Handle;
}
else
{
this.passedControl.Invalidate();
IntPtr h = this.passedControl.Handle;
}
}
}
As you can see in the DoSomething() method, I have to write 10 lines of code instead of 2. Given that I'll be using my passed object often, one can clearly see the side effects of using such a model.
I think C# should have some construct to allow me to accomplish a similar task without writing extra lines of code; if not interfaces, then maybe something like C unions. What do you guys think?
---------------------------
He who knows that enough is enough will always have enough.
-Lao Tsu
|
|
|
|
|
Because in .net (and java and lots of other languages) interfaces have to be declared in class declration. Since Form does not implement IFoo can't convert it to IFoo. What you're looking for is named interface semantics and .net has structural interface semantics.
|
|
|
|
|
The form (which you must derive from System.Windows.Form ) must implement the interface. This is by design and is common in many languages (including all .NET languages - if they support interfaces, Java and C++).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Thanks for the reply. Yeah I realize that it must implement the interface to actually work. So maybe an interface is not the right solution, maybe a new C# construct would be a better solution. For instance, if I were to have a component class that was passed either a DataView or a BinaryWriter object, and the component itself only cared about the .Close method of either the DataView or the BinaryWriter, I could write the following code:
public SpecialC#Construct
{
has a .Close method
}
public class myComponent
{
private SpecialC#Construct passedObject;
public myComponent(DataView v)
{
this.passedObject = v;
}
public myComponent(BinaryWriter b)
{
this.passedObject = b;
}
public void DoSomething()
{
this.passedObject.Close();
}
}
This is really what I'm trying to do. But since I'm not allowed to do that with interfaces, and there's no other construct that'll let me do that, I'm forced to write the above like so:
public class myComponent
{
private DataView passedDataView;
private BinaryWriter passedWriter;
public myComponent(DataView v)
{
this.passedDataView = v;
}
public myComponent(BinaryWriter b)
{
this.passedWriter = b;
}
public void DoSomething()
{
if(passedDataView != null)
{
passedDataView.Close();
}
else
{
passedBinaryWriter.Close();
}
}
}
Given that I'd be using the passed object very often in my code, be it a DataView or a BinaryWriter, that will roughly double the number of lines I have to write, as seen in the DoSomething method. From what I can tell, there doesn't seem to be a good way to do this.
---------------------------
He who knows that enough is enough will always have enough.
-Lao Tsu
|
|
|
|
|
You are trying to circumvent the strongly typed system in .Net. You should write a shim object that behaves like a DataView or a BinaryWriter through that shim object/interface. This shim will have Close and any other logic to call the right things.
Too many times people try to use "code reuse" to get out of the wrong type of work. You have a situation where you have two objects that behave in a similiar manner but aren't related. The logic to determine which one is applicable has to exist somewhere.
ps. Even in C++, the results of doing what you were doing is somewhat unexpected (and often frowned upon). Close could be any method on any object in the inheritance chain. If the v-table is built arbitrarialy (ie. in a random order) then who knows which object version of Close you just called. It is one the banes of having a system where multiple inheritance exists.
|
|
|
|
|
Tom Larsen wrote:
You are trying to circumvent the strongly typed system in .Net. You should write a shim object that behaves like a DataView or a BinaryWriter through that shim object/interface. This shim will have Close and any other logic to call the right things.
Yeah I figured that's what would be suggested. I hate to write an extra object just for this simple problem, but I suppose it would be better than writing it out as previously posted.
Thanks for the replies Tom and Heath.
---------------------------
He who knows that enough is enough will always have enough.
-Lao Tsu
|
|
|
|
|
Why do you care about a Close method? If you want to make sure something's closed, then you're going about it the wrong way. Instead, accept an IDisposable and call Dispose on the object. It doesn't matter what the implementation is, then. IDisposable is implemented by objects that have to clean up resources, like streams and the like. It will close any handles that are open for you. THAT's what you need to worry about if I follow your train of thought correctly. See the documentation for the IDisposable interface in the .NET Framework SDK for more information.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|