|
Mr. VB.NET wrote: It has a lot of depth to it and I don't find a ton of C# examples out there.
See http://www.dofactory.com/Patterns/Patterns.aspx[^]
Mr. VB.NET wrote: First question: How does one start to use patterns, you read about them etc. but How do you take a design requirement and start the process?
Not had much of a chance to apply patterns in anger but I found this to be an excellent book.
Design Patterns Explained
http://netobjectives.com/dpexplained/index.html[^]
I own the first edition, so the second edition will be even better. In fact the whole of their site is pretty good.
The book uses Java snippets. But it is very basic Java and a cinch for C# ers to follow. What I like about the book is that it is problem-context based. Starts with procedural code then shows how OO overcomes its problems. Then shows how design patterns improve the original OO. This is a much better approach than just listing a bunch of patterns.
Kevin
|
|
|
|
|
That is the book I just purchased last week. Good so we're on the same track.
I have seen the "dofactory" site and will continue to use it. Of course all of this has piqued my interest in UML. I was thinking if we can reduce design to uml then there must be tools which generate code. Sure enough there's tons of them out there. Seems to me if you had a good UML tool you would be setting up good designs right away.
|
|
|
|
|
Mr. VB.NET wrote: Seems to me if you had a good UML tool you would be setting up good designs right away.
If only it were that straightforward! (we'd all be out of jobs)
I find that design patterns are often used for the sake of being used. Some people see it as a quantifiable way of determining whether a design is "good" or not. This is, in my opinion, a grave mistake. In my experience, patterns are only useful if they solve a distinct problem. If they do not, they add unnecessary complexity to what could be a simple solution.
Now that I've ranted about when not to use patterns...
I typically use a pattern if I find myself trying to satisfy multiple related requirements, conflicting or not. For example, in the most recent system I designed I had the need for a general way of expressing a hierarchial relationship between various types of business objects. The hierarchies needed to be expressed in various configurations, and also needed to play nice with WinForms databinding. To satisfy all of these requirements, I chose to use the Composite pattern...and it worked out beautifully.
HTH,
Josh
-- modified at 13:29 Wednesday 14th June, 2006
|
|
|
|
|
Interesting, I started using Java about 10 years ago, after being an Operating System's programmer with a large company for 3 years prior. I quickly wanted to use object oriented programming for reuse. However, I found myself then and now, still doing top down coding, breaking it all into methods or other classes. All of this with little thought into reuse, and even using a design at all. I just start programming and the design appears.
Having also been a carpenter I know that plans are important. Being a guitar player gave me patterns to use. I just put them together differently. I'm thinking this design stuff for programming is really important. I see my own company fail repeatedly with new implementations, which take years to maintain and change to make it really workable. There's got to be a better way.
|
|
|
|
|
Mr. VB.NET wrote: That is the book I just purchased last week. Good so we're on the same track.
You'll enjoy it!
It's one of those rare techie books that you can read more-or-less cover to cover.
Kevin
|
|
|
|
|
|
I have a deployment project, with an Installer class to do my custom actions. In it's Install() override I show a form.
My problem is I cannot seem to make my form change it's localization value and be displayed in french. Here is basicly what I want to do in my dialog:
public Form1()
{
Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-CA");
Thread.CurrentThread.CurrentUICulture = new CultureInfo("fr-CA");
InitializeComponent();
}
Why won't this display Form1 in french? If I call this routine from any other class but my Installer class it works fine.
Even if I run my deployment project in french, my Form1 will STILL not flip to french.
I know I need a seperate deployment project for both languages, but was hoping to use the same Installer Lib for both languages and just flip it's forms' culture settings....
Any insight on this would be helpful. Thanks!
-- modified at 11:32 Wednesday 14th June, 2006
|
|
|
|
|
I'm trying to create (using VC# 2005 Express and .NET2) a simple application that monitors the rate that bytes are received by a serial port. I've written a class that opens the serial port, counts the incoming bytes, and every second updates a property called "Rate" which is the number of bytes received in the last second.
Here's the class:
class PortMonitor : INotifyPropertyChanged<br />
{<br />
public event PropertyChangedEventHandler PropertyChanged;<br />
<br />
private SerialPort port;<br />
private UInt64 count;<br />
private UInt64 rate;<br />
private Thread thread;<br />
<br />
public PortMonitor ()<br />
{<br />
count = 0;<br />
rate = 0;<br />
<br />
port = new SerialPort("COM9",38400);<br />
port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);<br />
port.Open();<br />
<br />
thread = new Thread(new ThreadStart(Run));<br />
thread.Start();<br />
}<br />
<br />
public UInt64 Rate<br />
{<br />
get { return rate; }<br />
}<br />
<br />
private void Run ()<br />
{<br />
while(port.IsOpen)<br />
{<br />
count = 0;<br />
Thread.Sleep(1000);<br />
rate = count;<br />
NotifyPropertyChanged("Rate");<br />
}<br />
}<br />
<br />
private void port_DataReceived (object sender,SerialDataReceivedEventArgs e)<br />
{<br />
count+=Convert.ToUInt64(port.BytesToRead);<br />
port.DiscardInBuffer();<br />
}<br />
<br />
private void NotifyPropertyChanged (string property)<br />
{<br />
if(PropertyChanged != null)<br />
PropertyChanged(this,new PropertyChangedEventArgs(property));<br />
}<br />
}
At the user interface end of things I've got a form with a label on it. I want to bind the text of the label to the rate property of my monitoring object. I see that the recomendation for .NET2 is to use a BindingSource inbetween the label and the monitor.
Here's the UI:
PortMonitor monitor;<br />
BindingSource source;<br />
<br />
public Form1 ()<br />
{<br />
InitializeComponent();<br />
<br />
monitor = new PortMonitor();<br />
source = new BindingSource();<br />
source.DataSource = monitor;<br />
<br />
label1.DataBindings.Add("Text",source,"Rate");<br />
}
But this throws an InvalidOperationException as soon as the monitor class tries to notify the BindingSource that the Rate property has changed. I guess this is a variation of the "one thread can't call methods on the UI thread" exception.
What do I need to do to get this working?
Iain
|
|
|
|
|
Use a delegate.
Start the application off with the main form that just has the controls you want updated. Spin a thread off to do the work, in that thread there will be a delegate which will "notify" the main form's method of choice to process the data. Note you must set up a delegate type in the main form which the thread adheres to.
Note when you communicate with that control you must check for invoke.required and take appropriate action, which amounts to recalling the same routine via the invoke method. This ensures inter-thread communication and allows for the control to "always" receive and display the update.
When I first started learning about delegates I found them to be more difficult than the java modes of interprocess communications, however, once I cracked the surface open I found them to be rather easy. There are other ways to do this such as using static variables, but the deletegate is the best way hands down.
|
|
|
|
|
Just to clarrify: I should write my own event handling code in the form, which listens to PropertyChanged events from the monitor object, and then calls methods (via Invoke) on the label to update the text?
Something like...
public partial class Form1 : Form<br />
{<br />
PortMonitor monitor;<br />
<br />
public Form1 ()<br />
{<br />
InitializeComponent();<br />
<br />
monitor = new PortMonitor();<br />
monitor.PropertyChanged += new PropertyChangedEventHandler(monitor_PropertyChanged);<br />
}<br />
<br />
public void monitor_PropertyChanged (object sender,PropertyChangedEventArgs e)<br />
{<br />
if(InvokeRequired)<br />
{<br />
BeginInvoke(new PropertyChangedEventHandler(monitor_PropertyChanged), sender, e);<br />
}<br />
else<br />
{<br />
label1.Text=monitor.Rate;<br />
}<br />
}<br />
}
This seems like a knarly way of pushing data out to the UI, as it bypasses the BindingSource and negates the usefullness of the DataBindings in the Label. Isn't the BindingSource meant to be in the middle there handling all this inter-thread malarky?
I really like the simplicity of a one liner like:
progressBar1.DataBindings.Add("Value",myBindingSource,"FileTransferProgress");
Isn't there some way I can handle the invokation stuff in the NotifyPropertyChanged method of my monitoring class? Something like:
private void NotifyPropertyChanged (string property)<br />
{<br />
if(PropertyChanged != null)<br />
{<br />
Control target = (Control)PropertyChanged.Target;<br />
if(target.InvokeRequired)<br />
{<br />
target.BeginInvoke(new PropertyChangedEventHandler(PropertyChanged),this,new PropertyChangedEventArgs(property));<br />
}<br />
else<br />
{<br />
PropertyChanged(this,new PropertyChangedEventArgs(property));<br />
}<br />
}<br />
}
Would that, or something similar, work?
Iain
|
|
|
|
|
Start of with a delegate definition in the main form (A).
ex. public delegate void cmdFinished(string str);
Class (A) Spins off a thread passing the delgate which points to a method in the main form to send the update to.
The other class (B) which should be a thread has this:
ex. public Form1.cmdFinished cmdFinished;
Class (B) does has a constructor which passes in the deletegate. You might say it is encapsulated.
ex. public classConstrustor(Form1.cmdFinished incmdfinished, string inusername, string inpassword, string incomputername, string indomain)
Class (B) does it's stuff and then issues a callback
ex. cmdFinished("MSG:Attempting to Connect to remote location...");
This call will call the function to process this data in the main form.
The main form must check whether or not invoke is required on the control (a form restriction).
private void updateDataGridView1(string[] instr)<br />
{<br />
<br />
if (dataGridView1.InvokeRequired)<br />
{ <br />
Form1.updatedataGridView1 view1 = new Form1.updatedataGridView1(this.updateDataGridView1);<br />
base.Invoke(view1, new object[] { instr });<br />
}<br />
else (Process the string array, updating the control etc.)<br />
<br />
|
|
|
|
|
iswoolley wrote: But this throws an InvalidOperationException as soon as the monitor class tries to notify the BindingSource that the Rate property has changed. I guess this is a variation of the "one thread can't call methods on the UI thread" exception.
Try using the AsyncOperation and AsyncOperationManager classes. Raise your NotifyPropertyChanged event by passing a delegate to the AsyncOperation object's Post method. The AsyncOperation will take care of marshaling it to the Form's thread provided that the AsyncOperation object was created on the same thread as the Form.
See my article[^] on using the SynchronizingContext , AsyncOperation and AsyncOperationManager classes.
Hope this helps.
|
|
|
|
|
Okay, I think with all your help, I've solved this one (or at least got it working at the moment). I decided to use the SynchronizationContext object, so modified my constructor to take one:
public PortMonitor (SynchronizationContext c)<br />
{<br />
if (c != null)<br />
context = c;<br />
else<br />
context = new SynchronizationContext();<br />
<br />
count = 0;<br />
rate = 0;<br />
<br />
port = new SerialPort("COM9",38400);<br />
port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);<br />
port.Open();<br />
<br />
thread = new Thread(new ThreadStart(Run));<br />
thread.Start();<br />
}
Then when I want to raise an event I use:
private void NotifyPropertyChanged (string property)<br />
{<br />
if(PropertyChanged != null)<br />
{<br />
context.Post(new SendOrPostCallback(delegate(object state)<br />
{<br />
PropertyChanged(this,new PropertyChangedEventArgs(property));<br />
}),null);<br />
}<br />
}
And finally, in the UI when I create the PortMonitor object I pass into it a WindowsFormsSynchronizationContext:
public Form1 ()<br />
{<br />
InitializeComponent();<br />
<br />
monitor = new PortMonitor(WindowsFormsSynchronizationContext.Current);<br />
source = new BindingSource();<br />
source.DataSource = monitor;<br />
<br />
label1.DataBindings.Add("Text",source,"Rate");<br />
}
So hopefully now, all the events are raised in the appropriate context, but also non-UI threads can listen to events as well.
Thanks for your help.
Iain
|
|
|
|
|
Hi,
Can anybody tell which datatype of c# viz Float, double , decimal will be appropriate for calculating percentage (100%)
kumar
|
|
|
|
|
float is enough. It should be precise enough for most cases.
modified 12-Sep-18 21:01pm.
|
|
|
|
|
The float data type
float data type is the first of 3 data types that can store floating point numbers and actually this is the smallest of the 3 types. float variables store floating point numbers from 1.5 times 10 to the 45 th (±1.5 × 10-45 ) to 3.4 times 10 to the 38 th (±3.4 × 1038 ) in 32 bit. And this type has a precision to 7 numbers.
The double data type
double data type variables can store floating point numbers from 5 times 10 to the 324 th (±5.0 × 10-324 ) to 1.7 times 10 the 308 th (±1.7 × 10308 ) in 64-bit. And this type has a precision to 15-16 numbers.
The decimal data type
decimal data type variables can store 1 times 10 to the 28th 1.0 × 10-28 and 7.9 times 10 to the 28 th 7.9 × 1028 in 128 bit. If you think about this type you will note that it has a greater precision and a smaller range and that’s we exactly needs for financial calculations also note that decimal data type has a Precision of 28-29 significant digits.
|
|
|
|
|
One more quick thing on Decimal datatypes.
Although the C# language considers this a primitive datatype, the CLR does NOT. From a practical standpoint, this means that manipulating Decimal datatypes is slower than working with the other datatypes. Also, the checked and unchecked operators, and compiler switches have no effect on Decimal datatypes, which ALSO means that Decimal datatypes ALWAYS throw an OverflowException if the operation can't be done safely.
I was surprised by this, I am pretty sure I read it in Jeff Richter's book, and played with it some and he's right. I HATE it when that happens!
|
|
|
|
|
Hello!
I got a problem with the lines below. I don´t know how to use VirtualAllocEx in C# , because I must allocate a certain space for a struct and an item (both are pointers).
I´d like to know if anyone got any idea how I can do the same thing in c#.
This code is from: http://www.codeproject.com/threads/int64_memsteal.asp?df=100&forumid=29535&exp=0&select=727974&mpp=50#xx727974xx[^]
"Stealing Program's Memory"
LVITEM lvi, *_lvi;
char item[512], subitem[512];
char *_item;
HANDLE process;
_lvi=(LVITEM*)VirtualAllocEx(process, NULL, sizeof(LVITEM), MEM_COMMIT, PAGE_READWRITE);
_item=(char*)VirtualAllocEx(process, NULL, 512, MEM_COMMIT, PAGE_READWRITE);
Thank you!!
|
|
|
|
|
If you are trying to allocate memory in an unmanaged process, you can probably use PInvoke[^] to make it work. If the memory you need to allocate will be in another managed process, then those unmanaged APIs will not work. What you would need to do in that situation is, probably, use .NET remoting to communicate between the two managed processes.
Josh
|
|
|
|
|
Hi Josh, thanks for the reply!
What I´m trying to do is read a TreeView(Folder Browser Dialog) from another program.
By reading each item´s text I can select a especific Folder.
I noticed that usual codes did not catch anything from outside my program. For instance:
SubString Text = new SubString(255);
tvItem.pszText = Text;
SendMessage(TreeHandle, TVM_GETITEM, 0, ref tvItem);
This code works perfectly if the treeview is in your application, but SendMessage returns only false if the treeview is in another application(process).
Thank you
|
|
|
|
|
I have seen tabstrip Control Visual Studio Style 2005.
Can anyone tell me how i can get tabstripControl with tabs on downside.
|
|
|
|
|
SravanKrishna wrote: Can anyone tell me how i can get tabstripControl with tabs on downside
tabControl1.Alignment = TabAlignment.Bottom;
_____________________________
Success is not something to wait for, its something to work for.
|
|
|
|
|
|
Hi,
Can any body tell me please how can i use multi column dropdown box against a column in datagrid view. It means when i click on the button displayed on the right side of the column, then that multi column drop down be displayed.
Waiting for reply....
Regrads,
Shahid
Ever Respect the elders
|
|
|
|
|
Can someone point me in the right direction? I would like to have a button on a ToolStrip that drops down a single ToolStripMenuItem that has a TracBar instead of a standard text link. Is this possible or would this need to be done completely from scratch.
|
|
|
|