我有一个 C# Form 应用程序,在主窗体中有一个 TabControl。此 TabControl 用于显示包含 CustomControl 的多个 TabPage。这个CustomControl 只是一个带有几个按钮和一个PictureBox 的面板。
这是我的应用程序启动时的图片。如您所见,选项卡控件(白色区域)为空:
如果用户单击“添加图像”按钮,他们会看到一个 OpenFileDialog 来选择图像,然后使用所选文件调用addImage方法:
private void doAddImage()
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = Constants.Global.IMAGE_FILE_FILTER();
if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
string imageFileName = openFileDialog.FileName;
addImage(imageFileName);
}
}
private void addImage(string imageFileName)
{
// Create a new bitmap and image preview custom control. Then create a new tab
// page and add the custom control to the tab page.
Bitmap bitMap = new Bitmap(imageFileName);
ImagePreviewCustomControl previewControl = new ImagePreviewCustomControl(bitMap);
previewControl.Dock = DockStyle.Fill;
TabPage tabPage = new TabPage(Path.GetFileNameWithoutExtension(imageFileName));
tabPage.Controls.Add(previewControl);
// Insert the new tab page to the right of the currently selected tab page
int selectedTabIndex = imagesTabControl.SelectedIndex;
imagesTabControl.TabPages.Insert(selectedTabIndex + 1, tabPage);
imagesTabControl.SelectedIndex = selectedTabIndex + 1;
}
如您所见,在addImage方法中,我创建了 Bitmap、CustomControl 和 TabPage,然后将其插入到 TabControl 中。
我启动我的应用程序,单击“添加图像”按钮,一切正常。
这是一张添加了标签页的图片:
当我测试我的应用程序时,我不想每次都使用 OpenFileDialog 手动添加图像,所以在我的构造函数中,我只需使用一些我想测试的固定图像文件名调用addImage :
public ImageViewerApp()
{
InitializeComponent();
addImage(@"C:\MyImages\Calculator-3-icon.png");
}
我遇到的问题是,当我尝试在构造函数中添加图像时,它不会显示在 TabControl 中。应用程序启动时是空白的(如第一张图片)。
如上所述,当应用程序已经运行并且我单击“添加图像”按钮时,它被添加就好了。
我在 TabControl 类中找到了一个名为Created的属性,其中指出:
"Gets a value indicating whether the control has been created"
因此,为了弄清楚发生了什么,我在构造函数中调用addImage之前将Created的值写入控制台。(我有一个自定义控制台来调试我的表单应用程序。)
public ImageViewerApp()
{
InitializeComponent();
TestConsole.WriteLine(imagesTabControl.Created);
addImage(@"D:\Development\Work\Other\Stardock\Start8\_downloaded\Calculator-3-icon.png");
}
在构造函数中调用addImage之前Created的值是:
False
我在addImage方法中放置了另一个控制台输出:
private void doAddImage()
{
TestConsole.WriteLine(imagesTabControl.Created);
OpenFileDialog openFileDialog = new OpenFileDialog();
...
...
}
应用程序启动并且用户按下“添加图像”按钮后Created的值是:
真的
为什么 TabControl 没有在我的构造函数中创建(即使在 InitializeComponent() 调用之后)并且一旦应用程序运行它就是Created?
=UPDATE================================================= ======================== 根据Hans Passant的建议,我在addImage方法中添加了以下代码:
int selectedTabIndex = -1;
if (imagesTabControl.TabCount > 0)
{
selectedTabIndex = imagesTabControl.SelectedIndex;
}
else
{
selectedTabIndex = imagesTabControl.SelectedIndex + 1;
}
imagesTabControl.TabPages.Insert(selectedTabIndex, tabPage);
imagesTabControl.SelectedIndex = selectedTabIndex;
这行不通。 ==================================================== ==============================
=UPDATE2================================================= ========================
int selectedTabIndex = imagesTabControl.SelectedIndex;
if (imagesTabControl.TabCount == 0) selectedTabIndex = -1;
imagesTabControl.TabPages.Insert(selectedTabIndex, tabPage);
imagesTabControl.SelectedIndex = selectedTabIndex;
这会导致以下异常:
{"InvalidArgument=Value of '-1' is not valid for 'index'.\r\nParameter name: index"}
==================================================== ==============================
=UPDATE3================================================= ========================
我尝试了以下代码:
int selectedTabIndex = imagesTabControl.SelectedIndex;
if (imagesTabControl.TabCount == 0) selectedTabIndex = -1;
imagesTabControl.TabPages.Insert(selectedTabIndex + 1, tabPage);
imagesTabControl.SelectedIndex = selectedTabIndex + 1;
这不会引发异常,但在构造函数中调用 addImage后再次没有添加标签页。 ==================================================== ==============================
=UPDATE4================================================= ========================
我有点放弃在构造函数中添加图像。因此,我使用的是枚举 RunMode 和该类型的变量 RUN_MODE。然后,如果 RUN_MODE == RunMode.TESTI 在我单击按钮时调用一个方法来添加随机图像。(没有使用 OpenFileDialog。我只是解析了固定目录 IMAGE_DIRECTORY 中的所有图像文件。
enum RunMode { NORMAL, TEST }
private static string IMAGE_DIRECTORY = @"D:\\Work\Images";
...
...
private void doAddImage()
{
if (RUN_MODE == RunMode.TEST)
{
addRandomImage();
return;
}
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = Constants.Global.IMAGE_FILE_FILTER();
if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
string imageFileName = openFileDialog.FileName;
addImage(imageFileName);
}
}
private void addRandomImage()
{
string[] allFiles = Directory.GetFiles(IMAGE_DIRECTORY);
List<string> imageFileNames = new List<string>();
foreach (string file in allFiles)
{
bool isImageFile = Constants.Global.IMAGE_EXTENSIONS.Contains(Path.GetExtension(file));
if (isImageFile)
{
imageFileNames.Add(file);
}
}
int randomIndex = new Random().Next(imageFileNames.Count);
addImage(imageFileNames.ElementAt(randomIndex));
}
这行得通。现在,当我在 TEST_MODE 期间单击“添加图像”按钮时,我会跳过 OpenFileDialog 并添加一个随机图像。
我想了解 TabControl 的问题,但此时我只需要继续开发。我目前的解决方案效果很好。
作为一个喜欢了解一切的人,我想使用其他人的建议,所以我会继续关注这个问题以寻求解决方案。 ==================================================== ==============================