Click here to Skip to main content
15,893,486 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi,

I'm currently working on a Winforms application. I have a database and there are tables on it.

I created a Form that responsible for showing data's coming from this data tables. For this purpose I added a Data Grid View control to this form. I also created an 'enum' to specify which data is shown. The form gets the data from the database and show it in Data Grid View.

But I have some problems about it.

I have a lot of different data to show, and so I have a lot of if-else chain. Like;
C#
if(listType == ListViewTypes.Accounts)
{ 
   //get data from database
} else if(listType == ListViewTypes.Persons)
{ 
  // get data from database
} 
//etc...


Is there any solution about that?

Thank you.

What I have tried:

I think about create a different class to handle this but I also use this if-else chain in that class too.
Posted
Updated 3-Oct-17 1:38am
Comments
CHill60 5-Oct-17 11:32am    
I'm a bit late to the party but noting the solution you have accepted then you might find this article useful Dynamic Method Dispatcher[^]

Use a switch:
C#
switch (listType)
   {
   case ListViewTypes.Accounts:
      ...
      break;
   case ListViewTypes.Persons:
      ...
      break;
...
   default:
      ...
      break;
   }
 
Share this answer
 
Depending on the homogenity of the executed code, you could possibly use a Dictionary of delegates. See, for instance: c# - Dictionary with delegate or switch? - Stack Overflow[^].
 
Share this answer
 
You could move the "if" statement to a factory class

public interface IDataHandler
{
    void PopulateGridView(GridView gridView);
}

public class AccountsHandler : IDataHandler
{
    public void PopulateGridView(GridView gridView)
    {
        // populate gridView with accounts
    }
}

public class PersonsHandler : IDataHandler
{
    public void PopulateGridView(GridView gridView)
    {
        // populate gridView with people
    }
}

public class DataHandlerFactory
{
    public IDataHandler GetDataHandler (ListViewTypes types)
    {
        switch(types)
        {
            case ListViewTypes.Accounts:
                return new AccountsHandler();
            case ListViewTypes.Persons:
                return new PersonsHandler();
            default:
                throw new NotImplementedException();
        }
    }
}


usage

DataHandlerFactory f = new DataHandlerFactory();

IDataHandler dh = f.GetDataHandler(types);

dh.PopulateGridView(GridView1);


You could even do something like this to get rid of the switch

public class DataHandlerFactory
{
    private static Dictionary<ListViewTypes, IDataHandler> handlers;

    static DataHandlerFactory()
    {
        handlers = new Dictionary<ListViewTypes, IDataHandler>();

        handlers.Add(ListViewTypes.Accounts, new AccountsHandler());
        handlers.Add(ListViewTypes.Persons, new PersonsHandler());
    }

    public IDataHandler GetDataHandler (ListViewTypes types)
    {
        IDataHandler dh;
            
        if (!handlers.TryGetValue(types, out dh))
        {
            throw new NotImplementedException();
        }

        return dh;

    }
}
 
Share this answer
 
Comments
Onur ERYILMAZ 3-Oct-17 11:15am    
I will implement it tomorrow and I will share my code for check if I do this right. Thank you.
Onur ERYILMAZ 4-Oct-17 4:10am    
Ok, I implemented it to my project but unfortunately another problem occurs.
Let's say I have a data table in my database that stores ID, Name and Surname informations of people, and I have another table that stores ID and PhoneNumber of people.
In my ListViewTypes enum, I have enum's like this Persons and PersonsWithPhoneNumbers.
So, PersonsHandler class can handle retrieving data from only one data table but when I need Person's with Phone Numbers then I have to create another class PersonHandlerWithPhoneNumbers. Which is meaningles I thing.

I can add another method like PopulateGridViewWithExtraInformation to the IDataHandler. But in this case I have to add this method to all Handlers, and this is meaningless either.

What would you suggest to handle this kind of situations?

Thank you.
F-ES Sitecore 4-Oct-17 4:39am    
You could always pass both gridviews into the method

public void PopulateGridView(GridView gridViewPrimary, GridView gridSecondary)

then each implementation of IDataHandler can decide if the secondary one is used or not
Onur ERYILMAZ 4-Oct-17 6:08am    
But my Form has only one GridView.
F-ES Sitecore 4-Oct-17 6:19am    
So what's the problem then? Is it showing different data types in a single grid view? If so you can probably use nested grid views, so the phone data will be a cell that's another gridview, or something like that.
As an alternative to Solution 1 (which is perfectly fine): You could also use a Dictionary to map Delegates to your "ListTypes". I prefer doing this over a switch-statement if the case-statements would become rather long. An example (which uses made up types):

C#
class Program
{
    static void Main(string[] args)
    {
        Demo demo = new Demo();

        string action = "multiplyBy3";
        int input = 1;

        int result = demo.DoSomething(action, input);
    }

    class Demo
    {
        static Dictionary<string, Func<int, int>> Actions = new Dictionary<string, Func<int, int>>()
        {
            { "multiplyBy2", x => x * 2 },
            { "multiplyBy3", x => MultiplyBy3(x) },
        };

        public int DoSomething(string action, int input)
        {
            return Actions[action](input);
        }

        static int MultiplyBy3(int input)
        {
            return input * 3;
        }
    }
}
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900