0

我已经使用此代码大约 3 个小时,但我无法使其工作。我用对象列表 (clsMarcas) 填充 ComboBox,当我使用 SelectedItem 属性并为其分配相同类型的对象以使其显示 DisplayMember 时,什么也没有发生。你能指导我吗?

public class clsMarcas
{
    public int IdMarca {get; set;}
    public string NombreMarca {get; set;}
    public clsMarcas()
    {

    }
    public clsMarcas(string strMarca)
    {
        this.NombreMarca = strMarca;
    }

}


public class clsAuto
{
    public string Dominio {get; set;}
    public clsMarcas Marca {get; set;}        

    public clsAuto()
    {

    }

    public clsAuto(string Dominio, clsMarcas Marca)
    {
        this.Dominio = Dominio;
        this.Marca = Marca;
    }
}


public partial class frmAutosAE
{
    public frmAutosAE()
    {
        InitializeComponent();
    }
    private clsAuto oAuto;
    private clsMarcas defaultMarca;

    protected override void OnLoad(System.EventArgs e)
    {
        base.OnLoad(e);
        CargarMarcas();

        if (oAuto != null)
        {
            this.txtDominio.Text = oAuto.Dominio;
            SeleccionarMarca(oAuto.Marca);

        }
    }


    private void SeleccionarMarca(clsMarcas Marca)
    {
        cboMarcas.SelectedItem = Marca;

    }
    public void SetAuto(clsAuto oAuto)
    {
        this.oAuto = oAuto;
    }

    public clsAuto GetAuto()
    {
        return oAuto;
    }

    private void CargarMarcas()
    {
        List<clsMarcas> ListaMarcas = GestorDeRepositorio.GetInstancia().Repositorio.GetMarcas();
        this.cboMarcas.DisplayMember = "NombreMarca";
        defaultMarca = new clsMarcas { NombreMarca = "<Seleccione una marca>" };
        cboMarcas.Items.Add(defaultMarca);
        cboMarcas.SelectedIndex = 0;

        foreach (clsMarcas elemento in ListaMarcas)
        {
            this.cboMarcas.Items.Add(elemento);
        }
    }



    public void btnGuardar_Click(System.Object sender, System.EventArgs e)
    {
        if (validarDatos())
        {
            if (oAuto == null)
            {
                oAuto = new clsAuto();
            }

            oAuto.Dominio = this.txtDominio.Text;
            oAuto.Marca=GetMarcaSeleccionada();


            this.DialogResult = System.Windows.Forms.DialogResult.OK;
        }
    }



    private clsMarcas GetMarcaSeleccionada()
    {
        clsMarcas marca=(clsMarcas)cboMarcas.SelectedItem;
        if (marca==defaultMarca)
        {
            return null;
        }
        return marca;
    }



    public void btnCancelar_Click(System.Object sender, System.EventArgs e)
    {
        this.DialogResult = System.Windows.Forms.DialogResult.Cancel;
    }


    public List<clsMarcas> GetMarcas()
    {
        Marcas.Clear();
        try
        {

            using (OleDbConnection cnn = new OleDbConnection(ConnectionString.ToString()))
            {
                cnn.Open();
                OleDbTransaction tran = cnn.BeginTransaction();
                string strSQL = "SELECT * FROM Marcas";
                OleDbCommand comando = new OleDbCommand(strSQL, cnn, tran);

                using (OleDbDataReader oReader = comando.ExecuteReader())
                {
                    while (oReader.Read())
                    {
                        clsMarcas oMarca = new clsMarcas();
                        oMarca.IdMarca = oReader.GetInt32(0);
                        oMarca.NombreMarca = oReader.GetString(1);
                        Marcas.Add(oMarca);
                    }

                }

                tran.Commit();

            }


        }
        catch (Exception ex)
        {

            throw (ex);
        }
        return Marcas;
    }
}
4

3 回答 3

0

在 Load 事件和之后设置 SelectedItem。不要在表单的构造函数中设置 SelectedItem

于 2012-09-03T04:36:03.020 回答
0

首先,清理你的代码

不要覆盖 OnLoad,而是添加一个事件处理程序

protected override void OnLoad(System.EventArgs e)
{
    // your code
}

应改为

public frmAutosAE()
{
    InitializeComponent();
    Load += FormLoaded;
}

public void FormLoaded(object sender, EventArgs e)
{
    // your code
}

使用属性而不是 setter/getter 方法:

public void SetAuto(clsAuto oAuto)
{
    this.oAuto = oAuto;
}
    
public clsAuto GetAuto()
{
    return oAuto;
}

应该

public clsAuto Auto { get; set; }

使用using指令而不是完全限定名称:

this.DialogResult = System.Windows.Forms.DialogResult.Cancel;

应该

DialogResult = DialogResult.Cancel; 
// add using System.Windows.Forms to the top of the file

最后,请学习 C# 命名约定并使用它们。类以大写字母开头,局部变量不是。

然后解决你的问题

protected override void OnLoad(System.EventArgs e)
{
    base.OnLoad(e);
    CargarMarcas();

    if (oAuto != null)
    {
        this.txtDominio.Text = oAuto.Dominio;
        SeleccionarMarca(oAuto.Marca);

    }
}

这是您唯一可以打电话的地方SeleccionarMarca。在这里,oAuto始终为空,因此永远不会调用选择代码。初始化oAuto解决问题。

但是,正如 Xavier Poinas 在他的回答中指出的那样,您很可能还需要Equals在 clsMarcas 中覆盖,例如:

public override bool Equals(object obj)
{
    var marcas = obj as clsMarcas;
    if (marcas != null)
    {
        return IdMarca == marcas.IdMarca;
    }
    return false;
}

该解决方案已在我的机器上进行了测试,并且可以正常工作。

于 2012-09-03T01:20:59.323 回答
0

我尚未测试完整的代码,但这可能不起作用,因为当您将对象分配给 DisplayMember 时,它可能与您使用列表加载的对象(在内存中)不同。(除非您的存储库重用对象实例,这不太可能)。

因此,当组合框在列表中查找您正在分配的对象时,它不会找到它。

尝试覆盖 clsMarcas 的 Equals 方法以提供基于 ID 的相等性(例如)。

否则,尝试按索引选择,或者自己在列表中定位对象(根据 ID),然后将 DisplayMember 分配给列表中对象的实例。

于 2012-09-03T00:34:34.390 回答