您想要一个具有带有属性名称的标签的控件以及用于编辑属性值的控件,因此首先创建一个类,该类包装特定对象的属性以充当该控件的 DataContext:
public class PropertyValue
{
private PropertyInfo propertyInfo;
private object baseObject;
public PropertyValue(PropertyInfo propertyInfo, object baseObject)
{
this.propertyInfo = propertyInfo;
this.baseObject = baseObject;
}
public string Name { get { return propertyInfo.Name; } }
public Type PropertyType { get { return propertyInfo.PropertyType; } }
public object Value
{
get { return propertyInfo.GetValue(baseObject, null); }
set { propertyInfo.SetValue(baseObject, value, null); }
}
}
您希望将 ListBox 的 ItemsSource 绑定到一个对象,以便使用这些控件填充它,因此创建一个 IValueConverter 它将一个对象转换为 PropertyValue 对象列表以获取其重要属性:
public class PropertyValueConverter
: IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return
from p in value.GetType().GetProperties()
where p.IsDefined(typeof(IsImportant), false)
select new PropertyValue(p, value);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return Binding.DoNothing;
}
}
最后一个技巧是您希望编辑控件根据属性的类型而变化。您可以通过使用 ContentControl 并将 ContentTemplate 设置为基于属性类型的各种编辑器模板之一来做到这一点。如果属性是布尔值,则此示例使用 CheckBox,否则使用 TextBox:
<DataTemplate x:Key="CheckBoxTemplate">
<CheckBox IsChecked="{Binding Value}"/>
</DataTemplate>
<DataTemplate x:Key="TextBoxTemplate">
<TextBox Text="{Binding Value}"/>
</DataTemplate>
<Style x:Key="EditControlStyle" TargetType="ContentControl">
<Setter Property="ContentTemplate" Value="{StaticResource TextBoxTemplate}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding PropertyType}" Value="{x:Type sys:Boolean}">
<Setter Property="ContentTemplate" Value="{StaticResource CheckBoxTemplate}"/>
</DataTrigger>
</Style.Triggers>
</Style>
<DataTemplate DataType="{x:Type local:PropertyValue}">
<StackPanel Orientation="Horizontal">
<Label Content="{Binding Name}"/>
<ContentControl Style="{StaticResource EditControlStyle}" Content="{Binding}"/>
</StackPanel>
</DataTemplate>
然后,您可以将 ListBox 创建为:
<ItemsControl ItemsSource="{Binding Converter={StaticResource PropertyValueConverter}}"/>