2

I am creating my own UI Binding system, which ties controls to their associated objects. What would be better than using a series of if-statements? If I add new controls to serve new track items, I would not want to update this series of if statements every time.

TimelineTrackControl control;
Type objectType = track.GetType();

if (objectType == typeof(ShotTrack))
{
    control = new ShotTrackControl();
}
else if (objectType == typeof(AudioTrack))
{
    control = new AudioTrackControl();
}
else if (objectType == typeof(GlobalItemTrack))
{
    control = new GlobalItemTrackControl();
}
else
{
    control = new TimelineTrackControl();
}

control.TargetTrack = track;
timelineTrackMap.Add(track, control);

2 Answers 2

1

You could:

  1. Create a Dictionary<Type, Type> that contains the track types and the corresponding control types:

    private static readonly Dictionary<Type, Type> ControlTypes = new Dictionary<Type, Type>
    {
        { typeof(ShotTrack), typeof(ShotTrackControl) },
        ...
    };
    

    To get a corresponding control:

    control = Activator.CreateInstance(ControlTypes[track.GetType()]);
    
  2. Create a Dictionary<Type, Func<Control>> that contains the track types and the corresponding control creators:

    private static readonly Dictionary<Type, Func<Control>> ControlTypes = new Dictionary<Type, Func<Control>>
    {
        { typeof(ShotTrack), () => new ShotTrackControl() },
        ...
    };
    

    To create a new corresponding control:

    control = ControlTypes[track.GetType()]();
    
  3. Define a custom attribute that stores the corresponding control type:

    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
    public class TrackControlAttribute : Attribute
    {
        public readonly Type ControlType;
    
        public TrackControlAttribute(Type controlType)
        {
            ControlType = controlType;
        }
    }
    
    [TrackControl(typeof(ShotTrackControl))]
    public class ShotTrack
    {
        ...
    }
    

    To create a new corresponding control:

    object[] attrs = track.GetType().GetCustomAttributes(typeof(TrackControlAttribute), true);
    if (attrs.Length != 0);
        control = Activator.CreateInstance(((TrackControlAttribute)attrs[0]).ControlType);
    

    EDIT
    Bug fixed in the 3rd option.

Sign up to request clarification or add additional context in comments.

2 Comments

I really like option #3. Though I think I will make the Attribute for the control and point to it's track. That way the tracks have no knowledge of the controls.
Oops. I made a mistake in the getting of the attribute. I updated the sample.
1

You could use reflection, in this case http://msdn.microsoft.com/en-us/library/vstudio/d133hta4 like this:

Activator.CreateInstance(null, track.GetType().toString() + "Control");

1 Comment

This is a nice answer, but will only really work if you keep your class names consistent.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.