Author Topic: PaletteSet and the Current Palette  (Read 9150 times)

0 Members and 1 Guest are viewing this topic.

Keith Brown

  • Swamp Rat
  • Posts: 601
PaletteSet and the Current Palette
« on: February 24, 2014, 05:46:18 PM »
I have been struggling for a couple of hours trying to figure out how to get the current palette of a paletteset.  Is this possible?  Has anyone done it?
Keith Brown | AutoCAD MEP Blog | RSS Feed
AutoCAD MEP 2014 / Revit MEP 2014 / EastCoast CAD/CAM addon / Visual Studio 2013

n.yuan

  • Bull Frog
  • Posts: 348
Re: PaletteSet and the Current Palette
« Reply #1 on: February 25, 2014, 10:43:59 AM »
When PaletteSet was first available for .NET, it is a sealed class, so it is really difficult to find out what palette is current, and it also had no PaletteActivated event.

Since AutoCAD 2009, PaletteSet became inheritable, so you can easily and almost should always derive your custom PalleteSet, just you create a windows form/dialog box that always derives from Windows.Forms.Form.

In your derived PaletteSet, you can make sure unique Palette name and in conjunction with handing PaletteActivated event, you can keep track of the Palettebeing activated and expose a read-only property to let outside world know which palette is currently activated.

Following code show a custom PaletteSet containing 2 UserControls (PaletteA and PaletteB):

Code - C#: [Select]
  1. using System;
  2. using System.Drawing;
  3. using Autodesk.AutoCAD.Windows;
  4.  
  5. namespace GetCurrentPalatte
  6. {
  7.     public class MyPaletteSet : Autodesk.AutoCAD.Windows.PaletteSet
  8.     {
  9.         private Palette _currentPalette = null;
  10.  
  11.         public MyPaletteSet()
  12.             :base("MyPs",new Guid("4F17DF6C-99AE-44D8-BBB1-08ED1E873000"))
  13.         {
  14.             this.Style = PaletteSetStyles.ShowAutoHideButton |
  15.                     PaletteSetStyles.ShowCloseButton |
  16.                     PaletteSetStyles.Snappable;
  17.  
  18.             this.Opacity = 100;
  19.             this.Dock = DockSides.None;
  20.             this.DockEnabled = DockSides.None;
  21.             this.Size = new Size(500, 400);
  22.             this.MinimumSize = new Size(250, 200);
  23.  
  24.             Initialize();
  25.         }
  26.  
  27.         public string CurrentPaletteName
  28.         {
  29.             get { return _currentPalette == null ? "" : _currentPalette.Name; }
  30.         }
  31.  
  32.         private void Initialize()
  33.         {
  34.             this.Add("Palette A", new PaletteA());
  35.             this.Add("Palette B", new PaletteB());
  36.  
  37.             this.PaletteActivated += MyPaletteSet_PaletteActivated;
  38.  
  39.             this.Activate(1);
  40.             _currentPalette = this[1];
  41.         }
  42.  
  43.         void MyPaletteSet_PaletteActivated(object sender, PaletteActivatedEventArgs e)
  44.         {
  45.             _currentPalette = e.Activated;
  46.         }
  47.     }
  48. }
  49.  

Then here is the code of a CommandClass to show the code outside the PaletteSet gets current Palette's name:
Code - C#: [Select]
  1. using Autodesk.AutoCAD.ApplicationServices;
  2. using Autodesk.AutoCAD.EditorInput;
  3. using Autodesk.AutoCAD.Runtime;
  4.  
  5. [assembly: CommandClass(typeof(GetCurrentPalatte.MyCommands))]
  6.  
  7. namespace GetCurrentPalatte
  8. {
  9.     public class MyCommands
  10.     {
  11.         private static MyPaletteSet _ps = null;
  12.  
  13.         [CommandMethod("ShowPS", CommandFlags.Session)]
  14.         public static void RunMyCommand()
  15.         {
  16.             Document dwg = Application.DocumentManager.MdiActiveDocument;
  17.             Editor ed = dwg.Editor;
  18.  
  19.             if (_ps==null)
  20.             {
  21.                 _ps = new MyPaletteSet();
  22.             }
  23.  
  24.             _ps.Visible = true;
  25.         }
  26.  
  27.         [CommandMethod("CurrentPt")]
  28.         public static void ShowCurrentPallete()
  29.         {
  30.             if (_ps!=null && _ps.Visible)
  31.             {
  32.                 Application.ShowAlertDialog("Current palette is \"" + _ps.CurrentPaletteName + "\".");
  33.             }
  34.             else
  35.             {
  36.                 Application.ShowAlertDialog("MyPaletteSet is not visible");
  37.             }
  38.         }
  39.     }
  40. }
  41.  

With exposed CurrentPalette property, if you need to access the controls inside the Palette, such as a TextBox, you simply cast it into corresponding UserControl, and then whatever you exposed from the UserControl, you can access it, you have full control.

HTH

edit:kdub -> csharp code tags added
« Last Edit: February 25, 2014, 03:32:19 PM by Kerry »

Keith Brown

  • Swamp Rat
  • Posts: 601
Re: PaletteSet and the Current Palette
« Reply #2 on: February 25, 2014, 05:07:42 PM »


With exposed CurrentPalette property, if you need to access the controls inside the Palette, such as a TextBox, you simply cast it into corresponding UserControl, and then whatever you exposed from the UserControl, you can access it, you have full control.


Thank you for the code showing how to expose the current palette name.  That definately helped me retrieve the name but what I am really after is the ability to access the controls inside the palette.  I don't quite understand what you mean when you say to cast it into the corresponding UserControl.  What exactly do i cast?  The current Palette?


In your code you are creating your palettes inside your inherited PaletteSet MyPaletteSet.  I have chosen to create my palettes inside of my main code to make my PaletteSet easier to reuse.  Here is my class for my enhanced paletteset.


Code - C#: [Select]
  1. using System;
  2. using Autodesk.AutoCAD.ApplicationServices;
  3. using Application = Autodesk.AutoCAD.ApplicationServices.Core.Application;
  4.  
  5.  
  6. namespace Autodesk.AutoCAD.Windows
  7. {
  8.     /// <summary>
  9.     /// An enhanced version of the PaletteSet that will insure that the visibility of the palette is false
  10.     /// when the application enters a Zero Document State.  When exiting a Zero Document State the palette
  11.     /// will regain its previous visibility setting.
  12.     /// </summary>
  13.     public class EnhancedPaletteSet : PaletteSet
  14.     {
  15.         private bool _wasVisible;
  16.         private Palette _currentPalette;
  17.  
  18.  
  19.         public EnhancedPaletteSet(string name, string cmd, Guid toolId) : base(name, cmd, toolId)
  20.         {
  21.             InitializeHandlers();
  22.         }
  23.  
  24.  
  25.         public EnhancedPaletteSet(string name, Guid toolId) : base(name, toolId)
  26.         {
  27.             InitializeHandlers();
  28.         }
  29.  
  30.  
  31.         public EnhancedPaletteSet(string name) : base(name)
  32.         {
  33.             InitializeHandlers();
  34.         }
  35.  
  36.  
  37.         private void InitializeHandlers()
  38.         {
  39.             DocumentCollection documentCollection = Application.DocumentManager;
  40.             documentCollection.DocumentToBeDestroyed += DocumentToBeDestroyedPreventZeroDocumentState;
  41.             documentCollection.DocumentCreated += DocumentCreatedFromZeroDocumentState;
  42.             PaletteActivated += EnhancedPaletteSet_PaletteActivated;
  43.         }
  44.  
  45.  
  46.         private void EnhancedPaletteSet_PaletteActivated(object sender, PaletteActivatedEventArgs e)
  47.         {
  48.             _currentPalette = e.Activated;
  49.         }
  50.  
  51.  
  52.         private void DocumentToBeDestroyedPreventZeroDocumentState(object sender, DocumentCollectionEventArgs e)
  53.         {
  54.             var documentCollection = (DocumentCollection) sender;
  55.  
  56.  
  57.             if (documentCollection.Count == 1)
  58.             {
  59.                 if (Visible)
  60.                 {
  61.                     Visible = false;
  62.                     _wasVisible = true;
  63.                 }
  64.                 else
  65.                 {
  66.                     _wasVisible = false;
  67.                 }
  68.             }
  69.         }
  70.  
  71.  
  72.         private void DocumentCreatedFromZeroDocumentState(object sender, DocumentCollectionEventArgs e)
  73.         {
  74.             var documentCollection = (DocumentCollection) sender;
  75.  
  76.  
  77.             if (documentCollection.Count == 1)
  78.             {
  79.                 if (_wasVisible)
  80.                 {
  81.                     Visible = true;
  82.                 }
  83.             }
  84.         }
  85.  
  86.  
  87.         /// <summary>
  88.         /// Gets the current Palette Name
  89.         /// </summary>
  90.         public string CurrentPaletteName
  91.         {
  92.             get { return _currentPalette == null ? "" : _currentPalette.Name; }
  93.         }
  94.  
  95.  
  96.         /// <summary>
  97.         /// Gets the Current Palette
  98.         /// </summary>
  99.         public Palette CurrentPalette
  100.         {
  101.             get { return _currentPalette; }
  102.         }
  103.  
  104.  
  105.         /// <summary>
  106.         /// Toggles the visibility of the PaletteSet
  107.         /// </summary>
  108.         public void Toggle()
  109.         {
  110.             Visible = !Visible;
  111.         }
  112.     }
  113. }




And an abbreviated version of my main class


Code - C#: [Select]
  1. namespace Brown.Hangers
  2. {
  3.     public class HangerControl : IExtensionApplication
  4.     {
  5.         private static EnhancedPaletteSet _paletteSet;
  6.         private RibbonTab _contextualRibbonTab;
  7.  
  8.  
  9.         private static HangerControl _instance;
  10.         private HangerControl() { }
  11.  
  12.  
  13.         public static HangerControl Instance
  14.         {
  15.             get
  16.             {
  17.                 if (_instance == null)
  18.                 {
  19.                     _instance = new HangerControl();
  20.                 }
  21.                 return _instance;
  22.             }
  23.         }
  24.  
  25.  
  26.         /// <summary>
  27.         ///
  28.         /// </summary>
  29.         public void Initialize()
  30.         {
  31.             Console.WriteMessage("Custom Hanger Application loaded...");
  32.             var anvilFig260Palette = new HangerPalette("Anvil", "Fig-260", Properties.Resources.ANVILFIG260,
  33.                 "http://www.catalogds.com/db/service?domain=anvil.phas&command=locate&category=260",
  34.                 "73F0AA3B-5559-48B5-8484-2BCBD9FD0C47");
  35.             var anvilFig590Palette = new HangerPalette("Anvil", "Fig-590", Properties.Resources.ANVILFIG590,
  36.                 "http://www.catalogds.com/db/service?domain=anvil.phas&command=locate&category=590",
  37.                 "F65588D4-0899-48C0-B035-1F9AA5D002AB");          
  38.  
  39.  
  40.                         if (_paletteSet == null)
  41.             {
  42.                 _paletteSet = new EnhancedPaletteSet(HangerPropertySetName, null,
  43.                      new Guid("EB435B77-B94E-4540-B432-39899FE62732"))
  44.                 {
  45.                       MinimumSize = new Size(275, 750),
  46.                       Style = PaletteSetStyles.ShowTabForSingle
  47.                         | PaletteSetStyles.ShowPropertiesMenu
  48.                         | PaletteSetStyles.ShowAutoHideButton,
  49.                         Name = HangerPropertySetName,
  50.                         Icon = GetEmbeddedIcon("CLEVISHANGER")
  51.                 };
  52.                 _paletteSet.Add("Fig-260", anvilFig260Palette);
  53.                 _paletteSet.Visible = false;
  54.                 _paletteSet.KeepFocus = false;
  55.             }
  56.         }
  57.  
  58.  
  59.         /// Summary
  60.         /// Gets the Current Palette
  61.         /// Summary
  62.         public Palette GetCurrentPalette()
  63.         {
  64.            return _paletteSet.CurrentPalette;        
  65.         }
  66.  
  67.  
  68.         [CommandMethod("FabricationHangers")]
  69.         public void CommandFabricationHangers()        
  70.         {
  71.             _paletteSet.Toggle();
  72.         }
  73.  
  74.  
  75.     }
  76. }
  77.  


My UserControl class is called HangerPalette and I am creating several of the palettes and adding them to the EnhancedPaletteSet _paletteSet.


So in code in another class i would like to access the current palette's usercontrol and check the status of a checkbox.  This is what I am unsure of what to.  I have a feeling that I might have to restructure my control class in order to make this work.  I can access the current palette name by


Code - C#: [Select]
  1. HangerControl.Instance.GetCurrentPalette().Name


Beyond that I am lost.
Keith Brown | AutoCAD MEP Blog | RSS Feed
AutoCAD MEP 2014 / Revit MEP 2014 / EastCoast CAD/CAM addon / Visual Studio 2013

Jeff H

  • Needs a day job
  • Posts: 6150
Re: PaletteSet and the Current Palette
« Reply #3 on: February 25, 2014, 05:39:30 PM »
Hey Keith,

Won't speak for Norman because he is smarter than me, but looking at CurrentPaletteName property he is using the current palette and for the example was just exposing name to print to command line and could return palette instead name.

With a little more information from last post what is the checkbox for?

Is the checkbox the data or just a visual representation?

Do you see where I am going?




Keith Brown

  • Swamp Rat
  • Posts: 601
Re: PaletteSet and the Current Palette
« Reply #4 on: February 25, 2014, 05:52:06 PM »
Hi Jeff,


I have a property in the EnhancedPaletteSet that returns the currentpalette in addition to the currentpalettename.  What I am confused about is how to get the usercontrol that is present on the currentpalette.


The checkbox is just a true/false identifier to control whether to place an object on the current layer or on the layer as defined in the layerkeystyle of the object.  I created one UserControl class and create several palettes based on that class sending in different catalog information in the constructor.  Once the object in inserted into the drawing using the palette I have an eventhandler that handles the insertion and does some processing on the object inserted.  The reason why this code is in the eventhandler and not the class of the palette is that I also want to be able to handle not only the objects inserted by the palette but also by objects inserted by normal means.  i.e. either using the commandline or by using ribbon tools.  My palettes essentially streamline the process of going thru the mvpartadd dialogs.


HTH
Keith Brown | AutoCAD MEP Blog | RSS Feed
AutoCAD MEP 2014 / Revit MEP 2014 / EastCoast CAD/CAM addon / Visual Studio 2013

Jeff H

  • Needs a day job
  • Posts: 6150
Re: PaletteSet and the Current Palette
« Reply #5 on: February 26, 2014, 08:17:17 AM »
Was asking about checkbox to try to separate the control from data.

One step in that direction is exposing a property that returns its property

Publc bool InsertCurrentLayer { get {return chkbx.Checked;}}
but could do much better with viewmodel

You could always try

foreach (Control ctrl in this.Controls)
{
    if (ctrl  is CheckBox)
    {
     
    }
}

Keith Brown

  • Swamp Rat
  • Posts: 601
Re: PaletteSet and the Current Palette
« Reply #6 on: February 26, 2014, 08:39:25 AM »
I have a property setup in the usercontrol that does return the state of the checkbox.  I just am unable to reference the correct object that has that property.


I have a reference to the current palette.  The current palette has a usercontrol that is created by a class called HangerPalette.  The HangerPalette class has public properties that gets all of the private fields.  Once I have a reference to the current palette i am unable to get a reference to the user control on the palette.  I know that this is probably a C# 101 question but this is just the first time that i have created a very heavy palette application and i am unable to figure it out.  I started out using a Forms but thinking of switching to WPF.  I am not sure if it will help any in this case however.
Keith Brown | AutoCAD MEP Blog | RSS Feed
AutoCAD MEP 2014 / Revit MEP 2014 / EastCoast CAD/CAM addon / Visual Studio 2013

n.yuan

  • Bull Frog
  • Posts: 348
Re: PaletteSet and the Current Palette
« Reply #7 on: February 26, 2014, 11:14:06 AM »
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:
Code: [Select]
public interface IMyPalette
    {
        Dictionary<string, string> TextBoxValues { set; get; }
        string PaletteName { set; get; }
    }

The UserControls:
Code: [Select]
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];
                        }
                    }
                }
            }
        }
    }
Code: [Select]
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:
Code: [Select]
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:
Code: [Select]
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...).
« Last Edit: February 26, 2014, 11:19:04 AM by n.yuan »

Jeff H

  • Needs a day job
  • Posts: 6150
Re: PaletteSet and the Current Palette
« Reply #8 on: February 26, 2014, 11:36:00 AM »
Could he keep a dictionary of Dic<Palette,UserControl> or Dic<string,UserControl> and populate it when adding palettes or create a little dictionary class that when added to dictionary adds it to palette set?

Keith Brown

  • Swamp Rat
  • Posts: 601
Re: PaletteSet and the Current Palette
« Reply #9 on: February 26, 2014, 12:00:11 PM »
Thanks Norman and Jeff.  I definitely need to remove the palette code from my IExtensionApplication and Commands Class.  However, this is an internal project and I need to get proof of concept of my idea to management.  So after reading both of your posts and suggestings what I did was take Jeff's suggestion and create a dictionary<string, usercontrol> and get the current palette and then look that up in the dictionary to get the usercontrol.  Once I had the user control the public properties were already implemented and I was able to have access to the controls.  My proof of concept is now complete and working properly.  Now to just make sure that I handled every possible error that can come up!
 
I want to delve further into Norman's implementation however.  I kind of want to stay way from implementing my palettes in my EnhancedPaletteSet Class but that doesn't mean that I cannot create a new paletteset class that inherits from the EnhancedPaletteSet class and implement them there.  I just need to sit down and think about what I am really trying to accomplish in the long run and make it reusable.
 
Keith Brown | AutoCAD MEP Blog | RSS Feed
AutoCAD MEP 2014 / Revit MEP 2014 / EastCoast CAD/CAM addon / Visual Studio 2013

Jeff H

  • Needs a day job
  • Posts: 6150
Re: PaletteSet and the Current Palette
« Reply #10 on: February 26, 2014, 08:13:44 PM »
Take the problem your solving set it on your desk and turn it 180 degrees and look at it from the opposite direction.

Quote
sending in different catalog information in the constructor...
...streamline the process of going thru the mvpartadd dialogs.

Been while since used MEP and seemed like MVParts were more prevalent for mechanical, but maybe create a command line command the prompts for strings, ints, bools, etc... what ever needed to fill constructor so you can script or send a string from palette or ribbon.

Maybe create a MvPartBuilder object that ribbon or palette would use, and the palette just takes information and use builder to create it and the builder could return information if needed to be shown.

Maybe something will come from slapping some things like that together.

Creating a Mvpart should not have know or worry about what palette is current or any UI element just creating it and exposes state if needed.

On the other hand if it is small pretty straight forward then couple the sh*t out of it and do not waste time trying make something elegant that brings no real benefit. I will fall in the trap of spending too much time on something that does not require it trying to make it more "elegant" or whatever.
Spending time taking something simple adding more abstractions and layers that allow reusability and decoupling, just creates more information to learn and complexity.



Keith Brown

  • Swamp Rat
  • Posts: 601
Re: PaletteSet and the Current Palette
« Reply #11 on: March 03, 2014, 10:25:39 AM »
Unfortunately as a software engineer I am handed a set of design specifications from the customer and have to fulfill their wishes.  In other words the design is theirs and not mine. 
 
One thing that I hate doing is redoing something that I have done before.  I would rather spend many hours today designing for what I might need in the future.  I can see many scenarios where it would be very handy to have access to a control on the current palette without the command originating from that palette.  In this case however I feel that the controls that pertain to "setup" can be moved from the actual tool palette and placed on a setup tab located in the options dialog.  After speaking with the customer they agree that it makes more sense.
 
Since I am currently what I would consider a "student" of software engineering and in particular the API of AutoCAD MEP I am constantly thinking of ways to extending the API that will allow me to create high quality, efficient, and reusable code.  Attention to quality upfront is an investment and will lead to savings in the future and whether those saving are monetary, schedule based, or both it doesn't matter.
 
Creating a Mvpart should not have know or worry about what palette is current or any UI element just creating it and exposes state if needed.

The problem that I was having had nothing to do with the mvparts that I created.  What was the issue is that the customer wanted mvparts created through other means to act as if they were created using my tool palettes.  In other words if the settings in the tool palette called for the mvpart to be on a certain layer then any mvpart that met a certain criteria needed to be placed on that layer.   Different tool palettes could have had different settings which would have facilitated needing to know which palette was current and then grabbing those settings from that palette.  By moving the settings to their own dialog I can now just access that dialog for all mvparts that are added to the database.
 
 
Keith Brown | AutoCAD MEP Blog | RSS Feed
AutoCAD MEP 2014 / Revit MEP 2014 / EastCoast CAD/CAM addon / Visual Studio 2013

MexicanCustard

  • Swamp Rat
  • Posts: 705
Re: PaletteSet and the Current Palette
« Reply #12 on: March 03, 2014, 01:55:10 PM »
Keith, now that you've given your explanation that clarifies what you were after.

I would also point out that you could accomplish similar results through the palette using a WPF palette and a MVVM style architecture.  If your ViewModel contained the properties displayed on the palette you would be able to access them during a Database.ObjectAdded event and modify the objects properties appropriately.  Sounds like you found an alternative solution that works but if the customer insisted the controls be on a palette the MVVM way could accomplish that.
Revit 2019, AMEP 2019 64bit Win 10

Jeff H

  • Needs a day job
  • Posts: 6150
Re: PaletteSet and the Current Palette
« Reply #13 on: March 06, 2014, 09:38:35 AM »
Hi Keith,

As I was trying to push toward and MexicanCustard just mentioned is getting the settings out of UI.

If you like I could whip a sample that just uses a simple XML file and the palette can bound to it using XMLDataProvider where if you change a settings on palette it changes the xmldocument in memory which the options would reflect. Change it in options tab the palette will update vice versa(Just need to make sure to save it to file so it will persist on close or document change event etc....)

The point being the palette or options tab is not your data store just a way to visualize it and make changes to it, and can be notified when the data is changed to update its value.

Keith Brown

  • Swamp Rat
  • Posts: 601
Re: PaletteSet and the Current Palette
« Reply #14 on: March 06, 2014, 10:29:33 AM »
Hi Jeff,


I see what you are saying now.  For the options tab what i would normally do is save the settings in the dll then access the control to get the setting value.  I believe what you are saying is that instead of accessing the control, access the value directly where ever it is stored and just use the UI element to set the value.  Makes sense and will be something that i will try to impliment in Version 2.0. 


As far as the WPF goes i have only used it in one application that i wrote where I am replacing the AutoCAD MEP hover tooltips with my own wpf tooltip.  Very basic usage of a wpf window.  I would certainly like to get into all of that mumbo jumbo that mexicancustard mentioned I just need to find a little more time somewhere.


I would certainly welcome any sample you could bring my way.  I havent done much with saving and loading from XML files as of yet but i definately need to start learning for some more complicated projects that I have in mind.  Thanks again as always.
Keith Brown | AutoCAD MEP Blog | RSS Feed
AutoCAD MEP 2014 / Revit MEP 2014 / EastCoast CAD/CAM addon / Visual Studio 2013