Я нашел способ, который работает для моих целей.Это может быть расширено и для работы со свойствами, и все еще требует правильной обработки ошибок для ввода текста пользователем.
public class ViewModel : ViewModelBase
{
public ViewModel(object instance)
{
foreach (var field in instance.GetType().GetFields())
{
Fields.Add(new FieldViewModel(instance, field));
}
}
private ObservableCollection<FieldViewModel> _fields = new ObservableCollection<FieldViewModel>();
public ObservableCollection<FieldViewModel> Fields
{
get { return _fields; }
set
{
_fields = value;
OnPropertyChanged();
}
}
}
И FieldViewModel выглядит следующим образом ...
public class FieldViewModel : ViewModelBase
{
private object _instance;
private FieldInfo _fieldInfo;
private Type _fieldType;
public FieldViewModel(object instance, FieldInfo fieldInfo)
{
_instance = instance;
_fieldInfo = fieldInfo;
_fieldType = fieldInfo.FieldType;
IsReadOnly = fieldInfo.IsInitOnly || fieldInfo.IsLiteral;
FieldName = fieldInfo.Name;
TypeName = fieldInfo.FieldType.Name;
}
private bool _IsReadOnly;
public bool IsReadOnly
{
get { return _IsReadOnly; }
private set
{
_IsReadOnly = value;
OnPropertyChanged();
}
}
private string _fieldName;
public string FieldName
{
get { return _fieldName; }
set
{
_fieldName = value;
OnPropertyChanged();
}
}
private string _typeName;
public string TypeName
{
get { return _typeName; }
set
{
_typeName = value;
OnPropertyChanged();
}
}
public object Value
{
get
{
return _fieldInfo.GetValue(_instance);
}
set
{
_fieldInfo.SetValue(_instance, Convert.ChangeType(value, _fieldType));
OnPropertyChanged();
}
}
}
И использование выглядит как ...
Person personInstance = new Person
{
Name = "automagically",
Age = 25,
Height = 185.2,
IsMarried = false
};
ViewModel = new ViewModel(personInstance);
И представление ...
<ItemsControl ItemsSource="{Binding ViewModel.Fields}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding FieldName}" />
<TextBox Grid.Column="1" Text="{Binding Value}" IsReadOnly="{Binding IsReadOnly}"/>
<TextBlock Grid.Column="2" Text="{Binding TypeName}" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Что выглядит так ...