A variable of a structure type is, in essence, a group of variables stuck together with duct tape. A heap object of a structure type (i.e. a "boxed" struct instance) is processed by the runtime as though it were a class object with a variable of that structure type as its only field; any methods which would operate on the structure as a whole operate on that field, while those which would operate on the fields of the structure operate on its sub-fields.
The ability to binding groups of variables together with duct tape is useful if one will be using the variables as a group; almost all cases where one would want to do that, however, would require that the structure be used in at least two places (e.g. a place it's copied from, and a place it's copied to), though there are cases where all the places might be confined to a single function (e.g. one may have a variables prevState and currentState, each containing a few fields, and may want to be able to take a snapshot of all the variables in currentState and later revert all the variables to their earlier values). Structures can be good for that.
I would suggest that it's often good to have very bare-bones structure definitions. If one has a method which reads through a list and computes the minimum and maximum values according to some passed-in IComparer<T>, having a structure:
struct MinMaxResult<T> { public T Minimum, Maximum; }
could make things clearer than having a more complicated data type which wraps its fields in properties and tries to enforce invariants such as Maximim >= Minimum, etc. The fact that MinMaxResult is a structure with exposed fields makes it clear that given the declaration MinMaxResult mmr;, code shouldn't expect mmr.Minimum to have any meaning beyond "the last value written to mmr.Minimum, or default(T) if nothing was written." Everything of interest is going to be in whatever writes to mmr; the more concise definition of MinMaxResult<T>, the less it will distract from what's actually going on.