2015-04-16 8 views
12

ho bisogno di associare un GroupBox ad un BindingSource, che a sua volta è legato al seguente oggetto:casella di gruppo personalizzato non vincolante per BindingSource

public class CustomerType 
{ 
    public int Id {get; set;} 
    public string Name {get; set;} 
    public MemberType MemberType {get; set;} 
} 

public enum MemberType {Adult, Child} 

Ho seguito questo answer to create a custom GroupBox. Ho anche impostare le associazioni di dati come segue:

groupBoxMemberType.DataBindings.Add("Selected", this.bindingSource, "MemberType"); 

Tuttavia, quando si carica un oggetto esistente, ottengo la seguente eccezione:

DataBinding non riesce a trovare una riga nella lista che è adatto a tutte le associazioni .

L'eccezione si verifica quando si imposta l'origine dati:

customerType = customerTypeRequest.Load(id); 
bindingSource.DataSource = customerType; //raises exception 

Che cosa mi manca? Esiste un'alternativa per ottenere i pulsanti di opzione da associare a un'origine dati, in particolare uno BindingSource?

+0

Quando si aggiunge l'associazione dati, provare passando vero per l'ultimo parametro (FormattingEnabled) pubblica Binding ( \t stringa propertyName, dataSource \t oggetto, \t stringa DataMember, \t bool formattingEnabled ) – Mangist

+0

@Mangist Il l'eccezione non si verifica. Tuttavia, le modifiche non sono commesse sull'oggetto. –

+0

sei sicuro che il problema riguardi la casella di gruppo personalizzata? qual è il tipo di dati di 'customerType' in questa riga:' bindingSource.DataSource = customerType; '? –

risposta

2

Questo è il codice modificato:

[DefaultBindingProperty("Selected")] 
public class RadioGroupBox : GroupBox 
{ 
    #region events 

    [Description("Occurs when the selected value changes.")] 
    public event SelectedChangedEventHandler SelectedChanged; 

    public class SelectedChangedEventArgs : EventArgs 
    { 
     public int Selected { get; private set; } 

     internal SelectedChangedEventArgs(int selected) 
     { 
      this.Selected = selected; 
     } 
    } 
    public delegate void SelectedChangedEventHandler(object sender, SelectedChangedEventArgs e); 

    #endregion 

    private int selected; 

    [Browsable(false)] 
    [Bindable(BindableSupport.Yes, BindingDirection.TwoWay)] 
    [Description("The selected value associated with this control."), Category("Data")] 
    public int Selected 
    { 
     get { return selected; } 
     set 
     { 
      int val = 0; 
      var radioButton = this.Controls.OfType<RadioButton>() 
       .FirstOrDefault(radio => 
        radio.Tag != null 
        && int.TryParse(radio.Tag.ToString(), out val) && val == value); 

      if (radioButton != null) 
      { 
       radioButton.Checked = true; 
       selected = val; 
      } 
     } 
    } 

    protected override void OnControlAdded(ControlEventArgs e) 
    { 
     base.OnControlAdded(e); 

     var radioButton = e.Control as RadioButton; 
     if (radioButton != null) 
      radioButton.CheckedChanged += radioButton_CheckedChanged; 
    } 

    protected void OnSelectedChanged(SelectedChangedEventArgs e) 
    { 
     if (SelectedChanged != null) 
      SelectedChanged(this, e); 
    } 

    private void radioButton_CheckedChanged(object sender, EventArgs e) 
    { 
     var radio = (RadioButton)sender; 
     int val = 0; 
     if (radio.Checked && radio.Tag != null 
      && int.TryParse(radio.Tag.ToString(), out val)) 
     { 
      selected = val; 
      OnSelectedChanged(new SelectedChangedEventArgs(selected)); 
     } 
    } 
} 

Oltre a impostare la proprietà Tag al corrispondente valore int del enum, è necessario sottoscrivere l'evento SelectedChanged nel modulo, ad esempio:

private void radioGroupBoxMemberType_SelectedChanged(object sender, SelectedChangedEventArgs e) 
{ 
    customerType.MemberType = (MemberType)e.Selected; 
} 

Miglioramenti a questa classe sarebbe:

  1. Eredita da RadioButton e si utilizza una nuova proprietà anziché la proprietà Tag.

  2. Accedere e impostare la proprietà bindingsource direttamente nel controllo per evitare di iscriversi all'evento.

Problemi correlati