尽管在代码

时间:2015-10-13 14:29:04

标签: c# winforms

我显然有一个糟糕的一天,因为这个应该很容易,我没有看到它。啊!

我创建了一个派生自Panel的控件,它将作为某些“Tiles”的容器,它们本身也是从Panel派生的子类。所以它基本上只是在一个大面板中托管的多个面板 每个“Tile”上都有一个PictureBox,如果设置了它将显示一个图标,如果没有则显示一个占位符。

一切似乎都很好,但是尽管我在创建它时将图像传递到Tile对象,但属性仍然为null并显示错误图标。

这是一个简化版本,您应该能够粘贴到空白的Winform中。当然,您需要提供自己的图片,我建议您只抓一个HERE

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        Height = 500;
        Width = 500;

        MyPanel myPanel = new MyPanel();
        myPanel.BackColor = Color.White;
        myPanel.BorderStyle = BorderStyle.FixedSingle;
        myPanel.Height = Height - 50;
        myPanel.Width = 200;
        myPanel.Top = 5;
        myPanel.Left = 5;
        Controls.Add(myPanel);

        // I'M SETTING THE IMAGE AT CREATION, THE FILE IS DEFINITELY VALID
        MyPanel.Tile tile = new MyPanel.Tile();
        tile.TileIcon = Image.FromFile(@"path/to/file");
        tile.BackColor = Color.PowderBlue;
        myPanel.AddTile(tile);

        MyPanel.Tile tile2 = new MyPanel.Tile();
        tile2.TileIcon = Image.FromFile(@"path/to/file");
        tile2.BackColor = Color.PeachPuff;
        myPanel.AddTile(tile2);
    }    
}

class MyPanel : Panel
{
    private const int TILEHEIGHT = 75;
    private static List<Panel> tileIndex = new List<Panel>();

    public MyPanel() { }

    public void AddTile(Tile tile)
    {
        tile.Width = this.Width;
        tile.Anchor = AnchorStyles.Left | AnchorStyles.Right;
        tile.Top = tileIndex.Count * TILEHEIGHT;
        tileIndex.Add(tile);
        this.Controls.Add(tile);
    }

    public class Tile : Panel
    {
        // PROPERTY FOR IMAGE
        private Image _tileIcon;
        public Image TileIcon
        {
            get { return _tileIcon; }
            set { _tileIcon = value; }
        }

        public Tile()
        {
            base.Height = TILEHEIGHT;
            base.Left = 0;
            base.Top = 0;
            base.BackColor = ColorTranslator.FromHtml("#FF5555");

            // DISPLAY IMAGE IN PICTUREBOX
            // ALWAYS NULL!?
            PictureBox _picBox = new PictureBox();
            _picBox.SizeMode = PictureBoxSizeMode.StretchImage;
            if (_tileIcon != null)
            { _picBox.Image = _tileIcon; }
            else
            { _picBox.Image = Image.FromFile(@"path/to/file"); }

            _picBox.Left = 5;
            _picBox.Top = 5;
            _picBox.Height = (this.Height - 10);
            _picBox.Width = _picBox.Height;

            this.Controls.Add(_picBox);
        }
    }
}

错误
enter image description here

从右
enter image description here

谢谢!

1 个答案:

答案 0 :(得分:1)

这应该解决它。我将图像传递给构造函数。

问题正如我在评论中所说的那样,在构造函数中你还没有设置_tileIcon,所以它总是为空。您可以在构造函数之后设置它,但不要重新初始化图片框以使用该图像。您需要重置集合中的图片框才能工作。

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        Height = 500;
        Width = 500;

        MyPanel myPanel = new MyPanel();
        myPanel.BackColor = Color.White;
        myPanel.BorderStyle = BorderStyle.FixedSingle;
        myPanel.Height = Height - 50;
        myPanel.Width = 200;
        myPanel.Top = 5;
        myPanel.Left = 5;
        Controls.Add(myPanel);

        var icon1 = Image.FromFile(@"path/to/file");  //Load the image FIRST
        MyPanel.Tile tile = new MyPanel.Tile(icon1);  //Pass it into the constructor
        tile.BackColor = Color.PowderBlue;
        myPanel.AddTile(tile);

        var icon2 = Image.FromFile(@"path/to/file");  //Again, image first
        MyPanel.Tile tile2 = new MyPanel.Tile(icon2); //Then construct
        tile2.BackColor = Color.PeachPuff;
        myPanel.AddTile(tile2);
    }    
}

class MyPanel : Panel
{
    private const int TILEHEIGHT = 75;
    private static List<Panel> tileIndex = new List<Panel>();

    public MyPanel() { }

    public void AddTile(Tile tile)
    {
        tile.Width = this.Width;
        tile.Anchor = AnchorStyles.Left | AnchorStyles.Right;
        tile.Top = tileIndex.Count * TILEHEIGHT;
        tileIndex.Add(tile);
        this.Controls.Add(tile);
    }

    public class Tile : Panel
    {
        private PictureBox _picBox;

        // PROPERTY FOR IMAGE
        private Image _tileIcon;
        public Image TileIcon
        {
            get { return _tileIcon; }
            //Obviously needs additional logic for null images...
            set { _tileIcon = value; _picBox.Image = _tileIcon; }
        }

        public Tile(Image tileIcon = null)
        {
            _tileIcon = tileIcon;
            base.Height = TILEHEIGHT;
            base.Left = 0;
            base.Top = 0;
            base.BackColor = ColorTranslator.FromHtml("#FF5555");

            // Now this won't be null, and save a reference to the
            //_picBox so you can easily change the image later through
            //the icon property.
            _picBox = new PictureBox();
            _picBox.SizeMode = PictureBoxSizeMode.StretchImage;
            if (_tileIcon != null)
            { _picBox.Image = _tileIcon; }
            else
            { _picBox.Image = Image.FromFile(@"path/to/file"); }

            _picBox.Left = 5;
            _picBox.Top = 5;
            _picBox.Height = (this.Height - 10);
            _picBox.Width = _picBox.Height;

            this.Controls.Add(_picBox);
        }
    }
}