OK, now understand that you want to access individual controls on the UserControl as Palette.
Since the UserControl is contained inside a PaletteSet, you'd better expose anything with the UserControl through the custom PaletteSet, rather that declare it as an singleton static instance outside the PaletteSet (especially not in your IExensionApplication and your CommandClass code).
Here is an simplified example to define an interface for a Palette and let the UserControl to implement the interface. All the stuff you want to expose inside the UserControl will exposed via the Interface.
Assume there are 2 UserControls in the PaletteSet, each has a series of TextBoxes, which could be named differently and have different values, of course. We want to be able to access thee text boxes (read/write) by knowing the text box name and the palette name.
The interface:
public interface IMyPalette
{
Dictionary<string, string> TextBoxValues { set; get; }
string PaletteName { set; get; }
}
The UserControls:
public partial class PaletteA : UserControl, IMyPalette
{
private string _paletteName = "";
public PaletteA()
{
InitializeComponent();
}
public string PaletteName
{
set { _paletteName=value;}
get { return _paletteName; }
}
public Dictionary<string, string> TextBoxValues
{
get
{
//Assume you want to expose a set of text boxes on the UserControl
Dictionary<string, string> dic = new Dictionary<string, string>();
foreach (Control c in this.Controls)
{
TextBox txt = c as TextBox;
if (txt!=null)
{
dic.Add(txt.Name, txt.Text);
}
}
return dic;
}
set
{
foreach (Control c in this.Controls)
{
TextBox txt = c as TextBox;
if (txt != null)
{
if (value.ContainsKey(txt.Name))
{
txt.Text = value[txt.Name];
}
}
}
}
}
}
public partial class PaletteB : UserControl, IMyPalette
{
private string _paletteName="";
public PaletteB()
{
InitializeComponent();
}
public string PaletteName
{
set { _paletteName = value; }
get { return _paletteName; }
}
public Dictionary<string, string> TextBoxValues
{
get
{
//Assume you want to expose a set of text boxes on the UserControl
Dictionary<string, string> dic = new Dictionary<string, string>();
foreach (Control c in this.Controls)
{
TextBox txt = c as TextBox;
if (txt!=null)
{
dic.Add(txt.Name, txt.Text);
}
}
return dic;
}
set
{
foreach (Control c in this.Controls)
{
TextBox txt = c as TextBox;
if (txt != null)
{
if (value.ContainsKey(txt.Name))
{
txt.Text = value[txt.Name];
}
}
}
}
}
}
Then the custom PaletteSet:
public class MyPaletteSet : Autodesk.AutoCAD.Windows.PaletteSet
{
private string _currentPaletteName = null;
private Dictionary<string, IMyPalette> _palettes = new Dictionary<string, IMyPalette>();
public MyPaletteSet()
:base("MyPs",new Guid("4F17DF6C-99AE-44D8-BBB1-08ED1E873000"))
{
this.Style = PaletteSetStyles.ShowAutoHideButton |
PaletteSetStyles.ShowCloseButton |
PaletteSetStyles.Snappable;
this.Opacity = 100;
this.Dock = DockSides.None;
this.DockEnabled = DockSides.None;
this.Size = new Size(500, 400);
this.MinimumSize = new Size(250, 200);
Initialize();
}
public string CurrentPaletteName
{
get { return _currentPaletteName; }
}
public IMyPalette CurrentPalette
{
get { return _palettes[_currentPaletteName]; }
}
public Dictionary<string, string> GetPaletteTextBoxes(string paletteName)
{
if (_palettes.ContainsKey(paletteName))
{
return _palettes[paletteName].TextBoxValues;
}
else
{
throw new KeyNotFoundException("No palette with name \"" + paletteName + "\" found.");
}
}
private void Initialize()
{
PaletteA a = new PaletteA();
a.PaletteName = "Pallete A";
this.Add(a.PaletteName, a);
_palettes.Add(a.PaletteName, a);
PaletteB b = new PaletteB();
b.PaletteName = "Palette B";
this.Add(b.PaletteName, b);
_palettes.Add(b.PaletteName,b);
this.PaletteActivated += MyPaletteSet_PaletteActivated;
this.Activate(0);
_currentPaletteName = this[0].Name;
}
void MyPaletteSet_PaletteActivated(object sender, PaletteActivatedEventArgs e)
{
_currentPaletteName = e.Activated.Name;
}
}
Here is the sample code to get text box values and set text box values:
public class MyCommands
{
private static MyPaletteSet _ps = null;
[CommandMethod("ShowPS", CommandFlags.Session)]
public static void RunMyCommand()
{
Document dwg = Application.DocumentManager.MdiActiveDocument;
Editor ed = dwg.Editor;
if (_ps==null)
{
_ps = new MyPaletteSet();
}
_ps.Visible = true;
}
[CommandMethod("CurrentPt")]
public static void ShowCurrentPallete()
{
if (_ps!=null && _ps.Visible)
{
Application.ShowAlertDialog("Current palette is \"" + _ps.CurrentPaletteName + "\".");
//Get existing text boxes' value
Dictionary<string, string> dic = _ps.GetPaletteTextBoxes(_ps.CurrentPaletteName);
ShowPaletteTextBoxValues(dic);
//Set text boxes' value
SetPaletteTextBoxValues(dic, _ps.CurrentPaletteName);
//Show changed values
dic = _ps.GetPaletteTextBoxes(_ps.CurrentPaletteName);
ShowPaletteTextBoxValues(dic);
}
else
{
Application.ShowAlertDialog("MyPaletteSet is not visible");
}
}
private static void ShowPaletteTextBoxValues(Dictionary<string,string> dic)
{
StringBuilder values = new StringBuilder();
foreach (KeyValuePair<string,string> item in dic)
{
values.Append(item.Key + "=" + item.Value + "\n");
}
Application.ShowAlertDialog(values.ToString());
}
private static void SetPaletteTextBoxValues(Dictionary<string,string> dic, string paletteName)
{
Dictionary<string, string> newDic = new Dictionary<string, string>();
foreach (KeyValuePair<string, string> item in dic)
{
switch(item.Key.ToUpper())
{
case "TEXTBOX1":
newDic.Add(item.Key, "XXXX");
break;
case "TEXTBOX2":
newDic.Add(item.Key, "YYYY");
break;
case "TEXTBOX3":
newDic.Add(item.Key, "ZZZZ");
break;
}
}
_ps.CurrentPalette.TextBoxValues = newDic;
}
}
Obviously, the code is not optimized, I just quickly made some changes to the code I post yesterday, but you can get the idea: the key is design your custom PaletteSet correctly and expose the child components inside correctly, ideally, through in Interface, especially if the PaletteSet may have multiple Palettes and they have something in common (labels, textboxes...).