Domanda

At first, I'll show the standard way to build a custom UpdateCommand for a DataAdapter (used commonly when the Select has many tables involved and we can't use CommandBuilder to build all the commands automatically for a DataAdapter).

Here is code for my DataAdapter:

SqlDataAdapter myAdapter = new SqlDataAdapter("SELECT ID, Name FROM MyTable", myConnection);

Here is code for building a standard UpdateCommand for myAdapter. The example above involves only 1 single table, however, that's just for simple and demonstrative purpose.

myAdapter.UpdateCommand = new SqlCommand("UPDATE MyTable SET ID=@id,Name=@name WHERE ID=@id2", myConnection);
myAdapter.UpdateCommand.Parameters.Add("id", SqlDbType.VarChar).SourceColumn = "ID";
myAdapter.UpdateCommand.Parameters.Add("name", SqlDbType.VarChar).SourceColumn = "Name";
myAdapter.UpdateCommand.Parameters.Add("id2", SqlDbType.VarChar, 20, "ID").SourceVersion = DataRowVersion.Original;

The problem is I don't want to bind the the Parameter to a SourceColumn exactly. I want to change the value from SourceColumn a little before the values are passed to the corresponding Parameter. For example, my ID column contains all the values like 1,2,3,4,... I would like to append some string (e.g: 000, 001, A, B, C, ...) before it and pass this custom SourceColumn to my Parameter. With the code above, the passed values are exactly what the SourceColumn ID has: 1,2,3,4... and what I want is for example: C1,C2,C3,C4,...

That's is some kind of parsing value using some middle layer, I would like to know if this is possible. Parsing the value of SourceColumn outside is OK however there is some case I have to parse it right when building the UpdateCommand for my Adapter. Here is a case:

I have a DataGridView which has a column of Gender, this column is of type DataGridViewComboBoxColumn with 2 items: Male and Female. The underlying datasource should have a corresponding Gender column and the values should be "Male" and "Female", all the unmatched values (not contained in the Items list of the ComboBoxColumn) won't make the ComboBoxCell display the value correctly. I've tried CellFormating and CellPainting but it didn't work. CellPainting is too complex and CellFormating didn't work at all. In fact, I'm not using a standard .NET DataGridView, I'm using a custom DataGridView (also inherits from the standard DataGridView). All I've done to this DataGridView didn't work. The only solution is to prepare all the underlying values to include only "Male" and "Female". However I designed my Gender column as a boolean/bit column. Here is the SELECT command:

SqlDataAdapter myAdapter = new SqlDataAdapter("SELECT ID, Name, CASE WHEN Gender = 1 THEN 'Male' ELSE 'Female' END Gender FROM MyTable", myConnection);

The Gender column now is type of varchar or text and not a boolean/bit as I did before. But the Gender column in the original table is type of bit. How can I build my UpdateCommand for the SELECT command above? A solution is include a hidden Gender column and use this column for the SourceColumn to build the UpdateCommand, the visible Gender is just for displaying. This is however a little much more work to do. If I could do some kind of Custom SourceColumn, it would be better to use.

Your help would be highly appreciated!

È stato utile?

Soluzione

I don't know if this helps, but I think you are heading in the wrong direction.

Let the DataGridView display how you would like to see and edit the data. Regarding your 'Gender' column, you should be able to setup your combobox column as follows:

Consider the following scenario: Your data table has a column 'Gender' which holds a 0 (unknown), 1(Male), 2(Female), 3(Other).

Here is a sample code which will define the lookup, creates sample data and populates the grid with data. The Gender will be displayed in english but stored as number.

    class Employee
    {
        public string Name { get; set; }
        public int Gender { get; set; }
    }
    class GenderLookup
    {
        public string Display { get; set; }
        public int Value { get; set; }
    }

    private void SetupGrid()
    {

    GenderLookup[] _lookups = new[]
        {
            new GenderLookup { Value = 0, Display = "unknown" }, 
            new GenderLookup { Value = 1, Display = "Male" },
            new GenderLookup { Value = 2, Display = "Female" }, 
            new GenderLookup { Value = 3, Display = "Other" }
        };

    Employee[] _employees = new[]
        {
            new Employee() { Gender = 1, Name = "James T. Kirk" }, 
            new Employee() { Gender = 2, Name = "Lt. Uhura" },
            new Employee() { Gender = 3, Name = "Data" }
        };
        GridView.AutoGenerateColumns = false;
        GridView.DataSource = _employees;
        GridView.Columns.Add(
            new DataGridViewTextBoxColumn() 
                { 
                    DataPropertyName = "Name" 
                }
            );

        GridView.Columns.Add(
            new DataGridViewComboBoxColumn()
                {
                    DataSource = _lookups,
                    DisplayMember = "Display",
                    ValueMember = "Value",
                    DataPropertyName = "Gender"
                }
            );
    }

So there is no need to 'parse' (or better: translate) the gender display name manually. The DataGridView creates a 'view' of your underlying data, which might be hard to read (as with the gender information in this case).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top