简体   繁体   中英

Asp.net WebForms DropDownList - controls with different values and displayed texts (DataValueField/DataTextField)

I have two entity classes - Users and Tasks. Every User has the following properties: UserId (int), Username (string), Password (string), FirstName (string), Lastname (string)

and every Task, these: TaskId (int), Title (string), Description (string), EstimatedTime (int), CreatedOn (Datetime), CreatedBy (int), AssignedTo (int), Finished (bool)

So CreatedBy and AssignedTo are actually UserIds - CreatedBy is the Id of the user, who created the task, and AssignedTo - the id of the one the task is for. I have a database where I use them - no problems there.

In my WebForms Application I use a GridView to show the Tasks. So I hide the TaskId and all the other properties are shown as columns in the GridView. But, the problem is, I don't want my users to see the values in CreatedBy and AssignedTo as ids(integers) - I want them to see the values as Usernames, so it would look like this: AssignedTo - "myUsername", and not like this: AssignedTo - 321.

This is my first problem, I don't know how to do that. As you will see in my code, the ItemTemplate is a Label, Bound to the property AssignedTo. How can I keep the value invisible and display the username instead?

Second, as I log in as an admin, I want to be able to edit the Tasks. So I added these command fields to my GridView:

<asp:CommandField ShowEditButton="true" />
<asp:CommandField ShowDeleteButton="true" />

I have a TaskRepository ans UserRepository that I use to access my database. For example, the GridView is bound to a property in my TaskRepository that returns a list of all the tasks :

TaskRepository taskRepo = new TaskRepository;
GridViewTasks.DataSource = taskRepo.GetAll();
GridViewTasks.DataBind();

Everything works perfectly. And here is my AssignedTo ItemTemplate:

<asp:TemplateField HeaderText="Assigned to">
   <EditItemTemplate>
                    <asp:DropDownList ID="editAssignedTo" runat="server" DataTextField="Username" DataValueField="UserId"></asp:DropDownList>
   </EditItemTemplate>
   <ItemTemplate>
                    <asp:Label ID="lbAssignedTo" runat="server" Text='<%#Bind("AssignedTo")%>'></asp:Label>
   </ItemTemplate>
</asp:TemplateField>

So when I edit a task, I click "Edit" and I can change the values in the selected row in each column. But the problem, again, is with AssignedTo. As you can see from the code, when I edit it I see a DropDownList where insted of Ids, I have to choose from usernames. But the moment I try to save my changes, I get an object null reference exception.. I don't know why. Here is my code:

protected void GridViewTasks_RowUpdating(object sender, GridViewUpdateEventArgs e)
        {
            GridViewRow selectedRow = GridViewTasks.Rows[e.RowIndex];
            Tasks task = new Tasks();
            task.TaskId = (int)GridViewTasks.DataKeys[e.RowIndex].Value;
            TextBox title = (TextBox)selectedRow.FindControl("tbTitle");
            task.Title = title.Text;
            TextBox description = (TextBox)selectedRow.FindControl("tbDescription");
            task.Description = description.Text;
            Label createdOn = (Label)selectedRow.FindControl("lblCreatedOn");
            task.CreatedOn = DateTime.Parse(createdOn.Text);
            Label createdBy = (Label)selectedRow.FindControl("lblCreatedBy");
            task.CreatedBy = int.Parse(createdBy.Text);
            TextBox estimTime = (TextBox)selectedRow.FindControl("tbEstimTime");
            task.EstimatedTime = int.Parse(estimTime.Text);          
            DropDownList assignedTo = (DropDownList)selectedRow.FindControl("editAssignedTo");           
            task.AssignedTo = int.Parse(assignedTo.SelectedItem.Value);
            Label lblFinished = (Label)selectedRow.FindControl("lblFinished");
            task.Finished = bool.Parse(lblFinished.Text);
            taskRepo.Save(task);
            BindDataToGridView();
        }

Everything works with the other controls but when it gets to task.AssignedTo, I get the exception. Here is what I want to happen: When I click Edit, I want to see a DropDownList in the AssignedTo column with all my users usernames to choose from (so far, so good) and when I select a user and click Update, I want it to get the selected username value of assignedTo, knowing the userId it corresponds to and update my Task. Where do I go wrong?

Sorry for the long post, I tried to be as thorough as possible and since I don't understand where the problem is, maybe I even missed something important (this is my first post). Please help, because I've been stuck on this since forever.

For you first problem you can use an OnRowDataBound method to convert your ID to a username. Essentially you get the ID from the row and get the name based on the ID.

For example:

protected void Gridview_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if(e.Row.RowType == DataControlRowType.DataRow)
    {
       //get your control like in rowupdating
       //take the ID value and query against your user info to get the name
       // set the value
    }
}

For your second problem it might be that you need OnRowUpdated instead. I don't have VS installed on this computer to try it out, so this is just a guess.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM