I might be going in the wrong direction, so let me try to sort out my thoughts (and hopefully get some tips from you guys):
Imagine an enum:
public enum ReportType
{
Performance,
Trending,
Statistical
}
This enum will also be a property or paramter to the constructor of a form. The value of the ReportType will determine things like:
a) the text displayed at the top of the form
b) Which controls are visible
c) the text for a combobox <---!!!! this is where the 2nd enum comes in
In regards to the 2nd enum, if it's a Performance ReportType, I would want:
public enum PerformanceGraph
{
Bar,
Line,
Pie,
Area
}
if it was Trending, I would want:
public enum TrendingGraph
{
Bar,
Line
}
This form is just gathering user input. I mean, I'd rather not get into some elaborate inheritance structure for a simple form. Seems like a lot of effort (I could be wrong) when I can quickly do something like:
(imagine this constructor)
public ReportInputForm(ReportType RptType)
{
m_RptType = RptType;
if (RptType == ReportType.Performance)
{
this.Text = "Performance Title";
this.CheckBoxCtl.Visible = false;
this.GraphCombo.Items.AddRange(Enum.GetNames(typeof(PerformanceGraph)));
this.GraphCombo.SelectedIndex = (int)PerformanceGraph.Bar;
}
else if (RptType == ReportType.Trending)
{
// blah, blah
}
else if (RptType == ReportType.Statistical)
{
// blah, blah
}
else
{
throw new ArgumentException("Invalid ReportType enum value");
}
}
It starts to get hairy when you want to actually do something with the GraphCombo, because now you need to know which ReportType it is for casting purposes.
Also, going back to my constructor, let's say I want to send it a Graph Value so we can set the GraphCombo's SelectedIndex (this may be the value that the user last selected, as opposed to setting some type of default). Ummm ....
public ReportInputForm(ReportType RptType, ???WhichGraphEnum???)
{
}
I mean, there's three graph enum's right now, because there are three ReportType's. Plus, imagine adding a few more ReportType's.
I suppose I can use an int/long:
public ReportInputForm(ReportType RptType, int lastGraphType)
{
}
But I suppose I'm trying to be Mr. Enum here with my compile-time checking. In other-words, I can detect an error if I could use some type of enum (like so):
ReportInputForm foo = new ReportInputForm(ReportType.Trending, GraphType.Area);
As opposed to:
// Is 4 even a valid graph type for the trending report? Answer: No
ReportInputForm foo = new ReportInputForm(ReportType.Trending, 4);
I've rambled on enough. Maybe this is more of a design question rather than enum related. I'm just looking for some thoughts on how to approach this. Thanks!
################################################################################## ################################################################################## ######################## EDIT BEGINS HERE ######################################## ################################################################################## ##################################################################################This is in response to using Generics (I apologize if I'm a bit slow; Thank you Daniel for your response):
Here was a suggestion:
ReportInputForm<TrendingReport> = new ReportInputForm<TrendingReport>(GraphType.Area);
OK, so if I'm to use Generics (and with a Form), I have to create a Type. I'm imagining something like this (we'll only expose one function, setting the title, for now):
public abstract class ReportType
{
public abstract string GetTitle();
}
public class PerformanceReport : ReportType
{
public PerformanceReport()
{
}
public override string GetTitle()
{
return "This is my Performance title";
}
}
public class TrendingReport : ReportType
{
public TrendingReport()
{
}
public override string GetTitle()
{
return "This is my Trending title";
}
}
public partial class Form1<T> : Form
where T : ReportType, new()
{
T foo = null;
public Form1()
{
InitializeComponent();
foo = new T();
this.Text = foo.GetTitle();
}
}
So, now I can do something like what was suggested:
Form1<TrendingReport> f = new Form1<TrendingReport>();
That's cool, and it works (my title depends on the type), but I don't think it helps my original issue. The 2nd enum.
If I am using a PerformanceReport, I want my GraphType enum to be:
public enum PerformanceGraph
{
Bar,
Line,
Pie,
Area
}
If I am using a TrendingReport, I want my GraphType enum to be:
public enum TrendingGraph
{
Bar,
Line
}
In other words, this enum is dependent upon the class (or as my original question stated, dependent upon the first enum).
I mean, I suppose I can put an enum, that encompasses all graph types, in the abstract class:
public abstract class ReportType
{
public enum GraphType
{
Bar,
Line,
Pie,
Area
}
public abstract string GetTitle();
}
But, that defeats the purpose of my original question. Because this now becomes legal (imagine that I modified the constructor of Form1):
Form1<TrendingReport> f = new Form1<TrendingReport>(ReportType.GraphType.Pie);
Remember, TrendingReport is supposed to only have Bar and Line. I'm trying to compile-time check this. I could definitely be missing something too (in regards to Generics).