函数同时包含PictureBox和DataGridViewImageCell

时间:2013-01-22 16:09:00

标签: c# winforms datagridview picturebox

我正在创建一个类来帮助修改GUI中的图像。图片可以是PictureBoxDataGridViewImageCell。该类将列出所有可修改的图像作为列表。该类的每个实例都将使用PictureBoxDataGridViewImageCells,但不能同时使用两者。

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

1 个答案:

答案 0 :(得分:3)

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

class MyClass
{
    public void AddImage(PictureBox image)
    {

    }

    public void AddImage(DataGridViewImageCell image)
    {

    }
}

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

对于共享类,我相信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!