2014-05-06 6 views
5

Ho un Telerik.WinControls.UI.RadGridView con più colonne al suo interno. Sto usando un mix di rowvalidation e cellvalidation per convalidare l'input che ottengo (anche se per il problema corrente ho anche provato a disattivare la rowvalidation ma ho ancora ottenuto gli stessi risultati).Visualizzazione dei messaggi di errore di convalida di una cella sotto forma di win telerik

Possiedo un daterow per il quale utilizzo l'evento cellvalidating per convalidarlo (altrimenti ottengo un'eccezione se un utente digita una data errata). Il comportamento che mi aspettavo era che il messaggio di errore fosse visualizzato e la cella non fosse stata convalidata. La seconda cosa ha funzionato, ma il messaggio di errore SOLO viene visualizzato quando Sposto il mouse sul bordo della cella (altrimenti non viene mostrato).

Quindi la mia domanda sarebbe: come potrei ottenere che il messaggio di errore venga visualizzato non appena e finché viene rilevato un errore durante la convalida?

ecco il codice cellvalidation che uso:

void MainFormGridView_CellValidating(object sender, CellValidatingEventArgs eventArgs) 
{ 
    var currentCell = eventArgs.Row.Cells[eventArgs.ColumnIndex]; 

    if (eventArgs.Column.Name == "OrderDate") 
    { 
     if (eventArgs.Value == null) 
     { 
      eventArgs.Cancel = true; 
     } 
     else 
     { 
      try 
      { 
       DateTime dateValue; 
       if (!DateTime.TryParse(eventArgs.Value.ToString(), out dateValue)) 
       { 
        eventArgs.Cancel = true; 
       } 
      } 
      catch 
      { 
       // Error occured so validation error! 
       eventArgs.Cancel = true; 
      } 
     } 
     if (eventArgs.Cancel) 
     { 
      currentCell.ErrorText = "Error no valid date! Please type in a valid date"; 
     } 
     else 
     { 
      currentCell.ErrorText = string.Empty; 
     } 
    } 
} 

risposta

0

Per riuscire a stampare il suggerimento e visualizzarlo mentre il mouse si trova sopra la cella, è necessario eseguire alcune operazioni. Tieni presente che la mia griglia è chiamata myGrid nell'origine di esempio mentre il modulo è chiamato myForm.

La prima cosa che dobbiamo fare è definire 2 variabili helper abbiamo bisogno:

private ToolTip _tooltip; 
private Point _mouse; 

allora abbiamo bisogno di definire il tooltip, e la necessità di definire un gestore personalizzato per l'evento abbiamo bisogno

public myForm() 
{ 
    InitializeComponent(); 
    ....//your additional initialization code 

    _tooltip = new ToolTip(); 
    this.myGrid.CellEditorInitialized += myGrid_CellEditorInitialized; 
    this.myGrid.CellValidating+= myGrid_CellValidating; 
} 

il codice per la convalida cella è abbastanza semplice:

private void myGrid_CellValidating(object sender, CellValidatingEventArgs e) 
{ 
    string errorText = string.Empty; 
    // Are we really on a column currently? 
    if (e.ColumnIndex >= 0) 
    { 
     if (e.Value == null) 
     { 
      errorText = "No field may be empty"; 
     } 
    } 

    // Has an error occured? If so don't let the user out of the field until its corrected! 
    if (errorText != string.Empty) 
    { 
     e.Cancel = true; 
    } 
    e.Row.ErrorText = errorText; 
    e.Row.Cells[e.Column.Name].ErrorText = errorText; 
} 

Dopo aver fatto questo abbiamo necessario assicurarsi che quando l'celleditor viene inizializzato, che il tooltip è fatto pronto in caso di necessità:

private void myGrid_CellEditorInitialized(objec sender, GridViewCellEventArgs e) 
{ 
       RadTextBoxEditor radTextBoxEditor = e.ActiveEditor as RadTextBoxEditor; 
       RadTextBoxEditorElement editorElement = radTextBoxEditor.EditorElement as RadTextBoxEditorElement; 
       editorElement.AutoToolTip = true; 
       TextBox myTextBox= (TextBox)editorElement.TextBoxItem.HostedControl; 

       myTextBox.MouseMove -= new MouseEventHandler(textBox_MouseMove); 
       myTextBox.MouseLeave -= new EventHandler(textBox_MouseLeave); 
       myTextBox.MouseMove += new MouseEventHandler(textBox_MouseMove); 
       myTextBox.MouseLeave += new EventHandler(textBox_MouseLeave); 
} 

Così prima si ottiene il "testo" del redattore (indipendentemente che tipo di Editor è davvero lì) e impostare gli eventi di cui avremo bisogno per questa casella di testo, poiché vogliamo sapere quando l'utente ha il mouse sulla casella di testo e quando no.

Il passo successivo è quello di definire la funzione MouseMove, così, quando viene visualizzato il tooltip:

void textBox_MouseMove(object sender, MouseEventArgs e) 
{ 
    if (mousePos != e.Location) 
    { 
     RadTextBoxEditor radTextBoxEditor = this.myGrid.ActiveEditor as RadTextBoxEditor; 
     GridDataCellElement gridCellElement = radTextBoxEditor.OwnerElement as GridDataCellElement; 
     if (gridCellElement != null && gridCellElement.ContainsErrors) 
     { 
      RadTextBoxEditorElement radTextBoxEditorElement = radTextBoxEditor.EditorElement as RadTextBoxEditorElement; 
      TextBox myTextBox = (TextBox)radTextBoxEditorElement.TextBoxItem.HostedControl; 
      _tooltip.Show(gridCellElement.RowInfo.Cells[gridCellElement.ColumnInfo.Name].ErrorText, myTextBox, new Point(e.Location.X + 8, e.Location.Y + 8)); 
      _mouse = e.Location; 
     } 
    } 
} 

Dopo questo abbiamo bisogno anche di lasciare che il tooltip scomparire di nuovo, che facciamo con l'evento mouseLeave:

Con questi passaggi, abbiamo un suggerimento che appare quando l'utente sposta il mouse nella cella e scompare di nuovo quando lascia la cella.

2

trovare un evento che viene attivato quando il mouse sopra la cella e il fuoco che dal codice se non ci sono errori di convalida. Non è la soluzione più elegante, ma dovrebbe funzionare.

+0

Ho cancellato il mio precedente commento come in un punto che hai ragione usando l'evento "mouseover" (o più mousemove) fa parte di una possibile soluzione, anche se di gran lunga non è l'unica parte. – Thomas

1

Sto usando i controlli RadGridView di Telerik WPF, eppure è ancora lo spazio dei nomi di Windows, provatelo.

/// <summary> 
/// RadGridView cell validating. 
/// </summary> 
/// <param name="e"> 
/// The e. 
/// </param> 
private void CellValidating(GridViewCellValidatingEventArgs e) 
{ 
    bool isValid = true; 
    string validationText = "Validation failed. "; 
    GridViewCell cell = e.Cell; 
    switch (cell.Column.UniqueName) 
    { 
    case "Code": 
    case "Name": 
    case "County": 
    case "Region": 
     isValid = e.NewValue != null && !string.IsNullOrWhiteSpace(e.NewValue.ToString()); 
     if (!isValid) 
     { 
     validationText += string.Format("{0} is required.", cell.Column.UniqueName); 
     } 

     break; 

     /* Continue case statements... */ 

    } 

    if (!isValid) 
    { 
    MarkCell(cell, validationText); 
    } 
    else 
    { 
    RestoreCell(cell); 
    } 

    e.ErrorMessage = validationText; 
    e.IsValid = isValid; 
} 

/// <summary> 
/// Marks the cell with a red box and tooltip of the validation text. 
/// </summary> 
/// <param name="cell"> 
/// The cell. 
/// </param> 
/// <param name="validationText"> 
/// The validation text. 
/// </param> 
private void MarkCell(Control cell, string validationText) 
{ 
    ToolTipService.SetToolTip(cell, validationText); 
} 

/// <summary> 
/// Restores the cell and removes the tooltip. 
/// </summary> 
/// <param name="cell"> 
/// The cell. 
/// </param> 
private void RestoreCell(Control cell) 
{ 
    ToolTipService.SetToolTip(cell, null); 
} 
+0

Devo dire che mi sarebbe piaciuto se fosse così facile in winforms. Ho appena parlato con il supporto telérik (continuando ad analizzare il codice che mi hanno inviato), ma sembra che wpf abbia un enorme vantaggio in termini di semplicità rispetto alle winforms. In winforms ho bisogno di personalizzare 5 eventi oltre all'evento di validazione cellulare. Inserirò un post non appena sono sicuro di capire completamente cosa hanno fatto dove e perché. – Thomas