|
AussieLew wrote: Thanks
You're welcome
AussieLew wrote: I have been struggling with fully understanding the concept of delegates, so this will prompt me to get a handle on that first.
Work through this article[^], it goes step by step. I wrote it for people exactly in your position.
DaveIf this helped, please vote & accept answer!
Binging is like googling, it just feels dirtier.
Please take your VB.NET out of our nice case sensitive forum.(Pete O'Hanlon)
BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)
|
|
|
|
|
Thanks Dave, I can see how using an event is the better way for the child form to cause a change in the parent form. Your article on events etc has helped clarify delegates etc to a great extent. Anything I'm missing I'm sure will "click" soon!
The second part of my question regarded getting the state of the ToolStripMenuItem on the MainForm
from the child form. So for example, if the MainForm ToolStripMenuItemConfirmDeletes item is Checked or not I can take the appropriate action when deleting a record on the child form.
The only way I can see is to have a static variable (say in the startup code Static Class)
bool confirmDeletes that is set whenever the MainForm ToolStripMenuItemConfirmDeletes.Checked property changes. This is accessible from all child forms and the MainForm as eg. Program.confirmDeletes
Can ( and should ) this be done via an event or is using a Static variable acceptable practice?
Lew
|
|
|
|
|
Glad it's helped
Good questions. Static variables/properties are almost never the correct way to go, that normally indicates a bad design. There are 3 methods that can be used. In order of easiest to most complex but also worst to best (as is often the case in programming!)
- Easiest but normally worst
Static properties/variables as you mentioned. If using this, as they will need to be either internal or public I would strongly suggest properties with a private backing field. - Next best
A singleton class instance. See here[^] for a good tutorial by one of the C# gods. - Normally the best, but can be complex to implement depending on class hierachys
Let the parent form decide if the delete should be allowed and perform it. The children simply request the action and pass any required data via an event.
Not everyone would agree, and the 2nd method is very commonly used in production code as it gives better separation than the 3rd which is good OOP practice and therefore often the better solution.
DaveIf this helped, please vote & accept answer!
Binging is like googling, it just feels dirtier.
Please take your VB.NET out of our nice case sensitive forum.(Pete O'Hanlon)
BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)
|
|
|
|
|
Thanks once again!
I will try your option 3 I think.
I have spent a lot of time getting one Form right with data validation and save, edit delete actions etc.
I have a few forms along similar lines to come yet. My next task was to simplify creation of these additional forms.
By having the child form pass the parent form data through events and having the parent form look after some of the actions, like add, edit, delete, save etc this would be some things that would not have to be duplicated in each form.
This is starting to get off topic now but I guess for similar forms with different data sources etc I should set up a form with a constructor that takes the parameters I want to change, plus events etc for form interaction, and use that as a basis for all my similar forms.
Lew
|
|
|
|
|
Yep - you're getting there and thinking along the right lines now!
The next problem you may come across is getting the result of the action request back to the child. There are two good methods for this.
1. You can have a property in your event args that the main (parent) from sets. This is the normally recommended method.
2. Sometimes a more intuitive way is to forget about the standard event signature and create your own delegate that actually returns a result. I've knocked up this quick sample to demonstrate.
using System.Windows.Forms;
namespace CpDelegateSample
{
public partial class FormMain : Form
{
private bool toggle;
public FormMain()
{
InitializeComponent();
toggle = false;
FormSub formSub = new FormSub();
formSub.DeleteRequest += new FormSub.DeleteRequestEventHandler(formSub_DeleteRequest);
formSub.Show();
}
private bool formSub_DeleteRequest(string data)
{
bool result = toggle;
string message = result ? "Allowing" : "Denying";
MessageBox.Show(string.Format("{0} {1}", message, data));
toggle = !toggle;
return result;
}
}
}
using System;
using System.Windows.Forms;
namespace CpDelegateSample
{
public partial class FormSub : Form
{
public delegate bool DeleteRequestEventHandler(string data);
public event DeleteRequestEventHandler DeleteRequest;
public FormSub()
{
InitializeComponent();
Click += new EventHandler(FormSub_Click);
}
void FormSub_Click(object sender, EventArgs e)
{
OnDeleteRequest("ABC");
OnDeleteRequest("DEF");
}
protected virtual void OnDeleteRequest(string data)
{
DeleteRequestEventHandler eh = DeleteRequest;
if (eh != null)
{
bool result = eh(data);
string message = result ? "Allowed" : "Denied";
MessageBox.Show(string.Format("{0} {1}", message, data));
}
}
}
}
DaveIf this helped, please vote & accept answer!
Binging is like googling, it just feels dirtier.
Please take your VB.NET out of our nice case sensitive forum.(Pete O'Hanlon)
BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)
|
|
|
|
|
I remember reading an article that said that List.Sort() was not necessarily reliable, but I cannot remember the context..
Does anyone know the reference or know of a sample (extra credit) that I can look at?
I believe it was someones example of a "better" sorting algorithm...
Thanks in advance.
I'd blame it on the Brain farts.. But let's be honest, it really is more like a Methane factory between my ears some days then it is anything else...
|
|
|
|
|
MSDN says List.Sort uses Array.Sort which is a QuickSort implementation.
unreliable? if it does not sort correctly or in a finite time, it is not an algorithm and not worthy to be part of .NET
unstable? correct (confirmed by http://en.wikipedia.org/wiki/Quicksort[^]). I hope you know what it means.
|
|
|
|
|
Learn something new every day.
BTW, 10^6 seconds is a finite amount. O(n)=n^2 can be scary on large sets.
|
|
|
|
|
Ennis Ray Lynch, Jr. wrote: Learn something new every day.
Same here. I've used the List.Sort() method for years but I've never had any trouble with it. Maybe because I only use List<> for small collections only.
The mind is like a parachute. It doesn’t work unless it’s open.
|
|
|
|
|
Do you have an alternative that you use?
The mind is like a parachute. It doesn’t work unless it’s open.
|
|
|
|
|
Most of the time I don't collect millions of objects, and I use the built-in Sort method. When it is really important, I apply special data structures and keep the "collection" sorted while building it up. Think of a list of lists, so items can be added to the right sub-list straight away.
I trust others will suggest you keep huge amounts of data in a database and rely on its sorting capabilities.
|
|
|
|
|
As you've been told, the sort method isn't really suitable on large data sets. It's important to understand that this is really the wrong place to apply sorting on large data sets - assuming it's coming from a database then the best way to do this is to retrieve the data already sorted and then fill the list.
"WPF has many lovers. It's a veritable porn star!" - Josh Smith As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.
My blog | My articles | MoXAML PowerToys | Onyx
|
|
|
|
|
How do I format Column when a Gridview loads?
Details:
I have a grid named : SubcategoryGrid
the grid is binded to a data binding source.
there is a column in that grid(double type), I need to apply a simple conversion formula after the data binding completes
what gridview argument do I use? or how would I go on about this?
|
|
|
|
|
Hi,
have a look at the CellFormatting event. You could watch the value (e.Value) to be displayed and:
1. modify it,
2. or apply a special formatting (dgv.Columns[COL].DefaultCellStyle.Format="#,###";),
3. or set a special backcolor (e.CellStyle.BackColor=Color.Yellow; however this does not work for empty cells!).
I have used some of the above in my CP Vanity[^] article.
|
|
|
|
|
Thanks,
this is what I have:
Class:
private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
}
What args do I use in designer??
I tried this event to trigger cellformating:
this.SubcategoryGrid.DataBindings += ........
|
|
|
|
|
AFAIK there are two distinct mechanisms, one to provide the data (databinding), one to display the data (formatting).
The binding is whatever you want it to be.
The formatting will fire the CellFormatting event if you wire it up, which you can do by double-clicking the event in the events list, or by adding a dataGridView1.CellFormatting+=dataGridView1_CellFormatting; statement in the form's constructor. As you already have the outline, you probably have done the former already.
Now start manipulating the current cell inside your event handler, any way you want (You did not specify what kind of "simple conversion formula" you want).
|
|
|
|
|
Cellformating worked.
Thank you!
|
|
|
|
|
Why does it have to happen after the binding?
Is there some reason you can't use DataFormatString[^]?
|
|
|
|
|
That is for a WebUI thingy, isn't it? I believe the OP wants a WinForm with a DataGridView.
|
|
|
|
|
|
T M Gray wrote: Ahh he used the wrong control name
Happens all the time, we all get used to it.
|
|
|
|
|
I'm working on loging into an SMF based message board using a WebClient with a cookie collection. So far I've been able to use existing cookies to connect and download pages as needed, however I have to hard code the cookies to do it. Obviously not a good option.
The problem I'm running in to is that in order to have the server generate credentials I have to give it a log in name and a hashed password. The forum login generates them using sha1 hashing with this code:
<br />
doForm.hash_passwrd.value = hex_sha1(hex_sha1(doForm.user.value.php_to8bit().php_strtolower() + doForm.passwrd.value.php_to8bit()) + cur_session_id);<br />
I've been trying to use
<br />
private void btnLogin_Click(object sender, EventArgs e)<br />
{<br />
String sName = "test";<br />
String sPassword = "login";<br />
String sSessionID = "3d847dffa233343cc5065a82b73d566e";<br />
<br />
SHA1 sha = new SHA1CryptoServiceProvider();<br />
byte[] sResult = sha.ComputeHash(StrToByteArray(sName + sPassword));<br />
sResult = sha.ComputeHash(StrToByteArray(ByteArrayToStr(sResult) + sSessionID));<br />
}<br />
<br />
public static byte[] StrToByteArray(string str)<br />
{<br />
return Encoding.UTF8.GetBytes(str);
}<br />
<br />
public static string ByteArrayToStr(byte[] bytes)<br />
{<br />
return BitConverter.ToString(bytes).Replace("-", "").ToLower();<br />
}<br />
<br />
To generate the same hash as the php version...however it's obviously failing. Somewhere in there I'm missing some encoding or particular formatting that I don't know about. Can anyone point me in the right direction here?
EDIT:
<br />
String sName = "test";<br />
String sPassword = "login";<br />
String sSessionID = "8000e537c2a7a31547ffa779fab7a1e2";<br />
String sTemp;<br />
<br />
SHA1CryptoServiceProvider sha = new SHA1CryptoServiceProvider();<br />
sTemp = BitConverter.ToString(sha.ComputeHash(Encoding.UTF8.GetBytes(sName + sPassword))).Replace("-", "").ToLower();<br />
textBox2.Text = BitConverter.ToString(sha.ComputeHash(Encoding.UTF8.GetBytes(sTemp + sSessionID))).Replace("-", "").ToLower();<br />
After beating my head against a wall long enough I was able to come up with this, and it does spit out the exact same hash as the existing php code. This should allow anyone to generate a hash for logging into most SMF powered message boards (They seem to have a niche market in games and mods on a global scale.)
I was a bit surprised to notice codeproject itself doesn't actually hash passwords, it sends them in clear text.
modified on Thursday, July 15, 2010 7:12 AM
|
|
|
|
|
Maybe it should be
byte[] sResult = sha.ComputeHash(StrToByteArray(sName + sPassword));
byte[] sSessionResult =sha.ComputeHash(StrToByteArray(sSessionID));
byte[] returnResult = bew byte[sResult.length + sSessionResult.length];
Array.Copy(sResult, returnResult , 0, sResult.length);
Array.Copy(sSessionResult, returnResult , sResult.length, sSessionResult.length);
sResult = returnResult ;
Fix the compile errors because I just typed this in but I don't think your .NET code matches the PHP code.
|
|
|
|
|
I know the basics of documenting my code for intellisense but I have had alot of trouble finding a good tutorial that shows where the info will be displayed etc.
If anyone knows of a link that would be great.
I could probably find this myself if I knew what MS actually called documenting in this way.
I see things in the framework displaying in intellisense the way that I want but I have had trouble figuring out how they did it.
Thanks again for everyone's help.
Humble Programmer
|
|
|
|
|
Delimiters for Documentation
|
|
|
|