2012-06-06 20 views
10

WinForm .NET 3.5 (C#)Wyświetlacz kontroli użytkownika w DataGridViewCell

Mam DataGridView (DGView) i stworzyłem CustomColumn i CustomCell być wyświetlane w DGView. Stworzyłem CustomUserControl, który chcę wyświetlić w CustomCell.

Problem: Nie widzę kontroli użytkownika w kolumnie. Myślę, że muszę przesłonić metodę Paint() w CustomCell - Jakieś punkty, jak mogę to zrobić?

Uwaga - Przykładem hostingu MSDN dla hostingu jest edycja wartości komórki - dzięki czemu kontrola użytkownika jest widoczna w miejscu, w którym edytujesz komórkę. Chcę, aby moja kontrola użytkownika była renderowana jako normalna kontrola WinForm. Ta kontrolka użytkownika pokazuje powiadomienia dla wiersza .. i każdy wiersz może mieć różne powiadomienia. Chcę, aby użytkownicy mogli kliknąć powiadomienie i uzyskać więcej informacji na jego temat. ... ale na razie utknąłem w "jak wyświetlić tę kontrolę użytkownika". Wszystkie wskaźniki będą wysoko cenione.

public class CustomColumn : DataGridViewColumn { 
    public CustomColumn() : base(new CustomeCell()) { } 
    public override DataGridViewCell CellTemplate 
    { 
     get 
     { 
      return base.CellTemplate; 
     } 
     set 
     { 
      // Ensure that the cell used for the template is a CalendarCell. 
      if (value != null && 
       !value.GetType().IsAssignableFrom(typeof(CustomeCell))) 
      { 
       throw new InvalidCastException("It should be a custom Cell"); 
      } 
      base.CellTemplate = value; 
     } 
    } 
} 
public class CustomeCell : DataGridViewTextBoxCell 
{ 
    public CustomeCell() : base() { } 
    public override Type ValueType 
    { 
     get 
     { 
      return typeof(CustomUserControl); 
     } 
    } 
    public override Type FormattedValueType 
    { 
     get 
     { 
      return typeof(CustomUserControl); 
     } 
    } 
} 
+0

Należy również zdefiniować klasę, która pochodzi od sterowania i implementuje interfejs IDataGridViewEditingControl. –

+0

@AngshumanAgarwal Jak wspomniałem w moim pytaniu - nie chcę edytować, chcę tylko wyświetlić moją kontrolę użytkownika dla wszystkich wierszy w jednej kolumnie. – karephul

+0

Nie rozumiem dokładnie .. ale chcesz pokazać wartości komórek nie pokazane datagridview do użytkownika? (jeśli użytkownik kliknął raz w komórkę), jeśli tak, to po prostu skorzystaj z ToolTip z SQLQuery lub LINQ – sihirbazzz

Odpowiedz

4

Pierwsza próba: Próbowałem umieścić kontrolkę użytkownika na siatce, gdzie potrzebowałem. Problem: Przewijanie widoku siatki danych wymaga ponownego rozmieszczenia wszystkich elementów sterujących użytkownika. Wynik - Odrzucono.

Druga próba: Zbudowałem kontrolkę użytkownika i namalowałem ją w odpowiedniej komórce. Wynik - działa do tej pory.

Właśnie przeszedłem Paint i OnClick metod DataGridViewCell w klasie CustomCell.

public class CustomeCell : DataGridViewCell 
{ 
    public override Type ValueType 
    { 
     get { return typeof(CustomUserControl); } 
    } 

    protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts) 
    { 
     var ctrl = (CustomUserControl) value; 
     var img = new Bitmap(cellBounds.Width, cellBounds.Height); 
     ctrl.DrawToBitmap(img, new Rectangle(0, 0, ctrl.Width, ctrl.Height)); 
     graphics.DrawImage(img, cellBounds.Location); 
    } 

    protected override void OnClick(DataGridViewCellEventArgs e) 
    { 
     List<InfoObject> objs = DataGridView.DataSource as List<InfoObject>; 
     if (objs == null) 
      return; 
     if (e.RowIndex < 0 || e.RowIndex >= objs.Count) 
      return; 

     CustomUserControl ctrl = objs[e.RowIndex].Ctrl; 
     // Take any action - I will just change the color for now. 
     ctrl.BackColor = Color.Red; 
     ctrl.Refresh(); 
     DataGridView.InvalidateCell(e.ColumnIndex, e.RowIndex); 
    } 
} 

Przykład czyni CustomControl w The CustomCell z CustomColumn). Gdy użytkownik kliknie komórkę, obsługuje kliknięcie CustomCell. Idealnym rozwiązaniem byłoby delegowanie tego kliknięcia do niestandardowego kontrolera użytkownika, który powinien obsługiwać zdarzenie tak, jakby było kliknięciem w siebie (niestandardowa kontrola użytkownika może wewnętrznie hostować wiele kontrolek) - tak więc jego mały kompleks.

public class CustomColumn : DataGridViewColumn 
{ 
    public CustomColumn() : base(new CustomeCell()) { } 

    public override DataGridViewCell CellTemplate 
    { 
     get { return base.CellTemplate; } 
     set 
     { 
      if (value != null && !value.GetType() 
       .IsAssignableFrom(typeof (CustomeCell))) 
       throw new InvalidCastException("It should be a custom Cell"); 
      base.CellTemplate = value; 
     } 
    } 
} 
+0

Połączyłem to rozwiązanie z wzorcem masy. To jest niesamowite - działa świetnie. – karephul

1

Kontrolka DataGridView obsługuje wyświetlanie rzeczywistej kontroli tylko wtedy, gdy komórka jest w trybie edycji. Formant DataGridView nie jest zaprojektowany do wyświetlania wielu elementów sterujących lub powtarzania zestawu elementów sterujących w wierszu. Formant DataGridView rysuje reprezentację kontrolki, gdy komórka nie jest edytowana. Ta reprezentacja może być szczegółowa, jak chcesz. Na przykład DataGridViewButtonCell rysuje przycisk niezależnie od tego, czy komórka jest edytowana czy nie.

Można jednak dodać kontroli przez DataGridView.Controls.Add() metoda, i ustawić ich położenie i rozmiar, aby ich gospodarzem w komórkach, but showing controls in all cells regardless of editing make no sense.

Przeczytaj here

[Aktualizacja - z MS DataGridView zespołu Prog Mgr]

http://social.msdn.microsoft.com/Forums/en-US/winformsdatacontrols/thread/394e04a8-d918-4fdd-be03-dfa13f6a1e66?persist=True

+1

MS nie obsługuje czegoś jest inne - ale nie zgadzam się z "ale pokazywanie kontroli we wszystkich komórkach bez względu na edycję nie ma sensu." - Weź pod uwagę, że przeglądasz listę zamówień klientów - każde zamówienie może mieć różne powiadomienia (brak ekwipunku, niepełny adres, zduplikowane zamówienie, zamówienie z powrotem itp.) Chciałbym, aby moi użytkownicy "przeglądali" te powiadomienia - najlepiej w kolumnie o nazwie Powiadomienia! - bez możliwości ich edycji !! - ale zobacz więcej szczegółów, jeśli klikną jeden z nich. – karephul

+0

Interesujące! Możesz przeczytać komentarze _DataGridView programu Manager Manager_. Zaktualizowałem odpowiedź za pomocą łącza msdn. –

+0

Nie zgadzam się ani z "ale pokazywanie kontroli we wszystkich komórkach bez względu na edycję nie ma sensu." Właśnie znalazłem to pytanie, ponieważ chciałbym umieścić niestandardowy przycisk w komórce, aby wykonać pewne działanie w wybranym wierszu. Jeśli to nie ma dla ciebie sensu, dlaczego istnieje DataGridViewButtonCell? – tapatio

Powiązane problemy