JerryShaw 46 Posting Pro in Training

You will be wrapping the code that creates the database anyway, so just supply good error messaging and go with the assumption. IOW, why add additional code when SQL is going to do those checks for you anyway regardless of your pre-checks.
JMO

JerryShaw 46 Posting Pro in Training

Setting the Enable property of the grid will prevent the user from moving to any subsquent rows.

You may have to manually prevent them from selecting that row by trapping the row in the Select event. Then setting the CurrentCell to the next selectable row. This could get messy because they could use the keyboard or the mouse. You may have to monitor the last Up/Down key used for the grid to know which direction they were going.

Another option maybe to just set all of the cells for the invalid row(s) to ReadOnly before you give them control of the grid. If you do that, even if they select the row, they can not do anything with it.

In any case, you should use the CellFormating event handler to indicate this is not a selectable cell. You can even set the colors to give them the illusion that it is not selectable:

private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
    if (e.RowIndex == 3) // some condition meaning not editable
    {
e.CellStyle.BackColor = Color.White;
e.CellStyle.ForeColor = Color.Black;
e.CellStyle.SelectionBackColor = Color.White;
e.CellStyle.SelectionForeColor = Color.Black;
     }
}

If you want to go the messy way (and this is just a start), Give youself a key var to track with, format the cell to make them think they can not select it, and monitor mouse and key strokes. Finally move the selection when they attempt to select a row you do not want them to.

private Keys _lastKey …
JerryShaw 46 Posting Pro in Training

I think you are stuck with Invoke because that is how C# moves the object pointer into the memory stack of the thread that wants to use it.
A little trick on sending the event to something that does not know how to check for InvokeRequired is to replace sender with null, and check that when it hits the handler. Replace sender in the delegate with this, or some non null value so it knows not to re-throw the invoke.

Good Luck

Thanks jerry, but calling the event from the 2nd thread always fails in my code. but I guess its because I haven't disabled the cross thread warnings.

I really don't like having to check if an invoke is required in the event handler on the form, I know an Invoke will always be required because that events exists in my code for the sole reason of threading. But I don't know how to get around it.

as I posted above, I did find a way to just run the methods asynchronously easy returning the data. but I still have the problem of having to invoke the response data in order to use it and I wish there was a way around it.

JerryShaw 46 Posting Pro in Training

If the receivers of the event absolutely must have the information back into thier own thread (like a Windows App sometimes does) then you would handle the invoke for arguments in those receiving threads.
Move your delegate out into the name space so that receivers outside of this class can use it. Really your choice, they can use fully qualified naming to get to it as well.

When the thread is ready to push the data into the event, then check to see if it is assigned, and then call it.

The receiver needs to check to see if invoke is required. Your Something class may itself be called from another thread, so to be safe, let the receivers deal with it.
(see more below this code snip)

using System.Threading;

namespace WindowsFormsApplication1
{
    public delegate void onTimelineHandler(object sender, TimelineArgs e);
    class SomeClass
    {
        public SomeClass() { }
        public event onTimelineHandler OnTimelineRecieved;

        public void TimelineAsyncStart(string url)
        {
            Thread myAsyncer = new Thread(new ParameterizedThreadStart(doTimelineAsync));
            string[] objar = new string[] { url, "username", "password" };
            myAsyncer.Start(objar);
        }

        private void doTimelineAsync(object objar)
        {
            string[] sa2 = (string[])objar;
            string url = sa2[0];
            string username = sa2[1];
            string password = sa2[2];
            object myobject = "411"; // just something to play with
            //some stuff happens here
            if( OnTimelineRecieved != null )
            {
                TimelineArgs targs = new TimelineArgs(myobject);
                OnTimelineRecieved(null, targs);
            }
        }
    }

    public class TimelineArgs
    {
        public object Something = null;
        public TimelineArgs(object something)
        {
            Something = something;
        }
    }

}

If …

JerryShaw 46 Posting Pro in Training

I changed your code so that you can actually click on the other buttons.

public partial class Form1 : Form
    {
        private int controlnum = 0;
        public Form1()
        {
            InitializeComponent();
        }
        private void button1_Click(object sender, EventArgs e)
        {
            Button homebtn = new Button(); 
            this.panel1.Controls.Add(homebtn);
            homebtn.Text = "New Button" + controlnum.ToString();
            homebtn.Location = new Point( 20, controlnum * 23); 
            homebtn.Size = new System.Drawing.Size(175, 23); 
            homebtn.Name = "Control" + controlnum.ToString(); 
            controlnum = controlnum + 1; 
            homebtn.Click += new System.EventHandler(this.SelectEditableControl); 
        }
        public void SelectEditableControl(object sender, EventArgs e)
        {
            propertyGrid1.SelectedObject = sender;
            propertyGrid1.Refresh();
        }
    }

// Jerry

JerryShaw 46 Posting Pro in Training

DataRow[] rows = yourTable.Select(string.Format("ID='{0}'",cbIDs.Text));

yourLabel.Text = (string)rows[0]["Name"];

JerryShaw 46 Posting Pro in Training

Maybe posting the rest of the code (or entire project) will help. The adapter.table is a bit of a mystery.
The acceptchanges is not really needed until later after the rows have all been added. I think the use of the adapter object in the for loop may be at the root of the problem, but until it is more obvious as to what that object is... it is just an assumption.

JerryShaw 46 Posting Pro in Training

Place an Applicaiton.DoEvents(); inside of the loop so that the main thread has a chance to service its message queue and this should allow your label to update.

// Jerry

JerryShaw 46 Posting Pro in Training

Make sure your DateTime value is enclosed in single quotes.

You might find it easier (to read and build) if you assemble the string using the string.Format() method.

SqlConnection conn = new SqlConnection();
SqlDateTime sTime = new SqlDateTime(DateTime.Now);
SqlCommand command = new SqlCommand(
string.Format("INSERT INTO Sensors VALUES ('{0}','{1}',{2},'{3}' )"
                    , sensors[i].getName()
                    , sensors[i].getType()
                    , sensors[i].getVal()
                    , sTime.Value
                    )
                , conn
                );
command.ExecuteNonQuery();
JerryShaw 46 Posting Pro in Training

I don't think it is a wrong thing to say at all.

LinkedList<T> is a generic replacement for the old style coded Linked List.

JerryShaw 46 Posting Pro in Training

Maybe this link wil help you understand linked lists.

http://www.c-sharpcorner.com/UploadFile/jeradus/UsingLinkedListInCS11102005005525AM/UsingLinkedListInCS.aspx

Too bad they are still teaching these prehistoric methods.
Since Generics were introduced, link lists are pretty much useless in the real world.

// Jerry

JerryShaw 46 Posting Pro in Training

Simple... Just set e.Handled to true
When e.Handled is set to true, then the keypress event stops there, otherwise it is passed up the chain to the TextBox.
// Jerry

JerryShaw 46 Posting Pro in Training

Please mark it as solved, only you can do that.

JerryShaw 46 Posting Pro in Training

ASP or WinForm ?
I can help if it is a Window Form...

JerryShaw 46 Posting Pro in Training

Instead of using a private bool variable, use a private variable for Form2, then you have some options...

public partial class Form1 : Form
    {
        private Form2 _form2 = null;
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            button1.Enabled = false;
            _form2 = new Form2();
            _form2.FormClosed += new FormClosedEventHandler(_form2_FormClosed);
            _form2.Show();
        }

        private void _form2_FormClosed(object sender, FormClosedEventArgs e)
        {
            _form2.Dispose();
            _form2 = null;
            button1.Enabled = true;
        }
    }

Simple, just let the Form2.FormClosed event take care of telling Form1 that it has closed, and that takes care of the _form2 var, and the button.

// Jerry

JerryShaw 46 Posting Pro in Training

Not exactly sure what you are asking for, but it is just a string, so you can concat the other textbox values into a single label using the (+) operator.

lblResult.Text = txtName.Text + " " + nextTxtName.Text + " "; // and so on...

If this is NOT what you are trying to do then provide a sample of what you want it to look like.


// Jerry

JerryShaw 46 Posting Pro in Training

:)
You need to use the row not rows[0]

foreach (DataRow row in rows)
                {
                    Console.Write("{0} ",  row["ID"]; // rows[0]["ID"]);
                    Console.Write("{0} ", row["FIRST"]; //rows[0]["FIRST"]);
                    Console.Write("{0} ", row["AGE"]; //rows[0]["AGE"]);
                    Console.WriteLine();
                }
JerryShaw 46 Posting Pro in Training

The rows array contains all rows where column [First] = 'Lance' so all you need to do is iterate through the array of rows.

DataRow[] rows = table.Select("[First]='Lance'");
foreach(DataRow row in rows)
{
      Console.Write("{0} ", row["ID"]);
      Console.Write("{0} ", row["FIRST"]);
      Console.Write("{0} ", row["AGE"]);
      Console.WriteLine();
}

BTW, there is a second parameter for the select method that allows you to set the order the rows are returned in.

// Jerry

JerryShaw 46 Posting Pro in Training

To use the select, try this:

DataRow[] rows = table.Select("[First]='Lance'");
if(rows.Length > 0)
{
      Console.Write("{0} ", rows[0]["ID"]);
      Console.Write("{0} ", rows[0]["FIRST"]);
      Console.Write("{0} ", row[0]["AGE"]);
      Console.WriteLine();
}

// Jerry

JerryShaw 46 Posting Pro in Training

I have a project I downloaded from Code Project called fun with animation. It has 100 animations running on a background image with no flicker.
(animation.zip) is attached.
I think the key to it is under the InitializeComponents() method in the form constructor it has the following code. Maybe you can find what you need in the attached project. I use the concept in a mapping program and it works fine.

SetStyle(	ControlStyles.AllPaintingInWmPaint |
	ControlStyles.DoubleBuffer |
	ControlStyles.ResizeRedraw |
	ControlStyles.UserPaint,
	true);
JerryShaw 46 Posting Pro in Training

Are you using double buffering ?

JerryShaw 46 Posting Pro in Training

Welcome, its nice to be able to help and work on something other than the complex code I typically deal with everyday in my job.

Yes you can have multiple forms and navigate between them using buttons, etc.

Have fun,
// Jerry

JooClops commented: Can't stop thanking You +1
JerryShaw 46 Posting Pro in Training

MS Visual Studio

JerryShaw 46 Posting Pro in Training

Okay,
You wanted lines... You got Lines :)
Add this Paint event handler to your panel's Paint event.

private void panel_Paint(object sender, PaintEventArgs e)
        {
            int rowLineOffset = panel.Height / 3;
            int colLineOffset = panel.Width / 3;
            Pen pen = new Pen(Brushes.Red);
            pen.Width = 3;
            pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
            for (int i = 1; i < 3; i++)
            {
                e.Graphics.DrawLine(pen, new Point(3, i * rowLineOffset - i * 2), new Point(panel.Width -3, i * rowLineOffset - i * 2));
                e.Graphics.DrawLine(pen, new Point(i * colLineOffset - i * 2, 3), new Point(i * colLineOffset - i * 2, panel.Height -3));
            }
            pen.Dispose();
        }
JerryShaw 46 Posting Pro in Training

I am thinking that isMkvTest is null.
You can test for that by changing:

if (isMkvTest.Trim().Length != 0)

change to:

if( !string.IsNullOrEmpty( isMkvTest ) )

As for using the Visual Studio Debugger. Simple... Left click the margin to the left of the code you want as a break point. You should get a red ball to appear, and the text will be back-lit with red. Press the F5 key to start debugging. Next, when it gets to that line, step into it with F11, or through it with F10. You can hover the mouse of an object to get its value, and you will see lots of other options once you start using the debugging tools.
If you do not have Visual Studio, then get the free express version from MSDN, and use it to debug your program.

// Jerry

JerryShaw 46 Posting Pro in Training

lbl.ForeColor = lbl.AllowDrop ? Color.Blue : Color.Black;
That is what we call short cut code. It comes from the old days when we had the IIF statement. your assumption is correct, the first segment must equate to a boolean expression, the second is the value to deliver when the boolean is true. The third segment is the else value.

Passes... This is a triggered kill point. If the validity checks fail after nine attempts, then just leave the target blank and move on. Without this, you could find yourself in an endless loop, or atleast a very long running loop.
Most of the time, the PassChecks() will return true, and it only goes into the loop when a conflict is detected.
Anytime you have a loop construct ALWAYS give your code a way of timing out or escaping the loop. If it came out of the loop and the trigger point was reached, then blank the text and array for this position.

How the code works is that if the randomizer gave us a value in range, we start testing (makes sure that the value being placed will not violate Soduko rules off the bat, the job of PassChecks). If it fails the test, then we give it another number to try. Stop trying after 9 passes.

BTW, to increase or decrease the difficulty level of the game, you can just set the rd.Next in the line above this section (currently 18).
This …

JerryShaw 46 Posting Pro in Training

Yes Try..Catch and Try..Finally are basic code blocks available in all projects for c#.

I will find another way to send you the zip file. I made a few changes so that the numbers are centered in the panel cell, and a randomizer populates some of the cells. A future option to consider is to allow the user to select the difficulty level so that you can control the number of values the computer places on the screen.

I think you will find it interesting.

// Jerry

JerryShaw 46 Posting Pro in Training

Have you used debug to trace to the actual line that crashes ?
I would venture to guess that it is at the line:
string isMkv = isMkvTest.Substring(isMkvTest.LastIndexOf(':'));

There is no guarantee that isMkvTest is instantiated.
Just because you are asking it to readline, does not mean that there is a non null value returned. Anyway, best bet is to set a break point at the top of the readStreams method, and step to the problem... Something is null that should not be.

// Jerry

JerryShaw 46 Posting Pro in Training

Okay

Got the project.
Below is the Clear button event handler.
An explanation follows.

private void btnclr_Click(object sender, EventArgs e)
        {
            Label lbl;
            int num;
            string tag;
            try
            {
                Enabled = false;
                this.Cursor = Cursors.WaitCursor;
                panel.SuspendLayout();
                foreach (Control cntrl in panel.Controls)
                {
                    lbl = cntrl as Label;
                    if (lbl != null)
                    {
                        tag = lbl.Tag as string;
                        num = 1 + Convert.ToInt32(tag.Split('|')[1]);
                        lbl.Text = num.ToString();
                    }
                }
                for (int i = 0; i < 9; i++)
                    for (int j = 0; j < 9; j++)
                        _mat[i, j] = i;
            }
            finally
            {
                this.Cursor = Cursors.Default;
                Enabled = true;
                panel.ResumeLayout(true);
            }
        }

First it declares a few working variables.
Next we place the code into a Try...finally, for a number of reasons, but primarily because we are going to set the cursor to a waitCursor ( because working with longer iterations should do this).
And we are going to Disable the form by setting the Enable to false (lock the user out so they can not mess with what we are doing).
Disable the layout panel so that it will not flicker and slow us down with its internal rendering.
and finally because we want to make sure all things will be turned back on no matter what happens in the code.

Inside of the working code, we iterate through all of the labels of interest within the layout panel. We get their j value from their Tag, add one to it …

JooClops commented: The most Awesome guy in the world<<<< +1
JerryShaw 46 Posting Pro in Training

JooClops,

Hope you live in a safe area of Israel.

It appears that you just copy paste'd the console methods into the Check button handler. That won't work.

You have three methods that are used to check faulty entries:
Col, Row, Square
and a single method used by each for the actual validation.
Rewrite them as individual methods (IOW not inside the Check button), and call them accordingly.

So, lets start with the isvalid method: Create it as its own method (not embedded within another method.)

private bool IsValid(int[] ar)
        {
            for (int i = 0; i < ar.Length; i++)
            {
                for (int j = 0; j < ar.Length; j++)
                    if ((j != i) && (ar[i] == ar[j]))
                        return false;
            } 
            return true;
        }

Changed to a private (non static) method using Camel-Case naming convention.
Modified to account for arrays less than 9 in length.

Next we need to add the row check method:

private bool CheckRow(int rownum)
        {
            int[] ar = new int[9];
            for (int j = 0; j < _mat.GetLength(1); j++)
                ar[j] = _mat[rownum, j];
            return IsValid(ar);
        }

Changed to a private (non static) method using a new Name.
Using the private _mat instead of passing it as a variable.
Return whatever IsValid gives you instead of evaluating it.

The remaining two methods are similar in changes:

private bool CheckCol(int colnum)
        {
            int[] ar = new int[9];
            for (int i = 0; i …
JerryShaw 46 Posting Pro in Training

You can set the Modifier property of the DataGridView in the second dialog box to public. Then if the dialog result is Ok, then you can access the selected row of the DataGridView from your first dialog.

Hope this helps
// Jerry

JerryShaw 46 Posting Pro in Training

ddanbe,

That line occurs because of the flat style being standard. During the click, the component base uses the drop effect which drops the top border into view.
Avoid that in the onPaint (or elsewhere) so that it does not exhibit the drop on click effect.

base.FlatStyle = FlatStyle.Flat;

// Jerry

JerryShaw 46 Posting Pro in Training

You need to move the declaration to the top of the class.

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
      
       // Private class declarations
       [B]private int[,] _mat new int[9, 9];[/B]

        public Form1()
        {
            InitializeComponent();
        }
...

When declared inside the class but outside of any methods it is a class variable. Any method within the class can access it.
Use public variables when classes outside of this class need to have access to it. You do not have any of those yet.

Also something to know is that any method declared inside of a method is only accessable from within the method it is declared. Also, the instance will die the moment the method exits.

BTW, what country are you residing ? just curious as to the time difference. I am in Idaho USA

// Jerry

JerryShaw 46 Posting Pro in Training

Okay,

No problem on the newB questions, everyone is a NewB at some point.

Does not look like you need to convert the text to integer, the (i+1) that you are assigning to the Text, is already an integer, so just set the array value to that value: mat[i,j] = i +1;

"1.once the label is changed ,how can i change it in tthe Matrix , i need to get it's place,which i can't think of a way to do it :"
For this, I will show you another little trick called Tag.
All components (well 99% of them) have a Tag property of type object. You can store anything you want in there. For this (and to keep it simple) lets place the address in this property as a string:

lbl.Tag = string.Format("{0}|{1}",i,j);
// use of the pipe character as a delimiter is just my choice, you can use any charcter.

Now to use this you will need to split the address back out and convert them back to Integer.

private void label1_DragDrop(object sender, DragEventArgs e)
        {
            Label target = sender as Label;
            Button btn = e.Data.GetData(typeof(Button)) as Button;
            target.Text = btn.Text;
            string address = (string)target.Tag;
            int i = Convert.Int32(address.Split('|')[0]);
            int j = Convert.Int32(address.Split('|')[1]);
            mat[i,j] = Convert.Int32(target.Text);
        }

BTW: you will learn this later, but code formatting will help your code stand out. For example all class private variables should start with an underscore (if you wish to follow the Microsoft coding …

Antenka commented: Great job :) Plenty of work you did!!! +2
JerryShaw 46 Posting Pro in Training

Looks like you are making progress.

You can create a single event handler for the label object to do this, however you could just as easily tag the event into the Drag Drop onto the label.

If you want to allow the user to actually type values into the object, you should replace the label component(s) with a TextBox component.

To turn a string from the label or TextBox (any string) into an integer you can use the parsing methods of that type.

int i;
            string someValue = "123";
            if (Int32.TryParse(someValue, out i))
            {
                // i now = 123
            }
            else
                MessageBox.Show("Invalid value, must be numeric");

To control the size of your labels, you should set the AutoSize property to false.

// Jerry

JerryShaw 46 Posting Pro in Training

The container should be the table (panel) not "this".
So instead of creating the labels and adding them to this

this.Controls.Add(lbl);

use

panel1.Controls.Add(lbl);

// Jerry

ddanbe commented: Nice job! +4
JerryShaw 46 Posting Pro in Training

Which "table" component are you using ?
Is this a DataGridView ? ListBox ? or something else ?

// Jerry

JerryShaw 46 Posting Pro in Training

The Label was purely to help you experience and play with Drag & Drop (concept stuff).
Not being a Sudoko player myself, I am not all that familiar with the game board.
If I were building it, I would use graphical design methods, but those are (for now) a bit more advanced than you should tackle.

To generate 81 labels, you can create and add them at runtime within a loop. You need to perform a few steps for this.
Primarily you will create them in a for..loop, and add them to the Main form, or a panel (or some other container).

Here is a quick and dirty way, you will have to manage your own location and size values:

To add this to your code, select the form, and assign an event handler for the Load event. In the code snipet below, I just create 4 new labels, and position them on the form, add them to the container (in this case the form itself).
Assign the event handler like you did in the Label component as you did earlier.

private void Form1_Load(object sender, EventArgs e)
        {
            for (int i = 0; i < 4; i++)
            {
                Label lbl = new Label();
                lbl.Text = i.ToString();
                lbl.Location = new Point( 30, 70 + (i * 20) );
                lbl.Size = new Size(label1.Width, label1.Height);
                lbl.DragDrop += label1_DragDrop;
                lbl.DragOver += label1_DragOver;
                lbl.AllowDrop = true;
                this.Controls.Add(lbl);
            }
        }

This being done, now you need to change …

JerryShaw 46 Posting Pro in Training

Good, I am glad you have decided not to cheat.
On the otherhand, reviewing someones code is the way most everyone learns.
Okay, as for the buttons, I assume you are using Visual Studio 2008 Express, if not get an IDE, SharpDev, Mono or VS2008e (all are free).

Here is some code to get you started:
Create a Windows application, and spread out the form so it can fit the 9 buttons along the bottom of the form.

For now, I dragged a Label component from the toolbox onto the center of the screen. This is the component we will drop the buttons onto. You will want to use your own target component(s) once you understand the concept. Set the AllowDrop property in the property editor of the label to true (means yes, I want this component to allow things to be dropped on it).

Select the first button (button1 in this case), and in the property editor, select the event (lightening bolt) tab, and find the onMouseMove event handler. Type in buttonMouseMove (or whatever you desire). Press enter and let it create the event handler code. Now go back to the form and select all of the other buttons, and drop down the onMouseMove property combobox, and select the buttonMouseMove handler you just created. This ties all of the buttons to the same event handler (just makes it easier than creating and duplicating 9 handlers).

Next you want to force the button …

JerryShaw 46 Posting Pro in Training
JerryShaw 46 Posting Pro in Training

I would imagine that you can even find some example Sudoko (or similar games) code on Code Project or elsewhere on the net.

JerryShaw 46 Posting Pro in Training

I don't think you really need to have an array of buttons for this project.
Instead set the table to allow drop that way it will allow you to use the drag drop events on the table.
Then on the Mouse Move event of the buttons, start a drag operation. Let the table handle the drag events, and handle the button that is being dropped on the table.

There are plenty of examples of drag drop on the net, and you should be able to see how to do each of these functions, however if you get in over your head, there are folks here that can help.

// Jerry

JerryShaw 46 Posting Pro in Training

Try using a switch( var.Length ) construct. That should limit you to ten or so case statements.

JerryShaw 46 Posting Pro in Training

Yes, the for--loop is inside the thread method.

JerryShaw 46 Posting Pro in Training

I sugest you take a different tact.

What I typically do for managing thread messages is I create a simple EventArgs class to hold the message information, a Delegate to represent the main thread method that will use the information, and an eventhandler in the main thread that can be assigned to an event in the thread.

So to start, build a simple EventArgs class

public class ProgressEventArgs : EventArgs
    {
        private int _maxValue = 100;
        private int _value = 0;
        private string _text = string.Empty;

        public int MaxValue
        {
            get { return _maxValue; }
        }
        public int Value
        {
            get { return _value; }
        }
        public string Text
        {
            get { return _text; }
        }
        public ProgressEventArgs(string text, int value, int maxValue)
        {
            _text = text;
            _value = value;
            _maxValue = maxValue;
        }
        public override string ToString()
        {
            return _text;
        }
    }

Now create a public delegate. Typically I have a constants.cs file where I create all of my constants, and then outside of the constants class, but in the same name space, I create my delegates like this:

namespace MyNameSpace
{
    public delegate void ProgressEvent(object sender, ProgressEventArgs e);
    public class Constants
   {
   }
}

OR you can just add the delegate to the main form.

Next you want to create the method that will receive the event, and process the information (in the main form)

public void SetProgressEvent(object sender, ProgressEventArgs e)
        {
            if( label1.InvokeRequired )
            {
                ProgressEvent d = new …
JerryShaw 46 Posting Pro in Training

string relPath = System.IO.Path.Combine(Application.StartupPath,"YourFile.xml");

JerryShaw 46 Posting Pro in Training

Are talking about the @quotenum as an Sql Parameter to the stored procedure ?
The stored procedure must declare this as an OUTPUT parameter.
Then you set your SqlParameter Direction so that it also knows it is an OUTPUT type and will store the value in the parameter.Value upon return.

Hope that helps

JerryShaw 46 Posting Pro in Training

Take a look at the DateTimeOffset struct.
Also the TimeZone class

You should be able to use those and then use the DateTime AddHours method to get the new date you are looking for.

//Jerry

JerryShaw 46 Posting Pro in Training

No you have have many connections.
Can you provide your exact connection string that you are using.

// Jerry
Sorry for the delay, I tried sending you a reply hours ago from a different PC, but for whatever reason, it did not show up here.

JerryShaw 46 Posting Pro in Training

Okay, I see you are getting nowhere, so I will give you the code to do this:

private void DoSomething()
        {
            string ConnectionString = "Data Source={0};Initial Catalog={1};Integrated Security=True";

            int estno; 
            if( int.TryParse(startestnoCB.Text,out estno) )
            {
                SqlConnection conn = new SqlConnection( 
                    string.Format(ConnectionString,".//SqlExpress" // Your Sql Server
                    , "EstimateDataSet" // Your SQL Database
                    ));

                SqlCommand cmd = new SqlCommand("EstimateApproval", conn);
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.AddWithValue("@Estno", estno);
                try
                {
                    conn.Open();
                    #if WantSomethingBack
                    DataTable result = new DataTable();
                    SqlDataAdapter adapter = new SqlDataAdapter(cmd);
                    adapter.Fill(result);
                    foreach(DataRow row in result.Rows)
                    {

                    }
                    result.Dispose()
                    #else
                    cmd.ExecuteNonQuery();  // If you do not need a return;
                    #endif
                }
                catch (SqlException err)
                {
                    MessageBox.Show(err.Message);
                }
                finally
                {
                    if(conn.State == ConnectionState.Open)
                        conn.Close();
                    conn.Dispose();
                }
            }
        }