>> ... mightn't it be better to get them all into one
dataset and set up a DataRelation between them? <<
This is exactly what I needed to do. I'm still not used to this concept of
multiple tables residing in the same DataSet. ( I come from an environment
where DataSet and table were synonymous. )
Here's the idea. Tasks is a table with a Foreign Key constraint in
SubCategory. Since the user can only include items from the finite set of
choices within the referenced table, I am providing a ComboBox from which
they are constrained to make their choice. Furthermore, the items in that
ComboBox are constrained by the choice made in another field, also controled
by a ComboBox.
I've placed a TextBox on the form and bound its Text property to
"Tasks.SubCategory" for the purposes of debugging this situation.
I've brought all of the tables within the same DataSet and created three
relationships (1 : m in each case): Task : Activities, Category :
SubCategory, and Category : Task. The dropdown behavior now results in the
underlying table receiving the user's selection. It did require one line of
code in the
SelectionChangeCommitted event to help it along:
dsTaskActivities.Tables["Tasks"].Rows[cMgr.Position]["SubCategory"] =
Value;
But I still have a problem. As the user moves through the records of the
Task table, the ComboBox does not always show the correct value for the
field that it is bound to. Sometimes it does, but other times it just
reveals a blank. What's really odd is that it will show a blank on a
specific row when approached from one direction, say the previous row, but
when approached from the following row it shows the correct value.
So, I've made some progress, but I still need to figure out why the ComboBox
is not consistant. If you have any thoughts on this I would really
appreciate it.
Also, I must implement the same behavior in a DataGrid. One of the columns
needs to have a ComboBox in it. In other words, it needs to function like
the property editor pane when editing a property like BorderStyle. Do you
know how to do this?
Thanks for your help.
"Ian Griffiths [C# MVP]" <ia*************@nospam.nospam> wrote in message
news:O$**************@tk2msftngp13.phx.gbl...
Sorry - I'm used to using strongly-typed datasets. With those, the
DataSet exposes a property for each table, and the table provides an
indexer that means you don't need to use Rows. I have a habit of
forgetting that when going back to normal datasets...
As for your combobox, if I understand correctly, you've bound the Text
property to one table, but you've got the DataSource of the same combobox
bound to a different table. I'm not sure if that's a supported scenario
to be honest.
cbSubCategoryLookUp.DataBindings.Add("Text", dsTaskActivities,
"Tasks.SubCategory");
and
cbSubCategoryLookUp.DataSource = dsCatSubCats.Tables["Category"];
I'm not sure what the expected behaviour is when you've got two different
currency managers trying to control the same value. (Which is ultimately
what's going on here. The combobox will want to set the Text property to
be whatever the currently selected item is, which will be an item from the
dsCatSubCats.Tables["Category"] table, but you've also got a binding
trying to set it to something from a different table altogether.)
At least that's how it looks to me. On the other hand it's late here, so
I could have misread it. :)
What are you trying to achieve here? Is there some relation between the
Category table in dsCatSubCats and the SubCategory table in
dsTaskActivities? If so, mightn't it be better to get them all into one
dataset and set up a DataRelation between them? But I'm not quite clear
on what your goal is, so I'm not sure how best to solve the problem.
--
Ian Griffiths - http://www.interact-sw.co.uk/iangblog/
"Christopher Weaver" <we*****@verizon.net> wrote in message
news:eK*************@TK2MSFTNGP10.phx.gbl... Thanks for the reply.
I've tried a couple of things before and since your post. Here's my
attempt to implement one of your suggestions:
Your suggestion was:
myDataSet.MyTable[currencyMgr.Position]["field"] = someValue;
and my implementation was:
dsTaskActivities.Tables["Tasks"][cMgr.Position]["SubCategory"] =
Value;
The error message received was:
Cannot apply indexing with [] to an expression of type
'System.Data.DataTable'
So I changed it to this:
dsTaskActivities.Tables["Tasks"].Rows[cMgr.Position]["SubCategory"] =
Value;
And added this:
dsTaskActivities.Tables["Tasks"].Rows[cMgr.Position].EndEdit();
Now here's the real problem. I've realized through some experimentation
that the problem lies in the specific control that I'm using. I'm using
a ComboBox to allow the user to select a value from a foreign key table.
When a selection is made, the selected value is revealed in a TextBox
that I added for debugging purposes; so I know that the value is being
set properly. When I leave the editted row and return, the new value is
still in the TextBox but the ComboBox is showing another value.
Sometimes it's the previous value, sometimes it's something else
entirely. While I thought that I was having trouble getting the value
selected by the user to stick, it appears that I'm really having trouble
getting the ComboBox to show the current value. I've used the following:
cbSubCategoryLookUp.DataBindings.Add("Text", dsTaskActivities,
"Tasks.SubCategory");
textBox2.DataBindings.Add("Text", dsTaskActivities, "Tasks.SubCategory");
And yet they don't always show the same value even though the ComboBox is
bound to the table that holds the only values allowed in SubCategory and
the only values that show up in the TextBox are selected from the
ComboBox dropdown list. This is how the ComboBox is bound:
cbSubCategoryLookUp.DataSource = dsCatSubCats.Tables["Category"];
cbSubCategoryLookUp.DisplayMember = "CatSubCats.SubCategory";
Do you have any idea what I'm missing here?
Chris.
"Ian Griffiths [C# MVP]" <ia*************@nospam.nospam> wrote in message
news:Oc**************@TK2MSFTNGP10.phx.gbl... Christopher Weaver wrote:
I want to set a value in a specific field in the current row of a
DataSet.
So the first thing to know is that the DataSet doesn't have any notion
of a current row.
In fact strictly speaking, the DataSet doesn't have any notion of a row.
It just contains a bunch of DataTables. And it's the DataTables that
contain the rows. But a DataTable doesn't have any notion of a current
row either, no more than a table in a relational database has a notion
of a 'current' row.
Currency (in the sense of what is currently selected) is entirely a UI
thing. It's managed by the currency manager in a Windows Forms
applciation.
SomeRow["fieldName"] = 'value';
But how do I set SomeRow to the row that the user is currently viewing?
I tried this:
DataRowView drv = (DataRowView) cMgr.Current; //Where cMgr is a
CurrencyManager
drv["SubCategory"] = Value;
But it doesn't stick. When the user moves off the record and back
again, the previous value is restored.
You mean that your changes aren't being stored in the DataTable?
In which case you've misdiagnosed the problem. You *are* successfully
getting hold of the current row. The reason the changes aren't sticking
is because you probably need to call EndEdit on the DataRowView.
In a Windows Forms app, edits are provisional until they are applied.
There are a number of reasons. One is that it may only make sense to
check constraints once all of the fields for a row have been entered, in
which case there has to be some point at which you say 'done now!' to
try and apply the changes.
Also, by convention, in most grid editing UIs in Windows, you can
usually cancel out of your current row edit.
So the changes you make through the view are probably not sticking
because the edit is being regarded as provisional, and you never try to
finish the edit.
At least that's one possibility - try calling EndEdit on the DataRowView
and see if that helps.
Alternatively, just get the Position from the CurrencyManager, and go
straight to the DataTable object rather than going via the view.
Something like:
myDataSet.MyTable[currencyMgr.Position]["field"] = someValue;
--
Ian Griffiths - http://www.interact-sw.co.uk/iangblog/