What you are trying to do is enforce non-optimistic concurrency on the resources you are accessing (in this case, database rows).
Generally, the data models in .NET only support optimistic concurrency (if you are supporting concurrency at all, that is), and most database programming that you see nowadays follows the same trend.
That being said, you should probably look at an optimistic concurrency model, where you have a timestamp of some sort (whether it be a binary value or a date, something that changes with each update to the record) which is compared when you want to perform the update operation.
If the id and the timestamp match, the operation succeeds, otherwise, it informs the user someone else has updated the record and should reload the data and try to update the record again.
It should be noted that this pattern scales much, much better than any non-optimistic patterns.
That being said, if you truly want a non-optimistic pattern, you have to fake it.
As mentioned above, the .NET data provider models do not support non-optimistic concurrency. When a user begins the operation, it would check a field ("locked" or something like that) to see if the record is currently locked. If it is locked, then you don't allow the user to open the form to modify the data. If it is NOT locked, then you allow the user to open the form and modify the data.
There are two important things that you have to do here. The first is to set the "locked" field to true, to indicate that you have a lock.
The second is to make sure you are operating in a transaction when comparing the value and updating the locked field. If you don't, then the possibility of two clients updating the field at the same time exist, which you don't want.
The best way to encapsulate this is to have a stored procedure which takes the id of the record you want to lock.
It then performs an update, like so:
--- Update the table.
update <table> set locked = 1 where id = @id and locked = 0
--- Return the rowcount.
return @@rowcount
It should be noted that the check on the "locked" field is very important, as it allows the @@rowcount value to be either 0 or non-zero (depending on whether or not your ids are unique) which you can evaluate to false in the zero case and true in the non-zero case in your application code.
Then, in your application code, you complete the transaction, and if the value is true, you open the form and allow the user to edit, otherwise, you inform them they have to wait.
When the user is done saving the record, they set the "locked" bit back to zero, again, in a transaction with the other save operations.
The one glaring drawback to this is the fact that if your application crashes after the user has locked the record, it will never become unlocked, and you will have to manually go and remove the "locked" bit.
With transactions and optimistic concurrency, you don't have to worry about any of this, so I would again, strongly urge you to not use the non-optimistic concurrency model.