gpt4 book ai didi

c# - WPF:将列表动态绑定(bind)到(某些)对象的属性

转载 作者:太空狗 更新时间:2023-10-29 17:45:27 47 4
gpt4 key购买 nike

我有一组对象存储在 CollectionViewSource 中并绑定(bind)到 DataGrid . 我想显示当前在 DataGrid 中选择的对象的“详细 View ” 。我可以使用 CollectionViewSource.View.CurrentItem 获取当前对象.

MyClass
{
[IsImportant]
AProperty{}

AnotherProperty{}

[IsImportant]
YetAnotherProperty{}
}

我想做的是在列表框中为每个标有IsImportant 的属性显示一个标签(带有属性名称)和一个控件(用于编辑)属性。绑定(bind)必须在所做的编辑、DataGrid 和支持对象之间起作用。显示的控件应根据属性的类型而有所不同,可以是 boolean , stringIEnumerable<string> (我写了一个 IValueConverter 来在可枚举字符串和换行符分隔字符串之间进行转换)。

有谁知道实现这个的方法吗?我目前可以通过以下方式显示每个属性的值,但编辑它们不会更新支持对象:

listBox.ItemsSource = from p in typeof(MyClass).GetProperties()
where p.IsDefined(typeof(IsImportant), false)
select p.GetValue(_collectionViewSource.View.CurrentItem, null);

澄清一下,我希望这种情况“自动”发生,而无需在 XAML 中手动指定属性名称。如果我可以在运行时根据哪些属性用特性标记来动态添加到 XAML , 那也行。

最佳答案

您想要一个带有属性名称标签的控件和用于编辑属性值的控件,因此首先创建一个包装特定对象的属性的类作为该控件的 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 绑定(bind)到一个对象,以便用这些控件填充它,因此创建一个 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 设置为基于属性类型的各种编辑器模板之一来实现。如果属性是 bool 值,则此示例使用 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}}"/>

关于c# - WPF:将列表动态绑定(bind)到(某些)对象的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3152557/

47 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com