Link to home
Create AccountLog in
Avatar of joelilly
joelilly

asked on

Gridview datakeynames columns should not be editable

I need some help controlling whether columns in a ASP.NET 2.0 Gridview are editable.  I'm trying to set 4 fields with the datakeynames property, and I'm expecting that the user won't be able to edit these.  I've set the gridview's datasource to a SqlDataSource control and am conditionally selecting from one (or another) View in a SQL Server db.  I need to modify the select query at runtime and I'm trying to do this when the page loads.  The following code correctly returns the records, however when I edit one of these records, I am able to edit fields which are in the datakeynames array, and I just can't allow this.   The first 2 fields, ScenarioID and Supplier, are not an issue because I've set their visible property to false.  I want the MatNo and Description fields to display in my gridview, but I don't want these to be editable.   Thanks for your help.


Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Try
            Dim sql As String
            sql = "SELECT [ScenarioID], [Supplier], [MatNo], [Description], [Price_MSF], [Min_Pcs], [Max_Pcs]"
            If Request.QueryString("Type") = "Graded" Then
                sql = sql & " FROM [vp_GradedMaterials]"
            Else
                sql = sql & " FROM [vp_SupplierMaterials]"
            End If
            sql = sql & " WHERE ScenarioID = " & Request.QueryString("ScenID")

            dsMaterials.SelectCommand = sql
            gvMaterials.DataKeyNames = New String() {"ScenarioID", "Supplier", "MatNo", "Description"}


        Catch ex As Exception
            MsgBox(ex.ToString())
        End Try
    End Sub
ASKER CERTIFIED SOLUTION
Avatar of valkyrie_nc
valkyrie_nc
Flag of United States of America image

Link to home
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
See answer
Avatar of joelilly
joelilly

ASKER

Thanks, that solves my problem in this case.  I happen to know the field names at design time.  How do I set ReadOnly="true" at runtime?  I have a similar problem on another page where I don't know the field names at design time.  I'd expect to be able to do something like:

gridview.columns(0).readonly = true

But this does not work because there is no readonly property on a column object.

Also, any idea why the DataKeyNames property is of no consequence here?

Thanks,
Joe
You can set the readonly property of a gridview column if you create the column in the code-behind, but I can't figure out how to do it if it's created at design-time on the .aspx page (no idea why).  

C#

        GridView thisGV = new GridView();
        BoundField thisDCCol = new BoundField();
        thisDCCol.ReadOnly = true;
        thisGV.Columns.Add(thisDCCol);

hth

valkryie_nc
Hmmm.  I don't think thats what I want.  Honestly, I'm not quite understanding what is actually happening at design time and what at runtime.  I'm changing the SqlDataSource.selectcommand during the page_load.  It seems that the gridview properties set at design time are applied if they still make sense with the new selectcommand.  At least thats what appears to be happening.  

I've set my gridview autoGenerateColumns to false because otherwise the grid gives me duplicate columns (I suspect because I'm mixing design time and runtime properties).

I don't want to add any new fields to the gridview but just control the fields that are generated by the SqlDataSource.

I think I'm looking for a way to reference an existing gridview column as a BoundField object like you've done in your C# example.  

Thanks
Also, I just found this on Microsoft:

Explicitly declared column fields can be used in combination with automatically generated column fields. When both are used, explicitly declared column fields are rendered first, followed by the automatically generated column fields. Automatically generated column fields are not added to the Columns collection.

So my auto generated fields are not added to the columns collection so it appears that I can't programmatically set the readonly property.
Can you reference it in the RowDataBound event?

BoundField thisField = e.Item.FindControl("FieldID") as BoundField;
thisField.ReadOnly = true;

hth

valkyrie_nc
Thanks but I'm unable to translate corresponding VB code on that.

I've decided to workaround the problem by writing separate pages for the two conditions I'm handling.  Its not that elegant but it is practical and it works.

I'd still be interested in case you come across a way to set column properties of these bound fields at runtime.

Thanks for your help,
Joe