2

我正在创建一个类来帮助修改 GUI 中的图像。图像可以是 aPictureBox或 a DataGridViewImageCell。该类将所有可以修改的图像存储为列表。该类的每个实例都将使用其中一个PictureBox或两个,DataGridViewImageCells但不能同时使用两者。

有没有办法处理两个输入?例如,它们之间是否有一些共同的接口,或者将它们转换为某个共同的父类的方法?

4

1 回答 1

3

好吧,您总是可以将它们视为object,但我建议您的类只为这两种类型提供两个重载:

class MyClass
{
    public void AddImage(PictureBox image)
    {

    }

    public void AddImage(DataGridViewImageCell image)
    {

    }
}

如何在内部存储它取决于您。也许你有一个List<object>你投入/退出的,或者你维护两个单独的列表,每个类型一个,或者你只是将每个列表添加image到包含对象的子集合中。

至于共享类,我从 MSDN 相信它们不共享基类,Object因此您必须坚持使用该类或用您自己的包含类包装它们。

编辑:这是一种使用包装接口和工厂处理它的更完整的方法。

首先,定义一个基于共享类型的接口(在本例中object),您可以使用它来传递图像:

public interface IImageWrapper
{
    object RawImage { get; }
}

public class PictureBoxImageWrapper : IImageWrapper
{
    public object RawImage { get; private set; }

    public PictureBoxMyImage(PictureBox image)
    {
        this.RawImage = image;
    }
}

public class DataGridViewImageCellImageWrapper : IImageWrapper
{
    public object RawImage { get; private set; }

    public DataGridViewImageCellImageWrapper(DataGridViewImageCell image)
    {
        this.RawImage = image;
    }
}

然后是用户 API 的一个简单工厂,用于包装图像在编译时安全地确定严格支持哪些图像类型:

public class ImageWrapperFactory
{
    public IImageWrapper Create(PictureBox image)
    {
        return new PictureBoxImageWrapper(image);
    }

    public IImageWrapper Create(DataGridViewImageCell image)
    {
        return new DataGridViewImageCellImageWrapper(image);
    }
}

然后您的显示类或视图可以接收这些IImageWrapper对象并将它们转换为可用类型:

public class MyDisplayClass
{
    private List<IImageWrapper> Images = new List<IImageWrapper>();

    public void AddImage(IImageWrapper image)
    {
        Images.Add(image);
    }

    private void AddImageToContainer(IImageWrapper image)
    {
        object rawImage = image.RawImage;

        if (rawImage is PictureBox)
            AddImageToContainerImpl((PictureBox)rawImage);
        else if (rawImage is DataGridViewImageCell)
            AddImageToContainerImpl((DataGridViewImageCell)rawImage);
        else
            throw new NotSupportedException();
    }

    private void AddImageToContainerImpl(PictureBox image)
    {
        //add to container
    }

    private void AddImageToContainerImpl(DataGridViewImageCell image)
    {
        //add to container
    }
}

一些示例用法:

PictureBox myImage = ...
MyDisplayClass myView = ...

myView.AddImage(ImageWrapperFactory.Create(myImage));

因此,图像的底层类型并没有被强制执行。如果您愿意,您可以更新工厂以返回强类型IImageWrapper对象,PictureBoxImageWrapper然后将显示类强类型化为它支持的对象,但这有点违背了目的(您也可以像我的第一个答案中那样强类型化PictureBox/ DataGridViewImageCell.

编辑:另一种方法是为您的“工厂”利用隐式运算符。这样,您的 API 只需“传递”原始图像对象,如果它们受支持,就会找到隐式运算符。如果不是,那么您将获得编译时异常:

public sealed class ImageWrapper
{
    public object RawData { get; private set; }

    private ImageWrapper(object rawData)
    {
        this.RawData = rawData;
    }

    public static implicit operator ImageWrapper(PictureBox image)
    {
        return new ImageWrapper(image);
    }

    public static implicit operator ImageWrapper(DataGridViewImageCell image)
    {
        return new ImageWrapper(image);
    }
}


PictureBox myImage = ...
ImageControl unsupportedImage = ... 
MyDisplayClass myView = ...

myView.AddImage(myImage); //OK!
myView.AddImage(unsupportedImage);// compile error!
于 2013-01-22T16:18:59.097 回答