0

我在用户控件 (DataGridView) 中有一个 DataGrid。此用户控件从应用程序的任何位置传播到 DataGrid 的 ItemsSource 的绑定,并用 K 的列表填充它。

对于此示例,让我们为 K 定义具有一些具有自定义属性的属性的类:

public class Foo
{
    [Enumeration(IsEnum=true, EnumerationType=typeof(MessageType))] //MessageType is enumeration and is consisted of values: 'Error', 'Warning' and 'Info'
    public MessageType MessageType { get; set; }

    [Enumeration(IsEnum=true, EnumerationType=typeof(FooType))] //FooType is enumeration and is consisted of values: 'Sweet' and 'Salty'
    public FooType FooType { get; set; }
 }

DataGrid 有一个用于自动生成列的事件。

private void OnAutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
    {
        foreach (Attribute attribute in (e.PropertyDescriptor as System.ComponentModel.PropertyDescriptor).Attributes)
        {
            Utilities.EnumerationAttribute enumAttribute = attribute as Utilities.EnumerationAttribute;

            if (enumAttribute != null
                && enumAttribute.IsEnum)
            {
                DataGridTemplateColumn templateColumn = new DataGridTemplateColumn();

                templateColumn.CellTemplate = (DataTemplate)Resources["enumTemplate"];

                e.Column = templateColumn;
            }
        }
        e.Column.IsReadOnly = true;
   }

“enumTemplate”的资源在 MergedDictionary 中定义为 DataTemplate

<DataTemplate x:Key="enumTemplate">
    <StackPanel>
        <ComboBox/>
    </StackPanel>
</DataTemplate>

我打算做的是设置网格将生成的每个 ComboBox 的 ItemsSource,其返回值为字符串 [] 类型的 Enum.GetNames(enumAttribute.EnumerationType)。

现在这里有很多匿名性,我不知道属性的名称、它们的类型,甚至这个 DataGrid 在运行时将显示的对象的类型。

我对此进行了几次尝试......比如定义一个 List> 类型的属性 DataSourcesList,其中 NamedArray 包含要填充组合框的项目和属性的名称(来自 e.PropertyName),以便我知道哪个 NamedArray 用于组合框正在生成...类似于:

 DataSourcesList.Add(new DataSourceWithMappedName<System.Object>() { MappedName = e.PropertyName, SourceList = Enum.GetNames(enumAttribute.EnumerationType) });

然后更改 DataTemplate:

<DataTemplate x:Key="enumTemplate">
    <DataTemplate.Resources>
        <converters:IListToItemsSource x:Key="ilistToItemsSource"/>
    </DataTemplate.Resources>
    <StackPanel>
        <ComboBox ItemsSource="{Binding DataSourcesList, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:DataGridView}}, Converter={StaticResource ilistToItemsSource}, ConverterParameter={Binding somethingButAllInVaine}}"/>
    </StackPanel>
</DataTemplate>

,但由于 ConverterParameter 不是 DependencyObject 且无法绑定,因此无法执行此操作。

也许我应该声明,以后应该将相同的原则用于绑定集合而不仅仅是枚举。

所以拜托,任何人都可以帮助我解决通用 GridView 中的通用 ComboBox 表示。

Tnx 和快乐的编码。

4

1 回答 1

1

也许DataTemplate在代码中设置会更容易。首先定义datatemplate,然后将设置ComboBox ItemSource Binding Source为.List of StringEnum.GetNames()

编码方式

        // Create template
        DataTemplate newTemplate = new DataTemplate();
        FrameworkElementFactory stackFactory = new FrameworkElementFactory(typeof(StackPanel));
        FrameworkElementFactory comboFactory = new FrameworkElementFactory(typeof(ComboBox));
        Binding newBinding = new Binding();
        newBinding.Source = Enum.GetNames(typeof(enumAttribute.EnumerationType));
        comboFactory.SetBinding(ComboBox.ItemsSourceProperty, newBinding);
        stackFactory.AppendChild(comboFactory);
        newTemplate.VisualTree = stackFactory;

        // Set the template
        templateColumn.CellTemplate = newTemplate;

XAML / 代码方式*

<CollectionViewSource x:Key="EnumCollection"/>

<DataTemplate x:Key="enumTemplate"> 
    <StackPanel>
        <ComboBox ItemsSource="{Binding Source={StaticResource EnumCollection}}" />
    </StackPanel>
</DataTemplate>

代码(确保设置Collection Source):

CollectionViewSource enumCollection = (CollectionViewSource)this.FindResource("EnumCollection");
enumCollection.Source =Enum.GetNames(typeof(enumAttribute.EnumerationType));

纯 Xaml

<ObjectDataProvider x:Key="EnumCollection"
                    MethodName="GetValues"
                    ObjectType="{x:Type sys:Enum}">
    <ObjectDataProvider.MethodParameters>
        <x:Type TypeName="YourEnum" />
    </ObjectDataProvider.MethodParameters>
</ObjectDataProvider>

<DataTemplate x:Key="enumTemplate"> 
    <StackPanel>
        <ComboBox ItemsSource="{Binding Source={StaticResource EnumCollection}}" />
    </StackPanel>
</DataTemplate>
于 2012-09-07T19:03:57.000 回答