Using reflection, you could create a collection of dynamic objects, then bind your DataGrid to it.
There is a great answer here about creating dynamic classes:
How to dynamically create a class in C#?
Using this, you can create the list of properties (which will be columns in your datagrid) at runtime like this
List<TypeBuilderNamespace.Field> myFields = new List<TypeBuilderNamespace.Field>();
myFields.Add( new TypeBuilderNamespace.Field("FirstName", Type.GetType("System.String")));
myFields.Add( new TypeBuilderNamespace.Field("Surname", Type.GetType("System.String")));
myFields.Add( new TypeBuilderNamespace.Field("Age", Type.GetType("System.Int32")));
Then dynamically create your class
Type myDynamicType = TypeBuilderNamespace.MyTypeBuilder.CompileResultType(myFields);
Create some sample data
List<dynamic> people = new List<dynamic>();
dynamic person1 = Activator.CreateInstance(myDynamicType);
person1.FirstName = "John";
person1.Surname = "Smith";
person1.Age = 45;
people.Add(person1);
dynamic person2 = Activator.CreateInstance(myDynamicType);
person2.FirstName = "Emma";
person2.Surname = "Jones";
person2.Age = 18;
people.Add(person2);
Then bind your data to the grid
DataGrid grid = new DataGrid();
grid.AutoGenerateColumns = true;
grid.ItemsSource = people;
This gives the following DataGrid

I modified the code in the answer quoted above slightly, so here is my listing of that for completeness:
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
namespace TypeBuilderNamespace {
    public class Field {
        public String FieldName { get; set; }
        public Type FieldType { get; set; }
        public Field(String name, Type type) {
            FieldName = name;
            FieldType = type;
        }
    }
    public static class MyTypeBuilder {                
        public static Type CompileResultType(List<Field> fields) {
            TypeBuilder tb = GetTypeBuilder();
            ConstructorBuilder constructor = tb.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);
            FieldName(string) and FieldType(Type)
            foreach (var field in fields)
                CreateProperty(tb, field.FieldName, field.FieldType);
            Type objectType = tb.CreateType();
            return objectType;
        }
        private static TypeBuilder GetTypeBuilder() {
            var typeSignature = "MyDynamicType";
            var an = new AssemblyName(typeSignature);
            AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run);
            ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule");
            TypeBuilder tb = moduleBuilder.DefineType(typeSignature
                            , TypeAttributes.Public |
                            TypeAttributes.Class |
                            TypeAttributes.AutoClass |
                            TypeAttributes.AnsiClass |
                            TypeAttributes.BeforeFieldInit |
                            TypeAttributes.AutoLayout
                            , null);
            return tb;
        }
        private static void CreateProperty(TypeBuilder tb, string propertyName, Type propertyType) {
            FieldBuilder fieldBuilder = tb.DefineField("_" + propertyName, propertyType, FieldAttributes.Private);
            PropertyBuilder propertyBuilder = tb.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, null);
            MethodBuilder getPropMthdBldr = tb.DefineMethod("get_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, propertyType, Type.EmptyTypes);
            ILGenerator getIl = getPropMthdBldr.GetILGenerator();
            getIl.Emit(OpCodes.Ldarg_0);
            getIl.Emit(OpCodes.Ldfld, fieldBuilder);
            getIl.Emit(OpCodes.Ret);
            MethodBuilder setPropMthdBldr =
            tb.DefineMethod("set_" + propertyName,
              MethodAttributes.Public |
              MethodAttributes.SpecialName |
              MethodAttributes.HideBySig,
              null, new[] { propertyType });
            ILGenerator setIl = setPropMthdBldr.GetILGenerator();
            Label modifyProperty = setIl.DefineLabel();
            Label exitSet = setIl.DefineLabel();
            setIl.MarkLabel(modifyProperty);
            setIl.Emit(OpCodes.Ldarg_0);
            setIl.Emit(OpCodes.Ldarg_1);
            setIl.Emit(OpCodes.Stfld, fieldBuilder);
            setIl.Emit(OpCodes.Nop);
            setIl.MarkLabel(exitSet);
            setIl.Emit(OpCodes.Ret);
            propertyBuilder.SetGetMethod(getPropMthdBldr);
            propertyBuilder.SetSetMethod(setPropMthdBldr);
        }
    }
}