访问兄弟控件实例化的对象

Access objects instantiated by sibling control

作为 C# 和 OOP 的新手,我在范围和访问方面遇到了一些新手问题,其中之一是:当主窗体加载 class Doc 的实例时,会创建一个构造函数打开 Word 文档并创建文档中所有图像的列表。列表中的第一张图片显示在图片框中,如下所示:

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

    public class Doc {
        public List<Image> images = new List<Image>();
        public Doc(string path) {
            // Open Word document, create list of images
        }
    }

    private void Form1_Load(object sender, EventArgs e) {
        Doc doc = new Doc("C:\lorem_ipsum.doc");
        pictureBox1.Image = doc.images[0];
    }

    private void numericUpDown1_ValueChanged(object sender, EventArgs e) {
        pictureBox1.Image =  doc.images[numericUpDown1.Value];
    }
}

还有一个numericUpDown控件应该用来显示不同的图片,这就是问题所在。上面示例中的最后一段代码不起作用,但我希望它能说明我想做什么。

这个问题的最佳实践解决方案是什么(以及一个控件应该能够访问其他控件创建的对象的类似问题)?我也尝试通过为 Doc class 创建一个方法来解决它,但是从那里访​​问图片框时遇到了问题。

只需将 doc 设为 Form1 的私有字段即可。

public partial class Form1 : Form {
    private Doc doc;

    public Form1() {
        InitializeComponent();
    }

    public class Doc {
        public List<Image> images = new List<Image>();
        public Doc(string path) {
            // Open Word document, create list of images
        }
    }

    private void Form1_Load(object sender, EventArgs e) {
        doc = new Doc("C:\lorem_ipsum.doc");
        pictureBox1.Image = dok.images[0];
    }

    private void numericUpDown1_ValueChanged(object sender, EventArgs e) {
        pictureBox1.Image =  doc.images[numericUpDown1.Value];
    }
}

你的 doc 有一个局部变量,即它是 Form1_Load 的局部变量。这意味着它只存在于该方法中。你想要的是一个成员字段,定义在 Form1 class 本身。只要表单存在,它就会一直存在:

public partial class Form1 : Form
{
    private Doc m_Doc;

    ....

    private void Form1_Load(object sender, EventArgs e)
    {
        m_Doc = new Doc("C:\lorem_ipsum.doc");
        pictureBox1.Image = m_Doc.images[0];
    }

    private void numericUpDown1_ValueChanged(object sender, EventArgs e)
    {
        pictureBox1.Image = m_Doc.images[numericUpDown1.Value];
    }
}

现在 m_Doc 可以被 class 中的任何东西访问(也可以被嵌套的 class 访问),但除此之外别无他法,因为它是 private

我还选择添加 m_ 后缀。没有必要,人们会整夜争论什么惯例最好,但这就是我喜欢的!

您的问题是您将 doc 创建为局部变量。你需要一个class:

范围内的成员变量
public partial class Form1 : Form {
    private Doc _doc; // Add this line

    public Form1() {
        InitializeComponent();
    }

    public class Doc {
        public List<Image> images = new List<Image>();
        public Doc(string path) {
            // Open Word document, create list of images
        }
    }

    private void Form1_Load(object sender, EventArgs e) {
        _doc = new Doc("C:\lorem_ipsum.doc");
        pictureBox1.Image = _doc.images[0];
    }

    private void numericUpDown1_ValueChanged(object sender, EventArgs e) {
        pictureBox1.Image =  _doc.images[numericUpDown1.Value];
    }
}

范围小知识

public class MyClass
{
    // myMemberVariable is declared inside class, but outside
    // a function. Therefore, it can be accessed from anywhere
    // inside the class.
    int myMemberVariable;

    public void MyFunction()
    {
        // myLocalVariable is declared inside a function. Therefore,
        // it can be accessed only inside this function and nowhere
        // else.
        int myLocalVariable;

        for (int x=0;x<10;x++)
        {
            // anotherLocalVariable is declared inside a for loop. Therefore,
            // this variable can only be used inside this for loop and
            // no where else.
            int anotherLocalVariable;
        }
    }
}

将大括号视为范围分隔符。您创建的变量只能在左大括号和右大括号内使用,而不能在外面使用。唯一的 "partial" 例外是 static 变量。