|
It would depend alot on whether or not it is a COM or .NET dll that you wish to load. If it is a .NET dll you can use reflection to load the assembly that the class lives within. I believe it is in Assembly.Load() that you want to research.
|
|
|
|
|
|
Apologies for the really noob question, but here goes:
I want to make a boolean field in my homespun class available, so that I can link a Checkbox (or multiple checkboxes) to it. I'm not sure what the proper terminology for this link is, maybe data binding?
Here's the source of my class;
class ToggleClass<br />
{<br />
private bool value;<br />
<br />
public bool Value<br />
{<br />
get { return value; }<br />
}<br />
<br />
public ToggleClass ()<br />
{<br />
value=false;<br />
}<br />
<br />
public void Toggle ()<br />
{<br />
while(true)<br />
{<br />
value=!value;<br />
Thread.Sleep(1000);<br />
}<br />
}<br />
}
An application would create an instance of the ToggleClass, and then create a new thread and start the Toggle() method going.
ToggleClass obj=new ToggleClass();<br />
Thread thread=new Thread(new ThreadStart(obj.Toggle));<br />
thread.Start();
Now I assume that I can use
obj.Value
to read the current state of the boolean.
I'm using the C# Express development environment, so I've created a Form, put a Checkbox on it, and then linked my ToggleClass as a data source, so that I can set the DataBindings property of the Checkbox to the Value field of the ToggleClass class.
checkbox1.DataBindings.Add(new Binding("Checked",ToggleClass,"Value",true));
I suspect that I'm missing some way of notifying the Checkbox(es) that the value of the boolean has changed. So that's my question, what else do I need to implement such that the Checkbox will reflect the current value of the bool field? Should I be throwing an event, which the Checkbox(es) catches?
Alternatively, if I'm barking up the wrong tree to get this type of job done, please tell me which tree I should be barking up.
Thanks, Iain.
|
|
|
|
|
you're gonna love this one.
What you have setup so far is 1-way binding. That is to say that by binding your object's Value property to the checkbox's Checked property checking or unchecking the checkbox would affect your object. You should try this to confirm the behaviour.
In order to setup 2-way binding, which will update the checkbox when the underlying Value property chenges, you need a way to notify the UI that the data source's value has changed.
You do this by implementing a PropertyNameChanged event. So in your class you would have something like:
class ToggleClass<br />
{<br />
private bool value;<br />
<br />
public event EventHandler ValueChanged<br />
<br />
public bool Value<br />
{<br />
get { return value; }<br />
<br />
}<br />
<br />
public ToggleClass ()<br />
{<br />
value=false;<br />
}<br />
<br />
public void Toggle ()<br />
{<br />
while(true)<br />
{<br />
value=!value;<br />
if(ValueChanged != null)<br />
ValueChanged(this,EventArgs.Empty)<br />
Thread.Sleep(1000);<br />
}<br />
}<br />
}
Here is some extra reading for you:
http://msdn2.microsoft.com/en-us/library/xz45s2bh.aspx[^]
Current blacklist
svmilky - Extremely rude | FeRtoll - Rude personal emails | ironstrike1 - Rude & Obnoxious behaviour
-- modified at 12:05 Thursday 11th May, 2006
|
|
|
|
|
Thanks for the pointers, and the link to the MSDN article. My code now looks like:
public class ToggleClass : INotifyPropertyChanged<br />
{<br />
public event PropertyChangedEventHandler PropertyChanged;<br />
<br />
private bool value;<br />
public bool Value<br />
{<br />
get { return value; }<br />
}<br />
<br />
public ToggleClass ()<br />
{<br />
value = false;<br />
}<br />
<br />
private void NotifyPropertyChanged (string info)<br />
{<br />
if(PropertyChanged!=null)<br />
{<br />
PropertyChanged(this,new PropertyChangedEventArgs(info));<br />
}<br />
}<br />
<br />
public void Toggle ()<br />
{<br />
while(true)<br />
{<br />
value = !value;<br />
NotifyPropertyChanged("Value");<br />
Thread.Sleep(1000);<br />
}<br />
} <br />
}
I think I now understand about how the interface is implemented, and the event generated when the bool is changed. (Quite similar to my Java days; interfaces and events)
Now the bit which is perplexing me, is the connection to the Checkbox. I don't understand how this DataBindings concept works. When I use the C# Express development environment a toggleClassBindingSource is created for me, and a reference to the ToggleClass is created. The Checkbox appears to be bound to the binding source, but that only references to the class, not an instance of that class. Hence if I had two ToggleClass objects I can't point the Checkbox at either object, only at the class definition.
Thanks again, Iain.
|
|
|
|
|
Hi,
I have a form with tab pages on it, and I'd like to print each page whenever a button is pressed (all the tabpages share the same print button - I just give it a different parent when another tab is pressed). But I can only print once. When the print button is pressed the second time, I get error
An unhandled exception of type 'System.Runtime.InteropServices.ExternalException' occurred in system.drawing.dll
Additional information: A generic error occurred in GDI+.
I'm not sure what to do here. My code is below. I also tried giving the PrintDocument a different name each time, and it still isn't happy.
private void printClick(object sender, System.EventArgs e)<br />
{<br />
Graphics currentTab = this.CreateGraphics();<br />
Size s = this.Size;<br />
Bitmap memoryImage = new Bitmap(s.Width - 10, s.Height - 36, currentTab);<br />
Graphics memoryGraphics = Graphics.FromImage(memoryImage);<br />
IntPtr dc1 = currentTab.GetHdc();<br />
IntPtr dc2 = memoryGraphics.GetHdc();<br />
BitBlt(dc2, 0, 0, this.ClientRectangle.Width, this.ClientRectangle.Height, dc1, 2, 2, 13369376);<br />
CurrentPage = memoryImage;<br />
currentTab.ReleaseHdc(dc1);<br />
memoryGraphics.ReleaseHdc(dc2);<br />
CurrentPage.Save("sCurrentPage.bmp",System.Drawing.Imaging.ImageFormat.Bmp);<br />
<br />
PrintDocument pd = new PrintDocument();<br />
PageSetupDialog pg = new PageSetupDialog();<br />
printDialog1.Document = pd;<br />
pg.Document = pd;<br />
pg.PageSettings.Landscape = true;<br />
DialogResult result = printDialog1.ShowDialog();<br />
<br />
if (result==DialogResult.OK)<br />
{pd.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(PrintCurrentPage); pd.Print();}<br />
pd.Dispose();<br />
}
Thanks for any help!!!
Mel
|
|
|
|
|
Having a GDI exception occur tends to make me think that your problem is not with the printing, but rather in creating the bitmap. Where in your code does the stack trace point at? Does the bitmap get saved and have you looked at it to make sure it is the page you expected to print?
Two other things:
You can save yourself one object creation and a little bit of GC stress by changing the last four lines of code to this:
if ( printDialog1.ShowDialog() == DialogResult.OK )
{
pd.PrintPage += .....
}
}
|
|
|
|
|
I commented out just the pd.Print(); and it worked fine. No exceptions, correct bitmap saved each time.
I'm assuming the stack trace is the green arrow/highlight? If so, it points at the line PrintDocument pd = new PrintDocument(); .
Any ideas?
Mel
|
|
|
|
|
In case anyone needs it, the problem is in this line:
pd.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(PrintCurrentPage);
PrintCurrentPage looked like this:
private void PrintCurrentPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)<br />
{<br />
if (CurrentPage != null){CurrentPage = new Bitmap(@"C:\sCurrentPage.bmp");} <br />
}
I found that "When a bitmap image is loaded from a file the file remains locked open. This may be the root of the problem.
To overcome the file locking open the file on a stream, read the image from the stream and explicitly close the stream."
So I changed PrintCurrentPage to look like this:
if (CurrentPage != null)<br />
{<br />
FileStream fs = File.Open(@"C:\sCurrentPage.bmp", FileMode.Open, FileAccess.Read);<br />
Bitmap bm = (Bitmap)Bitmap.FromStream(fs);<br />
CurrentPage = bm;<br />
e.Graphics.DrawImage(CurrentPage, 0, 0);<br />
fs.Close();<br />
bm.Dispose();<br />
}
And it all worked fine.
Cheers,
Mel
|
|
|
|
|
Thank you!
Just needed it.
|
|
|
|
|
why it doesn't work? It show the draw i want, but when i write text the draw disappear:
public partial class UserControl1 : TextBox
{
public UserControl1()
{
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);
this.BorderStyle = BorderStyle.None;
InitializeComponent();
}
protected override void OnPaint(PaintEventArgs e)
{
Graphics g = e.Graphics;
Pen p = new Pen(Color.Red ,3.0f);
g.DrawRectangle(p, new Rectangle(0, 0, this.Width, this.Height));
}
}
|
|
|
|
|
Sasuko wrote: but when i write text the draw disappear:
Do you mean that the text you type is never displayed? If so, I would expect this is happening because your OnPaint() method isn't writing it.
/ravi
My new year's resolution: 2048 x 1536
Home | Music | Articles | Freeware | Trips
ravib(at)ravib(dot)com
|
|
|
|
|
OnPaint doesnt fire for TextBox based controls. Its by design. You will have to hack with P/Invoke.
|
|
|
|
|
My assembly is compiled for 64-bit, it is calling an unmanaged DLL, also compiled for 64-bit.
The kicker is that "long" compiles to Int64 on my side whereas "long" compiles to Int32 on the unmanaged side (right?)
So if I declare the unmanaged API like this
[DllImport("MyDll.dll", SetLastError = false)]
static extern void FillTheLong
(
out long theLong,
);
And call it like this
long myLong = 0xFFFFFFFF;
long myOtherLong;
FillTheLong(out myLong, out myOtherLong);
I would expect to hose the stack, but nothing adverse happens across hundreds of calls like this. Hard to believe I am just getting lucky, is the runtime protecting me somehow.
Anybody got a pointer to resources on details of P/Invoke and marshaling?
Thanks
NIK
|
|
|
|
|
It depends. Does FillTheLong take a C++ long? Or an 8 byte integer (i.e. a C# long)?
If the former, your call will mess things up eventually; you'll have some bizzare errors occuring at some point most likely. If you have Visual Studio 2005 and you run this under a debugger, Visual Studio's Managed Debugger Assistant will catch this and let you know the stack is corrupted.
Tech, life, family, faith: Give me a visit.
I'm currently blogging about: Islamic Domination: Coming to a Jewish state near you!
The apostle Paul, modernly speaking: Epistles of Paul
Judah Himango
|
|
|
|
|
FillTheLong takes a C++ (32-bit) long, but I am passing a C# (64-bit) long.
in my example I should have been using
long myLong = 0x0F0F0F0FFFFFFFF;
There is a type mismatch, as confirmed by the fact that the value gets truncated.
I'm just surprised there isn't obvious stack corruption.
NIK
|
|
|
|
|
|
nicknotyet wrote: I'm just surprised there isn't obvious stack corruption.
Why would there be? Isn't that passed "by value". If the function parameter is only 32 bit then only a 32bit space is pushed onto the stack correct?
"What classes are you using ? You shouldn't call stuff if you have no idea what it does" Christian Graus in the C# forum
led mike
|
|
|
|
|
I'm not familiar with the physical layout of the stack, but yes as long as the construction of the callee's (unmanaged DLL) stack only pulls a 32-bit value from an allocated 64-bit space, then it should be ok.
Either way I still have re-write my code to explicitly use Int32 in place of long because of the truncation issues.
Thanks for the feedback.
|
|
|
|
|
nicknotyet wrote: Either way I still have re-write my code to explicitly use Int32 in place of long because of the truncation issues.
Do you need a 64-bit integer? Will you ever encounter numbers in your managed app that will be too big to fit in a 32-bit int?
Matt Newman
Even the very best tools in the hands of an idiot will produce something of little or no value. - Chris Meech on Idiots
|
|
|
|
|
Fortunately no, not for this assembly. The truncation will probably never be an issue, its just a matter of correctness at this point.
Nice quote, I'll try not to take it personally, and I will remind my boss of it if he ever tries to hire on the cheap.
Thanks for the response.
NIK
|
|
|
|
|
nicknotyet wrote: I would expect to hose the stack, but nothing adverse happens across hundreds of calls like this. Hard to believe I am just getting lucky, is the runtime protecting me somehow.
You could just be lucky with stack alignment, maybe there is some padded space. Why not step with the debugger , and look at the memory of the stack with proper and the wrong values?
|
|
|
|
|
1) Can't drill down from the managed side, maybe I need some education on this.
2) Tried debugging from the unmanaged side, but VS barfed.
Haven't had time to resolve either debugging issue. I wrote some code on the unmanaged side to show me what I needed to know and moved on.
Thanks for the response
NIK
|
|
|
|
|
Hi All,
Wondering if anyone has a good recommendation for a c# grid control? Looking for something that allows for "virtual grid" type of thing. I've tried ComponentOne, and wasn't crazy about theirs (too hard to customize). Anybody used one that they have been happy with?
|
|
|
|
|
SourceGrid[^] is a nice one, but be carefull, download it from the devage website (mentioned in the CP article) cause there is a new version already, but the CP articel gives a good shot what you can do with it.
|
|
|
|