Obbles
Obbles

Reputation: 563

How to access the properties of a generically defined object?

I have the following code. (Designed to open a viewmodel from code).

private void OpenView<viewType,viewModelType> (object parameters) {

        //STEP 1. CREATE THE VIEW
        var view = (viewType)Activator.CreateInstance(typeof(viewType));            

        //STEP 2. SET THE DATACONTEXT
        var viewModel = (viewModelType)view.DataContext;            

        //STEP 3. OPEN THE WINDOW AND WAIT UNTIL MANUALLY CLOSED            
        TestWindow window = new TestWindow();
        window.LayoutRoot.Children.Add(view);
        window.Activate();
        window.ShowDialog();            
    }

The compiler gives me the following error;

Error CS1061 'viewType' does not contain a definition for 'DataContext' and no extension method 'DataContext' accepting a first argument of type 'viewType' could be found (are you missing a using directive or an assembly reference?)

I cannot access the DataContext in step 2 because I presume the compiler does not know what type the view variable is. Can anyone tell me how I can tell the compiler what type the view variable is? and if that is not possible. How to work around it?

Upvotes: 1

Views: 83

Answers (1)

DavidG
DavidG

Reputation: 119076

There's two real solutions here.

  1. viewType is always the same type: So don't make it generic.
  2. viewType always inherits from the same base class or implements a common interface. For example, it is always a FrameworkElement which has the DataContext property. If that's the case, you can constrain the generic type to that class:

    private void OpenView<TViewType, TViewModelType>(object parameters)
        where viewType : FrameworkElement // This is the magic sauce
    {
        var view = (TViewType)Activator.CreateInstance(typeof(TViewType));            
    
        // Now we can access the DataContext
        var viewModel = (TViewModelType)view.DataContext;  
    
        //snip
    }
    

PS It's pretty common practice to prefix generic types with T

Upvotes: 2

Related Questions