Questions: Tons of Images; Arrays cross-class.

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Samishii23
    New Member
    • Sep 2009
    • 246

    Questions: Tons of Images; Arrays cross-class.

    First, images...
    I have a project that, at this time and version I am working with, I have 648 main stay images, so to say, plus another 100 or so in side features.

    They are going to stored in a outside .dll. Though I can't figure out if I want to use the Resources feature with C# rather then the "Direct" calling if you will. I have, in many Learning projects in the past have just used the direct call "C:\\Image. jpg" with success, even outside my PC. So I could do that, as I have already have all the file names in my arrays awaiting the code to make use of them.

    Question: Should I go with the Resource feature? Is this the best way to go about this with all these images? =P

    Second, my program has a separate .dll holding all the text data for the program. The .cs file is over 120k as it is and I'm still not done filling all the data. Mind you this is simply a namespace, and seperate data classes, then the data. Thats it.

    How should I go about calling the arrays from separate namespaces and classes? I can't figure it out. Heres an example of what I was doing earlier with no success.

    Code:
    using System; using System.Collections.Generic; using System.Drawing;
    
    namespace GeneralLibrary {[INDENT]public class ImageLib {[INDENT]System.Drawing.Image[] FrontIcon = new System.Drawing.Image[] { /*Array of 10 Images in Resources */ };[indent]ImageLib Temp = new ImageLib();[/indent]
    static public Bitmap GetFrontIcon(int I) {[INDENT]return Temp.FrontIcon[I];
    }[/INDENT]
    }[/INDENT]
    }[/INDENT]
    and this has failed, bringing up the error "An object reference is required for the non-static field, method, or property".
    I'm at a loss as to how to go about this problem. =\
  • GaryTexmo
    Recognized Expert Top Contributor
    • Jul 2009
    • 1501

    #2
    "An object reference is required for the non-static field, method, or property"
    GetFrontIcon is a static method that tries to return Temp, a non-static member. I hope that helps! I don't really have anything to offer on the other topic, except maybe you should reevaluate your image allocation. Do you need to have all 648 images loaded at the same time?

    I don't know anything about your program so it's hard for me to speculate, but it might be worthwhile to only load those images you'll be using for any given state in your code. When you go from one state to another, eat a bit of a loading time and cache the images you'll need for that state. Not always necessary, but it's something to think about at any rate.

    Comment

    • Samishii23
      New Member
      • Sep 2009
      • 246

      #3
      Ok, I'll be a little more specific...

      Should I use an ImageList to cache the images I need for the instance? That was one of my original thoughts. But Im cornered with this again, lol...

      I don't know which way would be more efficient, or probable. I already have a array with images named out in their specific category, and I have a variable with the directory string... I have done that method of calling an image from a .dll before on a seperate computer to see if it worked, and there wasn't an error...
      Do I just "Embed" all the files into the .dll file, and do I just call them like (for example) this:
      Code:
      List<Image> ImgCache = new List<Image>();
      // 1 way
      ImgCache.add(@"C:\\Project\\images\\icon_1.jpg");
      // Another way using the Resource system
      ImgCache.add(global::GeneralData.Properties.Resources.icon_1);
      Also...
      How do I get data from an entirely different NameSpace / Class that is in an array. Am I going to have to make a method in that Class to push out the data to be class / method I need the data at?

      Also Gary: I tried removing the Static from the method from above that was giving me the error. No change, error wise or where the error was located in the code.

      Comment

      • GaryTexmo
        Recognized Expert Top Contributor
        • Jul 2009
        • 1501

        #4
        No I meant put static in :) You had a static method trying to access a non-static member. So when that static method tried to look at the contents of the non-static member, it's null because it hasn't been instantiated. An easy fix would be to make the non-static member a static member.

        I guess if you're loading everything with a DLL, it's already in memory. The alternative I was talking about was to load it directly from a file when needed (hence the caching). As I said, either way would work for you, I was just suggesting an alternative :)

        As for your actual storage type... it depends on how you're looking it up I guess. If you'll be going through every image anyway, you might as well just use a List, then parse the list and put each image where it needs to go. If you'll be looking up an image by name as you need it, maybe use a hash table with the image name as the key for fast retrieval. This part really depends on how you code your program.

        Comment

        • Samishii23
          New Member
          • Sep 2009
          • 246

          #5
          Lol. Im still new to C#, and pretty much .exe making in general. So I have no idea other then the little bits and peices I've been told.

          I'd rather all those image files be in one centralized location without being visible to the end-user. Is there a way to do that without having all the files in another folder rather then in a dll?

          Im open for suggestions! :)

          Comment

          • GaryTexmo
            Recognized Expert Top Contributor
            • Jul 2009
            • 1501

            #6
            I don't know of any other way to hide resource files from the user other than to embed them in a DLL, which is what you were doing already. I think once a DLL is loaded, it's in memory... but I'm no expert on how that stuff works. Someone else may have some comments on that.

            Out of curiosity, why do they need to be hidden from the end user? I mean, all the user does is run the executable, any resources the program uses live in the directory and your average user shouldn't care. If some sneaky person decides they want to change a few of the images, the absolute worst they'll do is mess up the program form themselves... which is really their own fault.

            To be honest, having them live in a directory makes things easier for you. Images change... instead of having to recompile the DLL every time you need to update content, you can just replace files.

            Still, it's your project, do it how you like. I'm just trying to offer alternatives/discussion points. At the end of the day, just experiment. You know what you want to do, so try some things and if they work out, implement them. If they don't, try another approach. I think you've got a lot to work with and you seem like you have a good handle on what you want to accomplish. If images and text embedded in DLLs turn out to be what works best for you, then there ya go :)

            Comment

            • Samishii23
              New Member
              • Sep 2009
              • 246

              #7
              Ok Gary. Going to give storing the images an a the .exe dir and see how that goes in load time, and resources...

              Now. I have a side Class Library where I'll be holding all my "Current Version" data. Since there'll be multiple version entries, and Im an archiver, if you will, I'll be holding all the excess data in the outside .dll, so I can just recomile the .exe for bugs and new features, exc and the .dll when a new version comes out.

              So basicly this the the Librarys code.
              Code:
              namespace v322 {
               // I'll have 10 of theses
               public class DataClass1 {
                // There will be 44 entries in my project
                // But for the sake of this, only a couple
                int[] DataNumber = new int[] { 0, 2, 3, 2 };
                string[] DataTitle = new string[] { null, "First", "Second", "Third" };
                string[] DataIcon = new string[] { null, "1.jpg", "2.jpg", "3.jpg" };
                string[][] DataDisc = new string[][] {
                 null,
                 new string[] { "Sub Disc 1", "Sub Disc 2" };
                 new string[] { "Sub Disc 1", "2", "3" };
                 new string[] { "1","2" };
                };
               }
              }
              I've added the references to my main project. I have been able to get any data straight up from the DataClass in my main project. I'm lost as to how to retrieve the data without a Method in the DataClass to return each array item. I have once before tried to return the entire array variable without success...

              Is there a way I can return the entire array object? Or maybe a way to access the arrays in the main project with a way Im not seeing??

              Comment

              • GaryTexmo
                Recognized Expert Top Contributor
                • Jul 2009
                • 1501

                #8
                I'm like 99% sure that members are private by default in C#, so that would explain why you can't access any of your members in the DataClass1 class.

                Code:
                public class MyConstants
                {
                  [b]public[/b] double PI = 3.141592654;
                }
                You can also create public properties to get the data out...

                Code:
                public class Person
                {
                  private string m_firstName = "";
                
                  public string FirstName
                  {
                    get { return m_firstName; }
                    set { m_firstName = value; }
                  }
                }
                The first approach might be what you want since it's a data storage class (more like a struct, really), but it's up to you.

                Comment

                • Samishii23
                  New Member
                  • Sep 2009
                  • 246

                  #9
                  Can't you do:
                  Code:
                  class Data {
                     public string name { get; set; }
                  }
                  ???
                  I've seen tutorials talk about this a few times but when I tried to do it, theres a compiler error. lol Pretty pointless to put it in a tutorial if it doesn't work!! Heh

                  Comment

                  • GaryTexmo
                    Recognized Expert Top Contributor
                    • Jul 2009
                    • 1501

                    #10
                    Supposedly you can... they call it auto-implemented properties, but I could never get it to work. I typed that exact same thing into my copy of VS and it wouldn't do it. Maybe it's something new that VS 2005 (what I have at work) doesn't support, and what C# 2008 Express Edition (that I have at home) doesn't offer.

                    I have absolutely no idea how that's supposed to work... so I just do it manually, which isn't so bad :)

                    Comment

                    • Samishii23
                      New Member
                      • Sep 2009
                      • 246

                      #11
                      Data Code, Basicly I would like each of these variables to be passed through the GetMe function...
                      Code:
                      namespace CalcData
                      {
                          public class GeneralData
                          {
                              private GeneralData() {}
                      
                              // Image Directory Declarations
                              string DirIcon = Environment.CurrentDirectory + "\\icons\\";
                              string DirOther = Environment.CurrentDirectory + "\\img\\";
                              // Talent Icon Width / Height
                              public readonly int DIcoW = 32;
                              public readonly int DIcoH = 32;
                              // Talent Tree Image Width / Height
                              public readonly int DTreeBGW = 580;
                              public readonly int DTreeBGH = 210;
                              // StartUp Form Window Width / Height
                              public readonly int SUWindowW = 358;
                              public readonly int SUWindowH = 187;
                              // Form Window Normal Width / Height
                              public readonly int DWindowW = 791;
                              public readonly int DWindowH = 610;
                              // Talent Tree X and Y Positions
                              public readonly int DTreeX = 3;
                              public readonly int[] DTreeY = new int[] { 2, 218, 434 }; // Trees 1, 2, 3 Respectively
                              // Talent Icon X and Y Positions
                              public readonly int[] DTIconY = new int[] { 12, 64, 116, 168, 220, 272, 324, 376, 428, 480, 532 }; // 11 rows; applys to all 3 trees
                              public readonly int[] DTIcon1X = new int[] { 12, 64, 116, 168 }; // Tree 1; 4 Rows
                              public readonly int[] DTIcon2X = new int[] { 225, 277, 329, 381 }; // Tree 2; 4 Rows
                              public readonly int[] DTIcon3X = new int[] { 441, 493, 545, 597 }; // Tree 3; 4 Rows
                              // Start Up Icon X and Y Locations
                              public readonly int[] SUIconY = new int[] { 10, 76 }; // 2 Rows
                              public readonly int[] SUIconX = new int[] { 10, 76, 144, 210, 276 }; // 5 Columns
                      
                              public object GetMe(string What, int I)
                              {
                                  switch (What)
                                  {
                                      case "dir_icon": return DirIcon;
                                      case "dir_img": return DirOther;
                                      default: return null;
                                  }
                              }
                          }
                      }
                      This is all I've coded so far...
                      Code:
                      if (!Directory.Exists(CalcData.GeneralData.GetMe("dir_icon",0))) {
                         MessageBox.Show("Missing the icon directory!");
                         Application.Exit();
                         }
                      Error: Argument '1': Can not convert object object into string.

                      Added ToString() to the end of GetMe()...
                      Error: An object reference is required for the non-static field, method, or property 'CalcData.Gener alData.GetMe(st ring, int)

                      Added static to the method:
                      Code:
                      public static object GetMe(string What, int I)
                      Same Error as above...

                      Im lost. =\
                      Last edited by Samishii23; Oct 22 '09, 11:31 PM. Reason: Mis-typings

                      Comment

                      • GaryTexmo
                        Recognized Expert Top Contributor
                        • Jul 2009
                        • 1501

                        #12
                        I dunno if I'm reading this right, but you're still mixing statics and non-statics...

                        It's either...

                        Code:
                        public static Constants
                        {
                          public static string Name = "GaryTexmo";
                        
                          public static object GetMe(string description)
                          {
                            object obj = null;
                            switch (description.ToLower())
                            {
                              case "name":
                                obj = this.Name;
                                break;
                            }
                          }
                        }
                        
                        [[ main method ]]
                        {
                          Console.WriteLine(Constants.Name);
                          Console.WriteLine(Consants.GetMe("name"));
                        }
                        ... or ...

                        Code:
                        public Constants
                        {
                          public string Name = "GaryTexmo";
                        
                          public Constants() { }
                        
                          public object GetMe(string description)
                          {
                            object obj = null;
                            switch (description.ToLower())
                            {
                              case "name":
                                obj = this.Name;
                                break;
                            }
                        
                            return obj;
                          }
                        }
                        
                        [[ main method ]]
                        {
                          [B]Constants myConstants = new Constants();[/B]
                        
                          Console.WriteLine(myConstants.Name);
                          Console.WriteLine(myConsants.GetMe("name"));
                        }
                        See the difference?

                        (I think I coded that right, I didn't run it through a compiler... let me know if it still gives you troubles and I'll putter around with it. I'm hoping to give you enough "hints" that you'll sort it out on your own, so it'll stick with you :D)

                        Comment

                        • Samishii23
                          New Member
                          • Sep 2009
                          • 246

                          #13
                          Code:
                          static string DirIcon = Environment.CurrentDirectory + "\\icons\\";
                          static string DirOther = Environment.CurrentDirectory + "\\class\\";
                          
                          public static object GetMe(string What, int I) {
                            //object NObj = null;
                            switch (What)
                            {
                              case "dir_icon": return DirIcon;
                              case "dir_img": return DirOther;
                              default: return null;
                            }
                          }
                          Code:
                          public void DoCheck() {
                            // DoCheck() - Checking to see if files needed are there.
                            if (!Directory.Exists(GeneralData.GetMe("dir_icon",0).ToString()))
                            {
                              MessageBox.Show("Missing the icon directory!");
                              Enviroment.Exit(1);
                            }
                          }
                          I can see its not near your examples, but this is working.
                          I had gotten an error when I added "GeneralDat a gd = new GeneralData();" ... Something about not needing to do with with static members or something. After I removed that code. I put in the GeneralData.Get Me() and it started working...

                          lol! I don't know why but hey. =D

                          Comment

                          • Samishii23
                            New Member
                            • Sep 2009
                            • 246

                            #14
                            Problem solved... For now. :)

                            Code:
                            Namespace.Class Temp = new Namespace.Class();
                            This basic, instance caller ( the term evades my mind at this moment ) ?, is working. I can see all the variables in the dropdown, and theres no compiler errors.

                            Comment

                            • GaryTexmo
                              Recognized Expert Top Contributor
                              • Jul 2009
                              • 1501

                              #15
                              Well, for the above, the reason you got the error is because you were trying to instantiate a static class. You don't need to instantiate a class to access its static methods/members. The reason it works now is because you added a non-static method, which then calls static methods.

                              So if you instantiated a new object, you couldn't access the static method you made, "GetMe" without an error, which in my compiler comes out to be "Static member 'ConsoleApplica tion1.MyConstan ts.GetItem(stri ng)' cannot be accessed with an instance reference; qualify it with a type name instead." Which means exactly what it says, access it with the type name (whatever you called your class).

                              The example I posted above is what I tested with. The only change is where I wrote:

                              Code:
                                   switch (description.ToLower())
                                   {
                                     case "name":
                                       obj = this.Name;
                                       break;
                                   }
                              Should actually be:
                              Code:
                                   switch (description.ToLower())
                                   {
                                     case "name":
                                       obj = [B]Constants[/B].Name;
                                       break;
                                   }
                              Anyway, you may still want to pick whether or not you want a static class or a non-static class. Then again, you've got something that works (hopefully it makes sense why it works now :D) so you may just want to go on to other things. Though for the sake of clarity, you might want to revisit this at a later time.

                              I hope that helps :)

                              Comment

                              Working...