Подтвердить что ты не робот

Пользовательский групповой ящик не привязывается к связующему источнику

Мне нужно привязать GroupBox к BindingSource, который, в свою очередь, привязан к следующему объекту:

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

public enum MemberType {Adult, Child}

Я последовал за этим ответом на создание настраиваемого GroupBox. Я также установил привязки данных следующим образом:

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

Однако при загрузке существующего объекта я получаю следующее исключение:

DataBinding не может найти строку в списке, которая подходит для всех привязок.

Исключение возникает при настройке источника данных:

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

Что мне не хватает? Есть ли альтернатива для получения переключателей для привязки к источнику данных, в частности, BindingSource?

4b9b3361

Ответ 1

Это измененный код:

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

В дополнение к установке свойства Tag в соответствующее значение int перечисления, вам необходимо подписаться на событие SelectedChanged в вашей форме, например:

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

Усовершенствования этого класса:

  • Наследовать от RadioButton и использовать новое свойство вместо свойства Tag.

  • Доступ и установка свойства bindingsource непосредственно в элементе управления, чтобы избежать подписки на событие.