[...] I want to send the selected table name items back to the tree view
which will then populate itself with the details of those selected
tables.
Hopefully you don't need the designer code too.
I'm not going to use the code you posted. It's not concise enough, and I
don't feel like simplifying it myself.
As far as what you want to do goes, it sounds to me as though one obvious
approach would be to declare an event on your input form, to which the
custom control can subscribe. The event will be raised when the data on
the input form changes, and the custom control's handler would then take
the information in the event and do something with it.
See my comments after this code example (I'm leaving out all but the stuff
directly related to the event...obviously these would not compile or work
as-is):
class InputChangedEventArgs : EventArgs
{
private string _strInput;
public InputChangedEventArgs(string strInput)
{
_strInput = strInput;
}
public string Input
{
get { return _strInput; }
}
}
delegate void InputChangedEventHandler(object sender,
InputChangedEventArgs e);
class frmConnect : Form
{
public frmConnect()
{
InitializeComponent();
}
public event InputChangedEventHandler InputChanged;
protected void OnInputChanged(object sender, InputChangedEventArgs
e)
{
InputChangedEventHandler handler = InputChanged;
if (handler != null)
{
handler(sender, e);
}
}
private void btnOK_Click(object sender, EventArgs e)
{
foreach (int itm in lstTables.SelectedIndices)
{
selList = selList + lstTables.Items[itm].ToString() +";";
}
OnInputChanged(this, new InputChangedEventArgs(selList));
}
}
class DBTreeContainer : UserControl
{
private void connectToDBToolStripMenuItem_Click(object sender,
EventArgs e)
{
// build connection string
//SqlConnection cn = new SqlConnection();
// fill tree
FormConnect.frmConnect frmConn = new FormConnect.frmConnect();
frmConn.InputChanged += MyInputChangedHandler;
frmConn.Show();
}
private void MyInputChangedHandler(object sender,
InputChangedEventHandler e)
{
// This method will be called when the "selList" variable would
// have changed. The "e" paramter has an "Input" property that
// you can get that contains the value of the string that the
// "selList" variable would have had (and did in fact have in
// the scope in which that variable does exist).
// So, do whatever you want here using the value "e.Input" as
the
// input string from your form. For example, populating the
tree
// view control with the information from the tables in the
string.
}
}
My apologies in advance for any compilation errors. I didn't actually
compile the code above, and might have some typos. But it should be close.
Also, while the above matches as closely as possible the original design
you present, that doesn't mean it's actually the best design. In
particular, you appear to be concatenating the list into a single
';'-separated string. You didn't post code showing how you'd use that
string, but I'd guess you're just going to split that string up again upon
receipt.
If so, then you're probably better off just passing an array of strings in
the event in the first place. One obvious way to do that would be to
declare the data as "string[]" instead of "string", creating the array in
the "btnOK_Click()" method by appending each list box item value into a
local List<string> variable and then using the List.ToArray() method to
pass the resulting list as an array to the constructor of
InputChangedEventArgs. For example:
class InputChangedEventArgs : EventArgs
{
private string[] _rgstrInput;
public InputChangedEventArgs(string[] rgstrInput)
{
_rgstrInput = rgstrInput;
}
public string[] Input
{
get { return _rgstrInput; }
}
}
and then...
private void btnOK_Click(object sender, EventArgs e)
{
List<string> lstr = new List<string>();
foreach (int itm in lstTables.SelectedIndices)
{
lstr.Add(lstTables.Items[itm].ToString());
}
OnInputChanged(this, new
InputChangedEventArgs(lstr.ToArray()));
}
With appropriate changes elsewhere to deal with the
InputChangedEventArgs.Input property correctly, of course.
If for some reason you wanted to be super-careful and prevent that array
from being mutable, you could even return a ReadOnlyCollection<string>
instead of a string[]. For example:
class InputChangedEventArgs : EventArgs
{
private ReadOnlyCollection<string> _rgstrInput;
public InputChangedEventArgs(IList<string> lstrInput)
{
_rgstrInput = new ReadOnlyCollection<string>(lstrInput);
}
public ReadOnlyCollection<string> Input
{
get { return _rgstrInput; }
}
}
These are only examples. You can construct a ReadOnlyCollection<string>
from anything that implements IList<string>, so you could just pass the
List<string> to the constructor of InputChangedEventArgs instead of
converting it to an array, or any other collection class that might be
more appropriate than a string[].
Another option for making the results read-only would be to implement an
indexer on the InputChangedEventArgs class, hiding the actual collection
instance, but since that class isn't really a collection itself per se,
I'm not a big fan of doing it that way.
Hope that helps.
Pete