tags:

views:

104

answers:

3

I have a situation that is pretty simple, and I'd like to know the ideal way to do it.

I have a combo box. Each line of the combo box corresponds to a particular strategy object.

What is the proper way to map the combo box lines to the strategy object.

The way I was doing it seems overly complicated, and I'm pretty much guaranteed there is a simple standard way to do this.

Thank you.

EDIT:

I had the data in a Dictionary, where the string was the text for the combobox, and the object was the strategy... But this isn't ordered... And I just know there is some extremely simple way to do it.

SOLUTION: I used this solution, not feeling comfortable putting presentation logic in the data classes:

private partial class HtmlTransformState : AbstractHtmlEditFormState
{
private Dictionary<string, ITransformStrategy> strategies = new Dictionary<string, ITransformStrategy>() 
{ 
    { "Simple URL", new TransformStrategy<SimpleUrlCodeExtractor>() }, 
    { "Overview", new TransformStrategy<OverviewCodeExtractor>() },  
    { "Video List", new TransformStrategy<VideoListCodeExtractor>() }, 
    { "Video List No MbORKb", new TransformStrategy<VideoListNoMBOrKBAndNoLinksAllowedCodeExtractor>() },
    { "Blue Mountain 2007", new TransformStrategy<BlueMountain2007CodeExtractor>() },
    { "Four Gates", new TransformStrategy<FourGatesCodeExtractor>() },
    { "General", new TransformStrategy<GeneralCodeExtractor>() }
};
public override void DrawForm()
{
    // ...
    ParentForm.cmboTransformStrategy.DataSource = new BindingSource(strategies, null);
    ParentForm.cmboTransformStrategy.DisplayMember = "Key";
    ParentForm.cmboTransformStrategy.ValueMember = "Value";
}

public override IEnumerable<string> ProcessHtml(string urlPath)
{
    ITransformStrategy transformStrategy = (ITransformStrategy)ParentForm.cmboTransformStrategy.SelectedValue;

    // Do some stuff with 'transformStrategy'
}

}

A: 

I would use the SelectedIndexChanged event on the combobox and select the corresponding dictionary entry

found that, Bind a Dictionary to a ComboBox see below for a working example(at least on the original vb.net code that I wrote)

Vb.net converted into C#, you will have to manage the handle yourself

public class Form1
{

private Dictionary<int, myDic> dict = new Dictionary<int, myDic>();

private void  // ERROR: Handles clauses are not supported in C#
ComboBox1_SelectedIndexChanged(System.Object sender, System.EventArgs e)
{
    KeyValuePair<int, myDic> curItem = (KeyValuePair<int, myDic>)ComboBox1.SelectedItem;
    MessageBox.Show(curItem.Value.myvalue);
}

private void  // ERROR: Handles clauses are not supported in C#
Form1_Load(object sender, System.EventArgs e)
{
    myDic d = default(myDic);
    for (int i = 0; i <= 10; i++) {
        d = new myDic();
        d.myKey = i.ToString;
        d.myvalue = Strings.Chr(65 + i);
        dict.Add(d.GetHashCode, d);
    }
    ComboBox1.DataSource = new BindingSource(dict, null);
    ComboBox1.DisplayMember = "value";
    ComboBox1.ValueMember = "Key";
}
}

class myDic
{
public string myKey;
public string myvalue;

public override string tostring()
{
    return myvalue;
}
}
Fredou
but how can you use it when the data isn't ordered? Like with a Dictionary. This is the way I WAS doing it, but it required going through hoops with a List<>.
Alex Baranosky
If I could have a List<TextStrategyPair> that would be ideal. Or and OrderedDictionary<string, object>...
Alex Baranosky
Thanks for the link. I will have to check it out.
Alex Baranosky
@updated my answer with something that is working
Fredou
A: 

Override ToString for your strategy object. After that you can insert your strategy objects directly in the combo box.

public class StrategyObject
{
    public override string ToString()
    {
        return "return the text to display";
    }
}


StrategyObject selectedStratObj = comboBox1.SelectedItem as StrategyObject;
Francis B.
interesting idea!
Alex Baranosky
Should the data class really know about how it is presented? This seems like a violation of SoC...
Alex Baranosky
@GordonG: Well it depends how your StrategyObject is structured. Per example, if you had a collection of Animal and the class Animal has a property Name. It would be perfectly valid to return the property Name in the method ToString(). Now, If you need to generate a valid name for your object, my solution is not really the best for you.
Francis B.
But it's a nifty idea, and one I will remember for the future. Thanks.
Alex Baranosky
+2  A: 

Do you mean something like the following?

public class Strategy
{
    private string _name = "default";
    public string Name
    {
         get { return _name; }
     set { _name = value; }
    }

    public Strategy(string name)
{
        _name = name;
    }
}

Then in form load (you need to have a combo box on that form):

private void Form1_Load(object sender, EventArgs e)
{
    List<Strategy> ls = new List<Strategy>();
    ls.Add(new Strategy("First"));
    ls.Add(new Strategy("Second"));
    ls.Add(new Strategy("Third"));

    comboBox1.DataSource = ls;
    comboBox1.DisplayMember = "Name";
}
tzup
I am uncomfortable putting presentation information in the data classes... It seems to confuse the separation of concerns. Plus, who is to say the Strategy objects are going to know exactly how I want them to be formatted on the comboBox?
Alex Baranosky
Point taken. In some cases I use the "partial" feature of C# to separate logic. Data still is in the same class but in 2 files, one with the DB access layer (for instance) and the other with the presentation stuff. There are many ways to organize a hierarchy and I'm not saying one way is better than other; whatever works and follows the KISS principle I like :)
tzup