2013-10-08 1 views
0

기본 폼에 TabControl이있는 C# 양식 응용 프로그램이 있습니다. 이 TabControl은 CustomControl이 포함 된 다중 탭 페이지를 표시하는 데 사용됩니다. 이 CustomControl은 몇 개의 버튼과 PictureBox가있는 패널입니다.내 WinForms 응용 프로그램 생성자 내에서 TabControl에 탭 페이지를 추가 할 수 없습니다.

다음은 내 앱을 시작할 때의 사진입니다. 당신은 탭 컨트롤 (흰색 영역)을 볼 수있는 것처럼 비어 : 사용자가 클릭

App Started With Empty Tab Control

경우 그들이 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; 
} 

당신은 내가 비트 맵, CustomControl 및 TabPage를 만든 다음에 TabControl로를 삽입 addImage 방법에서 볼 수 있듯이.

내 응용 프로그램을 시작하고 "이미지 추가"버튼을 클릭하면 모든 것이 잘 작동합니다. 여기

는 탭 페이지에 사진이 추가됩니다

App With A Tab Page Added

내가 수동으로 OpenFileDialog를 매번 사용하여 이미지를 추가 할 필요가 내 응용 프로그램을 내가 원하지 않는 테스트입니다 동안 내 생성자에서 이렇게 난 그냥 함께 테스트 할 몇 가지 고정 된 이미지 파일 이름으로 addImage 전화 :

public ImageViewerApp() 
{ 
    InitializeComponent();   
    addImage(@"C:\MyImages\Calculator-3-icon.png"); 
} 

오전 데 문제가 내 생성자에서 이미지를 추가하려고 할 때 TabControl에 표시되지 않습니다. 응용 프로그램이 공백으로 시작됩니다 (첫 번째 사진과 같습니다).

위에서 언급했듯이 응용 프로그램이 이미 실행 중이고 "이미지 추가"버튼을 클릭하면 잘 추가됩니다.

"Gets a value indicating whether the control has been created" 

을 그래서 시도하고 내가 전화하기 직전에 콘솔에을 만든 의 값을 쓰기에 무슨 일이 일어나고 있는지 알아 내려고 :

나는 상태 만든 라는있는 TabControl 클래스의 속성을 발견 addImage 생성자에. (내 양식 응용 프로그램을 디버깅하기위한 사용자 지정 콘솔이 있습니다.)

public ImageViewerApp() 
{ 
    InitializeComponent(); 
    TestConsole.WriteLine(imagesTabControl.Created); 
    addImage(@"D:\Development\Work\Other\Stardock\Start8\_downloaded\Calculator-3-icon.png"); 
} 

생성자에서 addImage에 바로 호출 이전을 만든 의 값은 다음과 같습니다

private void doAddImage() 
{ 
    TestConsole.WriteLine(imagesTabControl.Created); 
    OpenFileDialog openFileDialog = new OpenFileDialog(); 
    ... 
    ... 
} 
:
False 

은 내가 addImage 방법 내에서 다른 콘솔 출력을 넣어

Cre 호텔 값 앱을 시작하고 사용자가 "추가 이미지"를 누르면 후 ated에 버튼은 다음과 같습니다

진정한

가 왜 TabControl에 내 생성자 내부을 만든 이 아니라고 그 것이다 (심지어의 InitializeComponent() 호출 후) 그리고 일단 응용 프로그램이 실행되면 이 생성됩니다.?

= UPDATE =========================================== ============================= 내 addImage 방법에 다음 코드를 추가 한 Hans Passant에 의해 제안을 바탕으로 :

int selectedTabIndex = -1; 
if (imagesTabControl.TabCount > 0) 
{ 
    selectedTabIndex = imagesTabControl.SelectedIndex; 
} 
else 
{ 
    selectedTabIndex = imagesTabControl.SelectedIndex + 1; 
} 

imagesTabControl.TabPages.Insert(selectedTabIndex, tabPage); 
imagesTabControl.SelectedIndex = selectedTabIndex; 

이것은 작동하지 않습니다. ================================================ ===============================

= UPDATE2 =========== ========================================================================================================== ==================

{"InvalidArgument=Value of '-1' is not valid for 'index'.\r\nParameter name: index"} 

: ==========

int selectedTabIndex = imagesTabControl.SelectedIndex; 
if (imagesTabControl.TabCount == 0) selectedTabIndex = -1; 

imagesTabControl.TabPages.Insert(selectedTabIndex, tabPage); 
imagesTabControl.SelectedIndex = selectedTabIndex; 

이 다음과 같은 예외가 발생합니다 ===================================================================================================== ============

= 갱신 3 ============================== =========================

나는 다음을 시도했다. 코드 :이 하나가 예외 그러나 다시 생성자에서 addImage를 호출 한 후 추가없이 탭 페이지를 throw하지 않습니다

int selectedTabIndex = imagesTabControl.SelectedIndex; 
if (imagesTabControl.TabCount == 0) selectedTabIndex = -1; 

imagesTabControl.TabPages.Insert(selectedTabIndex + 1, tabPage); 
imagesTabControl.SelectedIndex = selectedTabIndex + 1; 

. ================================================ ===============================

= 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)); 
}  

를이 내가 내가 OpenFileDialog를을 건너 뛰고 TEST_MODE 동안 "이미지 추가"버튼을 클릭하면 지금. 작동 임의의 이미지를 추가 할 수 있습니다.

내가 TabControl에와 있지만 난 그냥 개발을 계속하기 위해 필요한이 시점에서 문제를 이해하고 싶습니다. 내 현재 솔루션 작동 좋아요.

내가 좋아하는 사람이 나는 것 모든 것을 이해하는 것처럼 다른 사람의 것을 사용하고 싶습니다 제안 사항이므로 솔루션에 대한이 질문을 계속 모니터링 할 것입니다. ================================ =================

+0

중단 점을 설정 한 경우 "보이지 않는"탭이 보이십니까? – Tico

+0

중단 점을 넣으려면 어디서 나옵니까? 생성자 또는 doAddImage() 메서드에서? –

+0

생성자에서 바로. "지역"탭을 확인하고 탭이 추가되었는지 확인하십시오. – Tico

답변

0

디자이너에서 TabControl을 제거한 다음 수동으로 만들 수 있습니다. TabControl 프로그래밍 방식으로 및 InitializeComponent() 바로 뒤에 폼에 추가하십시오. 그런 다음 TabControl을 만든 후 addImage()를 호출하십시오. 예 :

InitializeComponent(); 

    TabControl tc = new TabControl(); 
    tc.Location = new Point(10, 10); 
    tc.Size = new Size(100, 100);   
    tc.Visible = true; 
    tc.Anchor = (AnchorStyles.Bottom | AnchorStyles.Right | AnchorStyles.Left |   AnchorStyles.Top); 
    this.Controls.Add(tc) 
    addImage("c:\pathToImage\image.bmp"); 
+0

이것은 좋은 생각입니다. 그러나 앱을 시작한 후에 이미지를 추가하는 방법으로 해결할 것입니다. 감사! :) –

+0

문제 없습니다. 그건 의미가 있습니다. 다행히 해결 방법이 있습니다. –

0

나는이 문제도 가지고 있으며 해결 방법을 찾았습니다. 나는 Insert()와 버그 생각합니다 :

  1. Insert()를 사용하지 마십시오, 그것은 일반적으로 아무것도 대신 Add()를 사용하지 않는다; 이렇게하면 확실하게 컬렉션의 끝에 TabPage가 추가됩니다.

  2. 추가 한 후 실제로 원하는 탭 위치로 바꾸십시오.

imagesTabControl.TabPages.Add(tabPage); 
// Now swap the two tabs: 
imagesTabControl.TabPages[imagesTabControl.TabCount - 1] = imagesTabControl.TabPages[selectedTabIndex + 1]; 
imagesTabControl.TabPage[selectedTabIndex + 1] = tabPage; 

마일리지는


정지를 눌러 :-) 물론 다를 수 있습니다! 더 좋은 수정 Insert()를 호출하기 전에 클래스의 Handle 멤버를 읽을 수 있습니다 : 당신이 그렇게 한 후에

var handle = imagesTabControl.Handle;

Insert() 완벽하게 작동합니다. 분명하지 않습니까 ????

핸들 속성의 값이 윈도우 HWND입니다 : 핸들의 도움말 페이지는 Handle을 읽을 때 객체가 실제로 무언가를 보여주는이 가능한 관련 있습니다. 핸들이 아직 만들어지지 않은 경우이 속성을 참조하면 핸들이 만들어집니다.