简体   繁体   English

从 C# 到 vb6 的 COM 可见列表

[英]COM visible List from C# to vb6

I have ClassLibrary (in visual studio 2010 C#) with a class Car:我有 ClassLibrary(在 Visual Studio 2010 C# 中)和一个 Car 类:

[ClassInterface(ClassInterfaceType.AutoDual)]
[ProgId("ClassLibrary1.Car")]
public class Car
{
    public Car()
    {
        Name = "";
        Parts = new List<string>();
    }

    public string Name { get; set; }

    public List<string> Parts { get; set; }
}

But when I use it in vb6 project: there is no property "Parts": http://i.imgur.com/x4h3BMp.jpg?1但是当我在 vb6 项目中使用它时:没有属性“零件”: http : //i.imgur.com/x4h3BMp.jpg?1

What can I do to make property List<> visible?我该怎么做才能使属性List<>可见?

Of course, the file "AssemblyInfo.cs" contains:当然,文件“AssemblyInfo.cs”包含:

[assembly: ComVisible(true)]

PS I really do not want to create for each List the class, like this: PS我真的不想为每个List类创建,像这样:

public class Parts
{
    private List<string> _parts;

    public Parts()
    {
        _parts = new List<string>();
    }

    public void Add(string part)
    {
        _parts.Add(part);
    }

    public string GetAt(int index)
    {
        if (0 <= index && index < _parts.Count)
            return _parts[index];
        return "";
    }

    public void Clear()
    {
        _parts.Clear();
    }

    public int Count{ get{ return _parts.Count; } }
}

because there are too many.因为太多了。

COM does not support generic collections; COM 不支持泛型集合; you'll have to use an array or ArrayList instead:你必须使用数组或ArrayList来代替:

[ClassInterface(ClassInterfaceType.AutoDual)]
[ProgId("ClassLibrary1.Car")]
public class Car
{
    public Car()
    {
        Name = "";
        Parts = new string[];
    }

    public string Name { get; set; }

    public string[] Parts { get; set; }
}

If you want to use a List behind-the-scenes you could use a List<string> as a backing variable, then change the property accessors to translate the list to/from an array:如果您想在幕后使用List<string>您可以使用List<string>作为支持变量,然后更改属性访问器以将列表转换为/从数组转换:

[ClassInterface(ClassInterfaceType.AutoDual)]
[ProgId("ClassLibrary1.Car")]
public class Car
{

    private List<string> _Parts;

    public Car()
    {
        Name = "";
        _Parts = new List<string>();
    }

    public string Name { get; set; }

    public string[] Parts 
    { 
        get
        {
            return _Parts.ToArray();
        } 
        set
        {
            _Parts = new List<string>(value);
        } 
    }
}

I did not want to do so, but had:我不想这样做,但有:

[ClassInterface(ClassInterfaceType.AutoDual)]
[ProgId("ClassLibrary1.Car")]
public class Car
{
    public Car()
    {
        Name = "";
        Parts = new Parts();
    }

    public string Name { get; set; }

    public Parts Parts { get; set; }
}

[ClassInterface(ClassInterfaceType.AutoDual)]
[ProgId("ClassLibrary1.Parts")]
public class Parts : IList<string>
{
    private List<string> _parts;

    public Parts()
    {
        _parts = new List<string>();
    }

    #region IList<string> Members

    public int IndexOf(string item)
    {
        return _parts.IndexOf(item);
    }

    public void Insert(int index, string item)
    {
        _parts.Insert(index, item);
    }

    public void RemoveAt(int index)
    {
        _parts.RemoveAt(index);
    }

    public string this[int index]
    {
        get
        {
            return _parts[index];
        }
        set
        {
            _parts[index] = value;
        }
    }

    #endregion

    #region ICollection<string> Members

    public void Add(string item)
    {
        _parts.Add(item);
    }

    public void Clear()
    {
        _parts.Clear();
    }

    public bool Contains(string item)
    {
        return _parts.Contains(item);
    }

    public void CopyTo(string[] array, int arrayIndex)
    {
        _parts.CopyTo(array, arrayIndex);
    }

    public int Count
    {
        get { return _parts.Count; }
    }

    public bool Remove(string item)
    {
        return _parts.Remove(item);
    }

    #endregion

    #region ICollection<string> Members


    public bool IsReadOnly
    {
        get { throw new NotImplementedException(); }
    }

    #endregion

    #region IEnumerable<string> Members

    public IEnumerator<string> GetEnumerator()
    {
        throw new NotImplementedException();
    }

    #endregion

    #region IEnumerable Members

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        throw new NotImplementedException();
    }

    #endregion
}

In vb6:在 vb6 中:

Option Explicit
Dim car As New ClassLibrary1.car
Dim parts As New ClassLibrary1.parts

Private Sub Form_Load()

    parts.Add "wheel"
    parts.Add "door"
    parts.Add "hood"
    parts.Add "trunk"

    car.Name = "GAS-24"
    Set car.parts = parts
    car.parts.RemoveAt (0)
End Sub

Drawback of this approach is a lot of code:(这种方法的缺点是代码很多:(

Let me know, if anyone knows something like this:让我知道,如果有人知道这样的事情:

//**[MakeVisibleListInVB6]**
[ClassInterface(ClassInterfaceType.AutoDual)]
[ProgId("ClassLibrary1.Car")]
public class Car
{
    public Car()
    {
        Name = "";
        Parts = new Parts();
    }

    public string Name { get; set; }

    public List<string> Parts { get; set; }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM