Oystein
Oystein

Reputation: 1322

Instantiating a class based on a property set value

When presenting the user with a ComboBox with ObservableCollection<Type> as its ItemsSource, how can I instantiate a class in the property that SelectedItem is bound to?

The elements in the ElementList list in parentItem is either of a generic class type Element, or is of a type inheriting from Element (e.g. DigitalOutputButton or TrendGraph).

XAML:

<StackPanel Orientation="Horizontal">
    <TextBlock Width="100" Text="Element Type:" />
    <ComboBox Width="300" ItemsSource="{Binding Path=Element.ElementTypeList}" 
              SelectedItem="{Binding Path=Element.SelectedElementType}" />
</StackPanel>

C# code:

private static ObservableCollection<Type> _elementTypeList 
    = new ObservableCollection<Type> { typeof(Element), typeof(DigitalOutputButton), typeof(TrendGraph) };
public static ObservableCollection<Type> ElementTypeList { get { return _elementTypeList; } }

public Type SelectedElementType {
    get { return GetType(); }
    set {
        if (value != GetType()) {
            var parentItem = Controller.ConfigurationHandler.FindParentItem(this);
            var currentItemIndex = parentItem.ElementList.IndexOf(this);
            parentItem.ElementList[currentItemIndex] = new typeof(value)();
        }
    }
}

The above set code will not build. But is it possible to achieve this behavior in another way?

EDIT: Ok, this way works:

public Type SelectedElementType {
    get { return GetType(); }
    set {
        if (value != GetType()) {
            var parentItem = Controller.ConfigurationHandler.FindParentItem(this);
            var currentItemIndex = parentItem.ElementList.IndexOf(this);
            if (value == typeof(Element)) {
                parentItem.ElementList[currentItemIndex] = new Element();
            }
            else if (value == typeof(DigitalOutputButton)) {
                parentItem.ElementList[currentItemIndex] = new DigitalOutputButton();
            }
            else if (value == typeof(TrendGraph)) {
                parentItem.ElementList[currentItemIndex] = new TrendGraph();
            }
        }
    }
}

But it would be great it there was a way to do this that were a little more "maintenance free" (no need to edit when adding a new element type).

Upvotes: 1

Views: 80

Answers (1)

nvoigt
nvoigt

Reputation: 77285

var instance = Activator.CreateInstance(value, Controller, ParentElementGroup, ItemLabel);
parentItem.ElementList[currentItemIndex] = (TYPE)instance;

The only missing link is the type of your collection so it can be cast. But that should be compile time knowledge.

Upvotes: 1

Related Questions