|
1. You should have probably gone for the database forum; this is more of an SQL question.
2. You should certainly be able to update multiple columns in one query. I just tried this in SQL Server and it worked:
update tablename set column1 = 'value1', column2 = 'value2' where column3 = 'condition'
3. You should never construct SQL like this. Google for "SQL injection".
|
|
|
|
|
Hi,
is there a possibility to clone a DataGridView?
I have a little formated Grid in a form and want to "copy" it to show and edit it in another form.
Cell- und backgroundcolors have to be retained unchanged. Thats why a DatagridView.DataSource solution is not so good.
Form1.CloneMemberWise() did't work. The source grid disapeared;
Thanx for your help.
Christian
from Germany
www.mindronics.de
|
|
|
|
|
Hi,
I am studying for MCTS and there i have a question fro practise purposes. The question is "Create a custom class that can be converted to common value types"?
I have been trying to solve this since 1 week but can not get the soluution of it.
Can any one help me with this answer...
Thanks in advance
Thanks
|
|
|
|
|
Faisal Khatri wrote: The question is "Create a custom class that can be converted to common value types"?
It sounds like the question is talking about Serialisation.
All types, eventually, boil down to some basic types such as int, string, double, bool etc.
For example, a Customer type may consist of an account number, a surname, forename, address (another custom type), etc. Account number could just be an int, while surname and forename are strings.
Serialisation (and its counterpart deserialisation) is the process of taking complex types and representing them in a common way so that they can be transferred to other systems or persisted to a storage medium.
Probably one of the most common ways to serialise stuff is to use XML, which is at its most basic just a big string.
Of course you can come up with your own scheme for serialising a type.
Now, whether this is what your tutor wants, I don't know. If they are careless with their vocabulary then it probably is. If they are very careful with their word usage then no. In .NET a "value type" has a very specific meaning, and a string (although immutable and therefore often confused with a value type) isn't a value type.
Does this help at all? Or does it just raise more questions?
|
|
|
|
|
Hi Guys,
I'm stumped about this.. I have a custom form that creates an instance of another customer form and displays it modally. There are a couple of buttons and events on the modal dialog window. It basically sets properties of the parent form based on user selections.
While I've got everything working just fine. The complaint I have is that the parent window isn't painted quickly enough. In other words, remnants of the modal window remain for a couple of seconds before it goes away entirely. How do I solve such a problem?
Here is a simple version of what I'm doing. Again, the problem I have is the ModalForm instance isn't "closing" fast enough- ie that it kind of fades then blends into the parent form instance.
public partial class ModalForm : Form
{
Button theButton; ...etc.
public ModalForm
{
theButton.Click+= new EventHandler(ClickHandler)
}
public void ClickHandler(object sender, Eventargs e)
{
objParenForm.myProperty = 1;
Dispose();
}
}
public partial class ParentForm : Form
{
ModalForm mForm
public int myProperty;
public void ParentForm_Load(object sender, Eventargs e)
{
mForm = new ModalForm();
mForm.Show(this);
}
}
|
|
|
|
|
Should you not be using ShowDialog for the modal form? Are you using any animations, I have not seen this problem and I use showdialog ALL the time. I suspect there is a setting somewhere that is controlling your form close style or something.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
I'm sorry. Posted that code rather quickly.. you're right, I did use ShowDialog to show the form. No animations, just standard controls.. buttons, listbox.
Any hints as to where I could look to confirm your suspicion?
|
|
|
|
|
hi every one
i add column in datagrid in design time and when set data source with a dataset add new column to datagrid i want to dont add i want to replace to design time
thanks
|
|
|
|
|
i dont understand what you are trying to ask.
do you mean you would like to replace the column of the datagrid on runtime?
Please explain your question.
|
|
|
|
|
|
I want to load small images on the background image and both images is having the same color but my problem is i am not able to make small images as totally transperant i.e. i can see the edges of these small images. so i am loading these images in resources and trying to load but the effect is same. I want to draw these images in a such a way that it should mix up with background image and edges cannot be seen. I used maketransparent API but no desired result. Also I streched the images in order to mix with the background but i can see the edges.
Pls let me know how can we do this.
|
|
|
|
|
set the parent property to the form or other image, should make it blend better?
*complete guess, has 0 idea if it will work or not*
|
|
|
|
|
Hi,
I am just wondering something related to safety:
Is it safe to create Windows forms from separated Threads (System.Threading) ?
The Thread is created from a UserControl (from a click button for example).
The point is that when the thread is started I need to show some "custom forms" (Windows.Forms) that are created inside the thread in order to promp to the user the -OK and -CANCEL options in order to take a desition from there.
The thread is a single thread apartment (STA)
Example:
namespace ThreadTestandForms
{
public partial class FormGUI : UserControl
{
private void button2_Click(object sender, EventArgs e)
{
Thread ThreadSendParts;
ThreadSendParts = new Thread(new ThreadStart(RunsOnThread));
ThreadSendParts.SetApartmentState(ApartmentState.STA);
ThreadSendParts.Priority = ThreadPriority.Highest;
ThreadSendParts.Start();
FrmSentPrtPgres.ShowDialog();
}
private void RunsOnThread()
{
for (int i = 0; i <= 100; i += 10)
{
Thread.Sleep(200);
ShowProgress("My Progress Status", i);
FrmMyMessage MyForm = new FrmMyMessage("Do you want do this or that?");
DialogResult DLRes = MyForm.ShowDialog();
if (DLRes == DialogResult.OK)
{
}
else
{
}
}
ThreadCompleted();
}
}
}
Regards,
modified on Monday, April 13, 2009 6:11 PM
|
|
|
|
|
Threads are for doing work, not for showing UI elements. You can do it, and you might even get away with it under some circumstances, but it is not supported and not supportable as the behavior of these elements is unpredictable in all cases.
|
|
|
|
|
Thanks for your reply Dave,
Actually I am using this thread to copy a lot of files from one computer to another, the problem comes when I need to promp a question to the user during this process,
For example: "this file is very small (or big), do you want to copy it anyway?" -OK or -CANCEL.
In this case the thread would stop and wait for the user to click, OK or CANCEL ... the code that I used above was just to illustrate my question.
Thank you for your time.
|
|
|
|
|
In this case, the actual copy operation would be on a background thread. It would have to notify a component on the UI thread, probably through an event or callback delegate, that this condition exists.
|
|
|
|
|
Yeap, actually I am doing the copy operation in RunsOnThread()
The method ShowProgress internally uses BeginInvoke and InvokeRequired to access the components in the GUI about the progress of the copy file.
e.g. ------------------------------------------------------------------
public void ShowProgress(string msg, int percentDone)
{
if (InvokeRequired)
{
System.EventArgs e = new MyProgressEvents(msg, percentDone);
object[] pList = { this, e };
BeginInvoke(new MyProgressEventsHandler(UpdateProgressBar), pList);
}
else
{
UpdateProgressBar(this, new MyProgressEvents(msg, percentDone));
}
}
private delegate void MyProgressEventsHandler(object sender, MyProgressEvents e);
private void UpdateProgressBar(object sender, MyProgressEvents e)
{
FrmSentPrtPgres.label_MsgContext.Text = e.msg;
FrmSentPrtPgres.progressBar.Value = e.percentDone;
}
-------------------------------------------------------------------------------------
|
|
|
|
|
I have been chasing this bug for three days now and wondered if anybody out there could point me in the right direction.
I have a circular array generated from a structure. We are writing data to this array and found that the second write was overwriting part of the first record. To simplify debugging we have put some test code that changes what is to be written and then does a second write. Here is the code:
class CAN
{
public struct CANTXSTRUCT
{
public int PGN;
public byte DLC;
public byte[] TxData;
}
private const int CANArraySize = 20;
static private int CANFront = 1;
static private int CANRear = 0;
static private CANTXSTRUCT[] arCANTx = new CANTXSTRUCT[CANArraySize + 1];
static public void QueueCANTxMsg(int PGN, byte DLC, byte[]TxData)
{
if ((CANRear + 2) % CANArraySize == CANFront)
{
MessageBox.Show("CAN Tx Array Overflow, Press OK to continue",
"Error Warning", MessageBoxButtons.OK);
return;
}
CANRear = (CANRear + 1) % CANArraySize;
CAN.arCANTx[CANRear].PGN = PGN;
CAN.arCANTx[CANRear].DLC = DLC;
CAN.arCANTx[CANRear].TxData = TxData;
TxData[0] = 0xFF;
CANRear = (CANRear + 1) % CANArraySize;
CAN.arCANTx[CANRear].PGN = PGN;
CAN.arCANTx[CANRear].DLC = DLC;
CAN.arCANTx[CANRear].TxData = TxData;
}
When the failing line is executed it overwrites the first written CAN.arCANTx[CANRear].TxData value. The CANRear value appears to beworking correctly and I think the problem is associated with the byte array copy implicit in the failing line.
Can anyone see what I am doing wrong? Cheers Bruce
|
|
|
|
|
Hi Bruce,
having fun with a CAN bus? been there using C, not C#.
Here are some remarks:
0. Not sure why you have one extra element in the CANTXSTRUCT array.
1. I am not sure why you want to store a message twice. Seems very odd.
2. your QueueCANTxMsg() method is queueing two messages, however they share all the data, which is fine for value types (PGN, DLC) but not for reference types: the TxData you are storing twice is the same array twice, so changing a byte in it (TxData[0] = 0xFF; ) will reflect in both copies, since you only are storing a reference.
3. your overflow test is not correct, if (CANRear + 1) % CANArraySize == CANFront you are also overflowing the circular buffer (adding two can make you look OVER the front node).
4. if you plan on using QueueCANTxMsg() from more than one thread (say a regular thread and some asynchronous datareceived handler) then you should lock otherwise the pointer adjustment (CANRear = (CANRear + 1) % CANArraySize; ) could be interrupted resulting in using the same location twice.
|
|
|
|
|
Hi Luc,
The circular array handling in point 0 and 3 is an old standard technique I have used for years that runs great but requires an unused buffer address.
The second message in the code sample was just test code so I could see the problem without leaving the function.
Point 4 - Only ever calling from 1 thread but your suggestion is well taken.
I am sure you are on the right lines with point 2 but how do I change this to store real individual values in a real circular array?
Thanks for your input. After 3 days it sure is appreciated.
Cheers, Bruce
|
|
|
|
|
Hi Bruce,
Bruce Coward wrote: an unused buffer address
I agree a simple circular buffer wastes one slot, since you must discriminate the empty case (getptr=putptr) and the full case (getptr=putptr), which is easiest by never filling the buffer completely, so there will always be an empty slot, however it moves around: the pointer arithmetic should use the actual array size, whatever extra elements get allocated are simply wasted.
So if you do array[DIM+1} then you should also do PTR=(PTR+1)%(DIM+1) otherwise PTR will never point to ARRAY[DIM].
Bruce Coward wrote: how do I change this to store real individual values
You must make sure the data either resides in a different array each time (so the caller must provide a new array each time), or you must copy the data into an array you allocate yourself. I prefer the latter, and I would try and allocate all the buffers just once (when intializing the circular buffer) and copy the data in them.
Depending on how you actually obtain the data from CAN, there is or isn't a way of saving one copy operation:
- split the queueMessage method in two parts;
- use first part to obtain the next array (the array preallocated for the next slot in the circular buffer) but don't advance the put pointer
- call "driver" to fill that buffer
- call remaining part of queueMessage to stuff value types, and advance slot pointer which makes it readable for the CAN message consumer.
|
|
|
|
|
The line you pointed out does not copy the array. Array assignments never perform an implicit copy, even in structures. As a side note, if you could do sizeof(CANTXSTRUCT), it would be the same regardless of the size of TxData because the structure only holds a reference to the array not the actual bytes.
The problem is that you are assigning CAN.arCANTx[CANRear].TxData variable to hold a reference to the parameter TxData. If you check the value after the first line of "Test Code", you should be seeing overwrite because doing (parameter)TxData[4] = 0x87 is equivalent to CAN.arCANTx[CANRear].TxData[4] = 0x87 since both arrays reference the same bytes. If you want to copy the data, you will need to create a new array to assign to the structure and call Array.Copy yourself.
Also, I would suggest using the Queue<t> class instead of making your own circular array.
|
|
|
|
|
Gideon Engelberth wrote: I would suggest using the Queue class instead of making your own circular array.
I beg to differ. There may be very good reasons to have a pre-allocated data structure to handle all traffic, since it avoids a lot of object creation and destruction, and it provides an upper bound to the amount of data that can be stored.
In fact I did some similar CAN drivers before, on embedded systems which did not have really dynamic memory, but even if they had I probably would have gone with the circular buffer anyway. BTW: when designed carefully one can forego all locking, which is quite useful when part of the code runs in an interrupt service routine.
|
|
|
|
|
Hi Bruce,
I find a circular buffer much easier to understand and manage with a control variable storing the current data amount. With this additional piece of information in place the buffer full/empty state is obvious and the empty slot can be discarded.
Not tested but something like this:
class CAN {
public struct CANTXSTRUCT {
public int PGN;
public byte DLC;
public byte[] TxData;
}
private const int CANArraySize = 20;
static private int CANFront = 0;
static private int CANRear = 0;
static private int currentCount = 0;
static private CANTXSTRUCT[] arCANTx = new CANTXSTRUCT[CANArraySize];
static public void QueueCANTxMsg(int PGN, byte DLC, byte[] TxData) {
if (currentCount < arCANTx.Length) {
CANRear = (CANRear + 1) % arCANTx.Length;
currentCount++;
} else {
}
}
static public void RemoveMsg() {
if (currentCount > 0) {
CANFront = (CANFront + 1) % arCANTx.Length;
currentCount--;
} else {
}
}
}
Alan.
|
|
|
|
|
Hi Alan,
while I agree on two pointers plus amount being easier to understand, the nice thing about a circular buffer with only two pointers (and an empty slot) is that you don't need to lock if there is only one producer and one consumer: each pointer will have one writer and two readers, so when writing is atomic all is fine (when implemented carefully that is). Adding a currentCount makes the state redundant and prohibits atomic operations.
Remember, in a typical application, the consumer would be the app itself, the producer of incoming messages would be the CAN driver, which operates from an interrupt service routine (an asynchronous handler in .NET speak).
|
|
|
|
|