2013-05-28 1 views
1

C#에서는 _ResizeEnd 이벤트를 DataGridView 컨트롤에 추가하려고합니다. 나는 이것을 (사용자 컨트롤에 _ResizeEnd 이벤트를 추가 할 수 있도록) 도와주는 코드를 발견했다._Load 이벤트를 컨트롤에 추가하려면 어떻게해야합니까?

private void UserControl1_Load(object sender, EventArgs e) 
{ 
((Form)this.Parent).ResizeEnd += new EventHandler(UserControl1_ResizeEnd); 
} 
void UserControl1_ResizeEnd(object sender, EventArgs e) 
{ 
MessageBox.Show("Resize end"); 
} 

앞서 언급했듯이, 나는 이것을 DataGridView에 추가하기를 원합니다. 내가 할 수있는 UserControl 만들고 DataGridView 컨트롤을 덤프 및 위의 코드에 따라 _ResizeEnd 이벤트를 구현하는 것입니다.

그러나 문제는 DataGridView의 모든 속성, 메서드 및 이벤트를 디자이너에서 계속 노출되도록하려는 것입니다. 나는 모든 get/set/events/methods 등을 쓰지 않고 부모 컨트롤에 자식 컨트롤 메서드를 노출하는 등의 쉬운 방법을 알지 못합니다.

변경할 수 있다고 생각했습니다. 공공 부분 클래스 MyDataGridView :로부터 상속 UserControl을 사람 : 공공 부분 클래스 MyDataGridView : DataGridView에 이것은 UserControl을에 노출 된 모든 DataGridView에 속성 등을 가지고있는 문제를 해결하지만, 물론이 나를 움직이지 않는

DataGridView 클래스 (UserControl 클래스와 달리)에는 _Load 이벤트가 없으므로 전달할 수 있습니다.

이렇게 .... 아무도이 문제를 해결하는 방법을 말해 줄 수 있습니까?

편집 : 그런데 ... 난 이해 서브 클래스가 될 것이라고 :

public partial class MyDataGridView : DataGridView 

이 등등 된 DataGridView 속성을 노출 않지만, 나는 잃을 : 더 _load 이벤트가 없음을 의미 UserControl을 상속 드러난.

내가 UserControl을 속성/방법과 DataGridView에 속성 등

+1

당신이 여기처럼, 당신은 ParentChanged 이벤트가 아닌로드 이벤트를 원하는 부모에 대해 알고 싶다면 다음과 같습니다. 문제 해결됨. –

답변

1

모두를 상속하는 방법을 잘 모르겠어요 왜 당신이 Load 이벤트 내부의 ResizeEnd을 설정해야합니까? 하위 클래스 인 DataGridView (기존 속성 및 이벤트를 모두 얻는 가장 좋은 방법)을 설정 한 다음 MyDataGridView 내부에 이벤트 처리기를 설정해야하는 이유는 무엇입니까? 부모님이 원하는 것은 모두 부모님이므로 ParentChanged 이벤트에 응답하시는 것이 좋습니다. 아래는 (필자는 부모가 이제까지 변경됩니다 생각하지 않는다 있습니다,하지만 사람들은 펑키 일을 할 수있다 :)) 나를 위해 작동 :

public class CustomDataGridView : DataGridView 
{ 
    private Form _curParent; 

    public CustomDataGridView() 
    { 
     // Since Parent is not set yet, handle the event that tells us that it *is* set 
     this.ParentChanged += CustomDataGridView_ParentChanged; 
    } 

    void CustomDataGridView_ParentChanged(object sender, EventArgs e) 
    { 
     if (this.Parent is Form) 
     { 
      // be nice and remove the event from the old parent 
      if (_curParent != null) 
      { 
       _curParent.ResizeEnd -= CustomDataGridView_ResizeEnd; 
      } 

      // now update _curParent to the new Parent 
      _curParent = (Form)this.Parent; 

      _curParent.ResizeEnd += CustomDataGridView_ResizeEnd; 
     } 
    } 

    void CustomDataGridView_ResizeEnd(object sender, EventArgs e) 
    { 
     System.Diagnostics.Debug.WriteLine("Resize End called on parent. React now!"); 
    } 
} 
+0

제가 아는 한 (저는 전문가가 아닙니다!) 생성자에 넣으면 생성자가 호출 될 때 컨트롤이로드되지 않았으므로 부모가 없습니다. 양식)에서 'ResizeEnd' 이벤트를 잡을 수 있습니다. 'load' 이벤트를 사용하면 컨트롤에 부모가 생깁니다. 서브 클래 싱에 대한 정보를 보내 주셔서 감사합니다. 그 방법을 모르는 경우 (이전에 Visual Basic 6에서만 수행 했음). 나는 그것을 연구 할 것이다. – ainwood

+0

좋은 포인트 - 업데이트 된 답변. – Oren

+0

OK - 감사합니다. 이 코드는 훌륭하게 작동합니다. 다른 문제를 발견했습니다. 'CustomDataGridView'가 폼에 직접 배치 될 때 잘 동작합니다. 컨트롤이 폼의 다른 컨테이너에 배치 될 때 작동하지 않습니다.재귀 적 접근법을 사용하여 부모 계층 구조를 반복하여 트리의 맨 위에있는 폼을 찾으려고했지만, ParentChanged 이벤트가 발생했을 때 Parent가 분명히 Null이기 때문에 어떤 이유로 작동하지 않습니다. (go figure ...)'while (! (parentForm is Form)) {parentForm = parentForm.Parent;}'(이 주석에서 꽤 형식화되지 않습니다!) – ainwood

0

OK - 모든 도움을 주셔서 감사합니다. 최종 작업 코드는 (은 정제가 필요한 경우 제안을 열어!)

public partial class MyDataGridView : DataGridView 
    { 
     private Form _curParent = null; 
     protected override void OnInvalidated(InvalidateEventArgs e) 
     { 
      //Exit if no parent, or _curParent already set. 
      if (Parent == null || _curParent != null) return; 

      base.OnInvalidated(e); 

      //Recurse until parent form is found: 
      Control parentForm = Parent; 

      while (!(parentForm is Form)) 
      { 
       if (parentForm.Parent == null) return; //Break if this is a null - indicates parent not yet created. 
       parentForm = parentForm.Parent; 
      } 

      //Have now found parent form at the top of the ancestor tree. 
      // be nice and remove the event from the old parent 
      if (_curParent != null) 
      { 
       _curParent.ResizeEnd -= MyDataGridView_ResizeEnd; 
      } 
      // now update _curParent to the new Parent 
      _curParent = (Form)parentForm; 

      //Add the resized event handler 
      _curParent.ResizeEnd += MyDataGridView_ResizeEnd; 

     } 


     void MyDataGridView_ResizeEnd(object sender, EventArgs e) 
     { 
      System.Diagnostics.Debug.WriteLine("Resize End called on parent. React now!"); 
     } 
    } 
+0

니스! 몇 가지 의견 : 1. base.OnInvalidated는 항상 호출해야하므로 처음에는 필요하다. (사실, 전체 감지 로직을 if와 call base에 넣는다. 무효화하면 크기가 조정된다.) 2. 두 번째'(_curParent! = null)'검사는 사실 일 수 없으므로 유효하지 않습니다 (이것이 사실이라면 위의 "반환"). Grid를 동적으로 움직이지 않는다면이 경우에 신경 쓰지 않아도됩니다. – Oren

관련 문제