2011-03-25 32 views
5

Tôi có một trang mà tôi đã tạo tự động tạo điều khiển người dùng. Ví dụ, điều khiển người dùng có hai trường có thể được chỉnh sửa: SomeId và SomeData. Tôi muốn có thể đặt các giá trị này dựa trên UserControlObject. Khi tôi đọc điều khiển sau đó, tôi muốn có thể trả lại một UserControlObject từ điều khiển và thiết lập các giá trị cơ sở dữ liệu cho điều đó. Tôi đang gặp một số vấn đề khi nhận được các giá trị để luôn cập nhật.Điều khiển người dùng động nhận và duy trì giá trị sau khi đăng lại

//Page 
public class SomePage 
{ 
    private List<MyUserControl> _MyUserControls; 

    private void InitControls() 
    { 
     var controlsToBuild = SomeDatabaseCallToGetControlObjects(); 

      foreach(MyUserControl control in controlsToBuild) 
      { 
     MyUserControl control = this.Page.LoadControl("MyControl.ascx") as MyUserControl; 

      UserControlPlaceHolder.Controls.Add(myControl); 
      _MyUserControls.Add(myControl); 
     } 
    } 

    protected void Page_Init(object sender, EventArgs e) 
    { 
     InitControls(); 
    } 

    protected void SaveButton_Click(object sender, EventArgs e) 
    { 
     if (this.IsValid) 
     { 
     List<MyUserObject>listObj = new List<MyUserObject>(); 
     foreach(MyUserControl control in _MyUserControls) 
     { 
      MyUserObject obj = control.GetObjectFromControl(); 
      listObjs.Add(obj); 
     } 
     SaveToDatabase(listObjs); 
     //Clear placeholder in case number of controls has changed based on the save 
     UserControlPlaceHolder.Clear(); 
     InitControls(); 
     GetObjectFromDatabase(); 
     } 
    } 

} 

//Object to put in control 
public class UserControlObject 
{ 
    public string DataForUser { get;set;} 
    public double MoreDataForUser { get;set;} 
    public int HiddenIdFromUser { get; set;} 
} 


//User control 
public class MyUserControl : UserControl 
{ 

    public MyUserControlObject GetObjectFromControl() 
    { 
    UserControlObject obj = new UserControlObject(); 
    obj.DataForUser = textBoxOnTheControl.Text; 
    obj.MoreDataForUser = anotherBoxOnTheControl.Text; 
    obj.HiddenIdFromUser = hiddenField.Value; 

    return obj; 
    } 

    public void SetUserControlObject(UserControlObject obj) 
    { 
    textBoxOnTheControl.Text = obj.DataForUser; 
    anotherBoxOnTheControl.Text = obj.MoreDataForUser; 
    hiddenField.Value = obj.HiddenIdFromUser; 
    } 
} 

Về cơ bản, tôi muốn tải lên mỗi giá trị từ một cơ sở dữ liệu. Người dùng có thể thay đổi hầu hết (nhưng không phải tất cả) của các trường đó. Người dùng không thể thay đổi ID, nhưng tôi cần nó để cập nhật bản ghi trong cơ sở dữ liệu.

Tôi đang gặp một số sự cố khi nhận thông tin để lưu và duy trì chính xác, vì tôi đang tạo lại một bộ sưu tập gồm MyUserControl. Dường như nó hoạt động tốt trên postback inital, nhưng sau postback tiếp theo, tôi vẫn nhận được giá trị cũ cho một trong các trường. Làm cách nào để đảm bảo rằng:

1) Thông tin được đặt thành (các) điều khiển người dùng một cách chính xác. Tôi có cần đặt thuộc tính công khai tham chiếu ViewState trên mọi thuộc tính của UserControl không?

2) Sau khi nhấp vào sự kiện lưu, sau khi đăng lại, việc xây dựng lại các điều khiển sẽ không khiến tôi giữ lại bất kỳ giá trị "cũ" nào từ lần tải đầu tiên? Làm thế nào tôi nên xử lý các ViewState ở đây? Tôi muốn dữ liệu phản ánh những gì người dùng đã thay đổi.

+0

Tôi đang cố gắng theo dõi mã của bạn có một số vấn đề khiến bạn khó theo dõi. Trong 'InitControls()' bạn có một vòng lặp 'foreach', nhưng tôi nghĩ bạn dự định là một vòng lặp đơn giản phải không? tức là 'cho (int i = 0; i

+0

@ Joel: Đã lâu rồi ... Tôi đã thực hiện các chỉnh sửa :) –

Trả lời

9

Để trạng thái xem/trạng thái điều khiển hoạt động đúng, bạn phải có cùng một ID cho các điều khiển của mình. Vì bạn không chỉ định ID rõ ràng, nó phải được tạo ra và sẽ có xung đột ở đó với nhiều hơn một điều khiển người dùng đang hiện diện. Tôi sẽ khuyên bạn nên có một số loại logic để tạo cùng một tập hợp các ID trên post-back. Ví dụ,

private void InitControls() 
{ 
    var numControlsToBuild = SomeDatabaseCallToGetNumControls(); 
    int idCounter = 1; 
    foreach(var controlData in numControlsToBuild) 
    { 
    var control = this.Page.LoadControl("MyControl.ascx") as MyUserControl; 
    control.ID = "MyControl" + idCounter.ToString(); 
    idCounter++; 
    UserControlPlaceHolder.Controls.Add(myControl); 
    _MyUserControls.Add(control); 

    // probably code load control data into control 
    } 
} 
+0

+1 Đây thực sự là vấn đề cốt lõi ở đây. Tôi sẽ đăng một câu trả lời khác để đi vào chi tiết hơn một chút. –

+0

Điều này đã khắc phục được sự cố. Cảm ơn vì đầu vào của bạn. –

4

Như đã chỉ ra bởi VinayC, vấn đề cơ bản ở đây là do thực tế rằng khi bạn tự động thêm các điều khiển đến một trang, nếu bạn không gán ID cho những người điều khiển, họ sẽ được tạo ra ID. Nếu số lượng điều khiển được tạo động thay đổi hoặc nếu thứ tự mà chúng được tạo thay đổi thì sẽ có sự không khớp giữa các điều khiển web được tạo động và thông tin trạng thái cho các đối tượng đó trong trạng thái chế độ xem. Tương tự, sẽ có sự không khớp giữa các ID của các điều khiển web được tạo động và các ID của tham số truy vấn trong các tiêu đề POST. Điều đó có nghĩa là các giá trị của một số trường sẽ không được cập nhật từ dữ liệu POST.

Xem không khớp ID trạng thái sẽ khiến những thứ như nhãn và chữ trở lại giá trị ban đầu. Mặt khác, dữ liệu POST không phù hợp với ID sẽ gây ra các trường nhập để hoàn nguyên về giá trị nội sinh. Nếu bạn đang gặp vấn đề với các trường đầu vào hoàn nguyên về giá trị ban đầu, việc nhét xung quanh với trạng thái xem sẽ không giải quyết được vấn đề. Đó là một quan niệm sai lầm phổ biến rằng các giá trị trường được duy trì trong trạng thái xem. Tuy nhiên, điều này là không cần thiết vì các giá trị trường đầu vào đã được chứa trong dữ liệu POST. Để có một cuộc thảo luận tốt về cách Chế độ xem hoạt động, hãy xem Understanding how the viewstate works bởi Scott Mitchell.

Nếu bạn luôn tạo các điều khiển được thêm động theo thứ tự như sau, như VinayC chỉ ra, bạn có thể tạo một chuỗi các ID như "ID1", "ID2", "ID3", ... tạo điều khiển web. Trong trường hợp của bạn, vì bạn đang lưu trữ giá trị trường User Control trong cơ sở dữ liệu, bạn có thể muốn tạo ID mới cho mỗi người dùng chỉ kiểm soát một lần và lưu trữ từng ID được tạo trong cơ sở dữ liệu cùng với các giá trị trường được liên kết. Bằng cách đó, bạn không cần phải lo lắng về thứ tự mà bạn tạo các điều khiển.

Các vấn đề liên quan