locked
A value of type 'ArrayExtension' cannot be added to a collection or dictionary of type 'String[]'. RRS feed

  • General discussion

  • The error

                   "A value of type 'ArrayExtension' cannot be added to a collection or dictionary of type 'String[]'."

    happen when I try assign XAML array to the string array Field.KeyFieldNames and Field.LookupKeyFieldNames

            <local:TableView  x:Key="peopleView" TableName="Person" Database="{StaticResource database}">
                <local:TableView.Fields>
                    <local:Field Name="Frerence" >
                        <local:Field.KeyFieldNames>
                            <x:Array Type="{x:Type sys:String}">
                                <sys:String>RowId</sys:String>
                            </x:Array>
                        </local:Field.KeyFieldNames>
                        <local:Field.LookupKeyFieldNames>
                            <x:Array Type="{x:Type sys:String}">
                                <sys:String>PersonId</sys:String>
                            </x:Array>
                        </local:Field.LookupKeyFieldNames>
                    </local:Field>
                </local:TableView.Fields>
                <local:TableView.IsOpened>true</local:TableView.IsOpened>
            </local:TableView>
    How to resolve problem?
    • Changed type Jim Zhou - MSFT Monday, August 24, 2009 7:32 AM customer does not provide feedback
    Sunday, August 16, 2009 4:38 AM

All replies

  • You couldn't assign an ArrayExtension, really. But you could bind to it:
    <local:Field.LookupKeyFieldNames>
      <Binding>
        <Binding.Source>
          <x:Array Type="{x:Type sys:String}">
            <sys:String>PersonId</sys:String>
          </x:Array>
        </Binding.Source>
      </Binding>
    </local:Field.LookupKeyFieldNames>

    Sunday, August 16, 2009 5:02 PM
  • It raise following exception:  A 'Binding' cannot be set on the 'KeyFieldNames' property of type 'Field'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject.    

    If I try bind ArrayExtension the way below, then I get following exception

        Property 'KeyFieldNames' does not support values of type 'ArrayExtension'

        <Window.Resources>
            <x:Array x:Key="keyFieldNames" Type="{x:Type sys:String}">
                <sys:String>RowId</sys:String>
            </x:Array>
            ....
                    <local:Field Name="Frerence" DataType="TableView" FieldKind="LookupTableView"
                                 LookupView="{StaticResource expencesView}"
                                 KeyFieldNames="{StaticResource keyFieldNames}">

    How to rework KeyFileldNames property to support ArrayExtension? I added TypeConverter to the KeyFileldNames property but Visual Studio does not use it. I remeber that VS does not load component editors/designer if component and editors/designer placed in the same solution. To fix that you need register designer assembly in the GAC and then VS start works ok. I did the same with my StringArrayConverter but it did not help.

    It is going to work if I change type of KeyFileldNames from String[] to ICollection but this approach is wrong that I'm losing type safety.

    My TypeConverter assigned to the KeyFileldNames and LookupKeyFileldNames properties
        public class StringArrayConverter : TypeConverter
        {
            public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
            {
                if (sourceType == typeof(string))
                {
                    return true;
                }
                if (sourceType == typeof(System.Collections.IList))
                {
                    return true;
                }
                if (sourceType == typeof(ArrayExtension))
                {
                    return true;
                }
                return base.CanConvertFrom(context, sourceType);
            }
    
            public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
            {
                if (!(value is string))
                {
                    return base.ConvertFrom(context, culture, value);
                }
    
                List<string> result = new List<string>();
                var arrayExtension = (ArrayExtension)value;
                var sourceList = (System.Collections.IList)value;
    
                if (sourceList != null)
                {
                    foreach (var item in sourceList)
                    {
                        result.Add(item.ToString());
                    }
                    return result.ToArray();
                }
                if (arrayExtension != null)
                {
                    foreach (var item in arrayExtension.Items)
                    {
                        result.Add(item.ToString());
                    }
                    return result.ToArray();
                }
                else
                {
                    string list = ((string)value).Trim();
                    if (string.IsNullOrEmpty(list))
                    {
                        return new string[0];
                    }
    
                    string[] tokens = list.Split(',');
                    for (int index = 0; index < tokens.Length; index++)
                    {
                        string token = tokens[index].Trim();
                        if (!string.IsNullOrEmpty(token))
                        {
                            result.Add(token);
                        }
                    }
                }
                return result.ToArray();
            }
    
            public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
            {
                if (destinationType == typeof(InstanceDescriptor))
                {
                    return true;
                }
                return base.CanConvertTo(context, destinationType);
            }
    
            public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, 
                object value, Type destinationType)
            {
                if (destinationType == null)
                {
                    throw new ArgumentNullException("destinationType");
                }
    
                if ((destinationType == typeof(string)) && (value is string[]))
                {
                    return string.Join(",", (string[])value);
                }
    
                if ((destinationType == typeof(ArrayExtension)) && (value is string[]))
                {
                    return new ArrayExtension((string[])value);
                }
    
                return base.ConvertTo(context, culture, value, destinationType);
            }



    Sunday, August 16, 2009 5:48 PM
  • Your KeyFileldNames should be a DependencyProperty
    Sunday, August 16, 2009 11:13 PM
  • Hi,

    What are the details about the TableView and Field class?Could you please provide a simplified(without irrelevant) and ready-to-run example to demonstrate the issue you are encountering? So that we can have a clear idea of where the issue is.

    Thanks.
    Jim Zhou -MSFT
    Friday, August 21, 2009 9:52 AM
  • We are changing the issue type to “Comment” because you have not followed up with the necessary information. If you have more time to look at the issue and provide more information, please feel free to change the issue type back to "Question” by clicking the "Options" link at the top of your post, and selecting "Change Type" menu item from the pop menu. If the issue is resolved, we will appreciate it if you can share the solution so that the answer can be found and used by other community members having similar questions.
     
    Thank you!


    Jim Zhou -MSFT
    Monday, August 24, 2009 7:31 AM
  • I simplified example:

        public class TableView
        {
            private readonly FieldCollection _fields = new FieldCollection();
            private bool _isReadonly;
    
            public FieldCollection Fields
            {
                get { return _fields; }
            } 
    
            public string TableName { get; set; }
    
            public bool IsOpened 
            {
                get { return _isReadonly;}
                set
                {
                   _isReadonly = value;
                   //open my table view 
                }
            }
        }
    
        public enum DataType : byte
        {
            String = 1,
            Integer = 2,
            Long = 3,
            Float = 4,
            Double = 5,
            Boolean = 6,
            DateTime = 7,
            TimeSpan = 8,
            Binary = 9,
            Guid = 10,
            Blob = 100,
            Memo = 101,
            TableView = 102
        }
    
        public enum FieldKind
        {
            Data,
            Calculated,
            Lookup,
            LookupTableView
        }
    
        public class FieldCollection : Collection<Field>
        {
    
        }
    
        public class Field
        {
            private string _name;
            private DataType _dataType;
            private FieldKind _fieldKind;
            private bool _readOnly = false;
            private string[] _keyFieldNames;
            private string[] _lookupKeyFieldNames;
    
            #region Generic Constructors
    
            public Field()
            {
            }
    
            #endregion
    
            #region Generic Members
    
            [Browsable(true)]
            [DefaultValue(null)]
            public string Name
            {
                get { return _name; }
                set { _name = value; }
            }
    
            [Browsable(true)]
            [DefaultValue(DataType.String)]
            public DataType DataType
            {
                get { return _fieldKind == FieldKind.LookupTableView ? DataType.TableView : _dataType; }
                set { _dataType = value; }
            }
    
            [Browsable(false)]
            public Type ClrType
            {
                get
                {
                    // Only float fields may have decimal count
                    if (_dataType != DataType.Float && _dataType != DataType.Double)
                    {
                        throw new Exception(string.Format(
                            "Decimal counts are not allowed for type {0}", _dataType));
                    }
    
                    switch (_dataType)
                    {
                        case DataType.String:
                            return typeof(string);
                        case DataType.Integer:
                            return typeof(int);
                        case DataType.Long:
                            return typeof(long);
                        case DataType.Float:
                            return typeof(float);
                        case DataType.Double:
                            return typeof(double);
                        case DataType.Boolean:
                            return typeof(bool);
                        case DataType.DateTime:
                            return typeof(DateTime);
                        case DataType.TimeSpan:
                            return typeof(TimeSpan);
                        case DataType.Binary:
                            return typeof(byte[]);
                        case DataType.Guid:
                            return typeof(Guid);
                        case DataType.Blob:
                            return typeof(byte[]);
                        case DataType.Memo:
                            return typeof(string);
                    }
    
                    throw new Exception(string.Format(
                        "Internal exception: unknown field type: {0}", _dataType));
                }
            }
    
            [Browsable(true)]
            [DefaultValue(FieldKind.Data)]
            public FieldKind FieldKind
            {
                get { return _fieldKind; }
                set { _fieldKind = value; }
            }
    
            [Browsable(true)]
            [DefaultValue(false)]
            [DisplayName("ReadOnly")]
            public bool IsReadOnly
            {
                get { return _readOnly || _fieldKind != FieldKind.Data; }
                set { _readOnly = value; }
            }
    
            #endregion
    
            #region Lookup Field Members
    
            [Browsable(true)]
            [TypeConverter(typeof(StringArrayConverter))]
            [DefaultValue(null)]
            public string[] KeyFieldNames
            {
                get
                {
                    return _keyFieldNames;
                }
                set
                {
                    _keyFieldNames = value;
                }
            }
    
            [Browsable(true)]
            [TypeConverter(typeof(StringArrayConverter))]
            [DefaultValue(null)]
            public string[] LookupKeyFieldNames
            {
                get
                {
                    return _lookupKeyFieldNames;
                }
                set
                {
                    _lookupKeyFieldNames = value;
                }
            }
    
            #endregion
        }
    
        public class StringArrayConverter : TypeConverter
        {
            public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
            {
                if (sourceType == typeof(string))
                {
                    return true;
                }
                if (sourceType == typeof(System.Collections.IList))
                {
                    return true;
                }
                if (sourceType == typeof(ArrayExtension))
                {
                    return true;
                }
                return base.CanConvertFrom(context, sourceType);
            }
    
            public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
            {
                if (!(value is string))
                {
                    return base.ConvertFrom(context, culture, value);
                }
    
                List<string> result = new List<string>();
                var arrayExtension = (ArrayExtension)value;
                var sourceList = (System.Collections.IList)value;
    
                if (sourceList != null)
                {
                    foreach (var item in sourceList)
                    {
                        result.Add(item.ToString());
                    }
                    return result.ToArray();
                }
                if (arrayExtension != null)
                {
                    foreach (var item in arrayExtension.Items)
                    {
                        result.Add(item.ToString());
                    }
                    return result.ToArray();
                }
                else
                {
                    string list = ((string)value).Trim();
                    if (string.IsNullOrEmpty(list))
                    {
                        return new string[0];
                    }
    
                    string[] tokens = list.Split(',');
                    for (int index = 0; index < tokens.Length; index++)
                    {
                        string token = tokens[index].Trim();
                        if (!string.IsNullOrEmpty(token))
                        {
                            result.Add(token);
                        }
                    }
                }
                return result.ToArray();
            }
    
            public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
            {
                if (destinationType == typeof(InstanceDescriptor))
                {
                    return true;
                }
                return base.CanConvertTo(context, destinationType);
            }
    
            public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture,
                object value, Type destinationType)
            {
                if (destinationType == null)
                {
                    throw new ArgumentNullException("destinationType");
                }
    
                if ((destinationType == typeof(string)) && (value is string[]))
                {
                    return string.Join(",", (string[])value);
                }
    
                if ((destinationType == typeof(ArrayExtension)) && (value is string[]))
                {
                    return new ArrayExtension((string[])value);
                }
    
                return base.ConvertTo(context, culture, value, destinationType);
            }
        }
    <Window x:Class="SampleWpf.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        xmlns:toolkit="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit"
        xmlns:local="clr-namespace:WPFExample;assembly=WPFExample"
        Title="Window1" Height="400" Width="528" Loaded="Window_Loaded">
    
        <Window.Resources>
            <local:TableView  x:Key="peopleView" TableName="Person" >
                <local:TableView.Fields>
                    <local:Field Name="Frerence" >
                        <local:Field.KeyFieldNames>
                            <x:Array Type="{x:Type sys:String}">
                                <sys:String>RowId</sys:String>
                            </x:Array>
                        </local:Field.KeyFieldNames>
                        <local:Field.LookupKeyFieldNames>
                            <x:Array Type="{x:Type sys:String}">
                                <sys:String>PersonId</sys:String>
                            </x:Array>
                        </local:Field.LookupKeyFieldNames>
                    </local:Field>
                </local:TableView.Fields>
                <local:TableView.IsOpened>true</local:TableView.IsOpened>
            </local:TableView>
    
            <ObjectDataProvider x:Key="peopleDataProvider" ObjectInstance="{StaticResource peopleView}"/>
        </Window.Resources>
    • Edited by mrUmka Tuesday, August 25, 2009 2:42 AM
    Tuesday, August 25, 2009 2:29 AM