Dan*_*ake 9 c# data-binding wpf binding
我有一个对象的集合存储在一个CollectionViewSource并绑定到一个DataGrid.我想显示当前所选对象的"详细视图"DataGrid.我可以使用获取当前对象CollectionViewSource.View.CurrentItem.
MyClass
{
[IsImportant]
AProperty{}
AnotherProperty{}
[IsImportant]
YetAnotherProperty{}
}
Run Code Online (Sandbox Code Playgroud)
我想要做的是在列表框中为每个标有该IsImportant属性的属性显示一个标签(带有属性名称)和一个控件(用于编辑).绑定必须在所做的编辑,DataGrid和后备对象之间起作用.显示的控件应根据属性的类型而变化,该类型可以是boolean,string或者IEnumerable<string>(我已编写了一个IValueConverter用于在可枚举和换行符分隔的字符串之间进行转换).
有谁知道实现这个的方法?我现在可以通过以下方式显示每个属性的值,但编辑它们不会更新后备对象:
listBox.ItemsSource = from p in typeof(MyClass).GetProperties()
where p.IsDefined(typeof(IsImportant), false)
select p.GetValue(_collectionViewSource.View.CurrentItem, null);
Run Code Online (Sandbox Code Playgroud)
为了澄清,我希望这可以"自动"发生,而无需在XAML中手动指定属性名称.如果我可以在运行时基于哪些属性标记属性动态添加到XAML,那也没关系.
Qua*_*ter 12
您希望具有带属性名称和控件的标签的控件编辑属性值,因此首先创建一个包装特定对象的属性的类,以充当该控件的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); }
}
}
Run Code Online (Sandbox Code Playgroud)
您希望将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;
}
}
Run Code Online (Sandbox Code Playgroud)
最后一个技巧是你希望编辑控件根据属性的类型而变化.您可以通过使用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>
Run Code Online (Sandbox Code Playgroud)
然后,您可以将ListBox创建为:
<ItemsControl ItemsSource="{Binding Converter={StaticResource PropertyValueConverter}}"/>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5108 次 |
| 最近记录: |