2013-08-06 3 views
9

Если я на моей странице: EnableViewState="true" ViewStateMode="Disabled" - Затем - ViewState отключен для страницы (если переопределение ...)Почему DropDownList.SelectedValue полагается на viewstate?

Затем, пытаясь читать (предполагая контроль не был заселен в последний дамп на экран и значение выбрано):

MyDDL.SelectedValue даст ""

Это из-инвалидов ViewState:

Но мой вопрос на более высоком уровне:

  • Если это все о значении формы (который я все еще могу получить от Request.Form[MyDDL.UniqueID]) - и мы говорим о входе, который ничего не нужно, чтобы сохранить его значение.

  • Почему делает DropDownList свойство с именем (SelectedValue) полагается на ViewState?

p.s. TextBox onchangeevent действительно полагается на viewstate, хотя элемент управления - это вход (который не нуждается в представлении) - он сохраняет значение текста, а затем сравнивает его при обратной передаче. Но он полагается только на viewstate, когда вы устанавливаете событие onchange (и AutoPostBack)

+0

Ну текстовое поле не полагается на viewstate, вы можете отключить viewstate, и вы все равно получите текстовое значение, его значение исходит от IPostBackDataHandler. Request.Form [""] Работает только при отправке ваших данных с использованием метода POST. Учитывайте, что пользователь не может отправить форму из-за ошибок проверки или любой ошибки, по которой ваша форма не может быть отправлена ​​на этом мероприятии. получите свои значения из Request.Form [""]. –

+0

@surajsingh Я уже знаю это. все еще мой вопрос остается. –

+0

Надеюсь, что я сейчас на правильном пути, я просто создал раскрывающийся список с использованием listitems, и он сохраняет состояние даже после отключения ViewState. Я все еще должен проверять выпадающее меню, которое ограничено через таблицы базы данных. Посмотрим, сохраняют ли они свое состояние и могут ли я получить ответ. –

ответ

6

РЕЗЮМЕ: Если вы хотите контролировать, чтобы работать без ViewState, то вам необходимо заполнить/связать коллекцию Items на каждом постбэка. Я рекомендую сделать это в событии Page_Init (т. Е. Метод OnInit).

Во-первых, я всегда рекомендую эту эту удивительную статью: TRULY Understanding ViewState.

SelectedValue не требует ViewState. Глядя на код ListControl, который наследуется от DropDownList, мы видим код:

public virtual string SelectedValue 
{ 
    get 
    { 
    int selectedIndex = this.SelectedIndex; 
    if (selectedIndex >= 0) 
     return this.Items[selectedIndex].Value; 
    else 
     return string.Empty; 
    } 

Важно, чтобы забрать из этого кода является то, что список предметов должны быть заполнены, чтобы получить SelectedValue.

Если вы используете ViewState, то коллекция предметов сохраняется и/или загружается из ViewState, что позволяет работать с свойством SelectedValue без переустановки элемента управления.

+0

Итак, как это работает. (реализация SelectedValue ....) классная. (Потому что странно полагаться на viewstate, если мне нужно только значение ....) –

7

SelectedValue полагается на ViewState потому что на PostBack восстанавливая свой ListItems от ViewState, а затем устанавливает выбранное значение на DropDownList от Request объекта.

Не принимается значение Request как SelectedValue. Это, в свою очередь, связано с тем, что ASP.Net может проверить, не был ли изменен опубликованный DropDownList на клиенте. Он делает это, сначала де-сериализуя исходные элементы из ViewState. Затем он находит значение Request в пунктах и ​​устанавливает его Selected как true. Только сейчас доступно свойство SelectedValue. (или SelectedIndex в этом отношении). Теперь он должен иметь возможность запустить событие SelectedIndexChanged.

Это также является причиной того, что вам не нужно снова связывать DropDownList в PageLoad. Элементы списка автоматически удаляются из ViewState.

Если ViewState отключен, то в ViewState не будет элементов исходного списка и будет пустым. Следовательно, он не сможет отмечать какой-либо элемент как выбранный. Следовательно, SelectedValue будет 0, или SelectedItem будет пустым. Я думаю, что событие SelectedIndexChanged также не срабатывает. Для работы в этом случае необходимо выполнить привязку данных, предпочтительно на init.

Однако есть обходные пути.

Complete Reference: http://msdn.microsoft.com/en-us/library/ms972976.aspx

Редактировать: (после комментариев Op в)

После жизненного цикла страницы, чтобы увидеть, где SelectedValue полагается на ViewState:

Этап 1 Init: контроль построена иерархия. Если DropDownList связан здесь или ListItems были добавлены декларативно, список будет заполнен здесь.

Этап 2 Загрузить ViewState: В PostBack ViewState проверяется здесь и загружается в DropDownList. Существует нетSelectedValue здесь.

Этап 3 Загрузка данных PostBack: Здесь Request Значение (из запроса формы) берется, а затем применяется к элементу управления. В этом случае DropDownList теперь множестваSelectedValue из принятого Request стоимости объекта, внутренняя реализация что-то вроде этого:

string selectedValue = HttpContext.Current.Request.Form[DropDownList_Id]; 
Items.FindByValue(selectedValue).Selected = true; 

Что важно здесь то, что, если ViewState не существует и DropDownList не данных- , то коллекция ListItem будет пустой и, следовательно, свойство SelectedValue равно 0. Это не имеет ничего общего с внутренней реализацией свойства.

Если ViewState не существует (отключено), а DropDownList привязан к данным, тогда коллекция ListItem будет существовать, и соответствующий элемент будет отмечен как выбранный, и, следовательно, свойство SelectedValue вернет правильное значение.

Если коллекция детали новая (через повторное связывание с другим набором данных или ViewState аннулируются), то значение Request формы не будет найдены в коллекции элементов и снова SelectedValue будет недействительно.

Этап 4 Загрузка страницы: к этому времени уже были загружены данные ViewState (или привязки данных) и PostBack Data.

Этап 5 Raise PostBack Событие: На этом этапе OnSelectedIndexChanged событие DropDownList увольняют, если индекс был изменен на этапе 3.

Следовательно, SelectedValue опирается на ViewState на стадии 3. Конечно, если элемент управления соответствующим образом привязан к данным, то он не будет полагаться на ViewState в качестве следствия.

SelectedValue полагается на ViewState, чтобы убедиться, что коллекция предметов была заполнена до ее установки. Связывание данных/повторное связывание - это еще один способ убедиться, что коллекция элементов заполнена.

Надеюсь, что уточняется.

+0

проблема с подделкой проверяется с помощью validationMAc. он не имеет ничего общего с выбранным значением. –

+0

_ он не сможет отметить какой-либо элемент как выбранный_, справа. но он должен иметь значение (IMHO), как request.form –

+0

Вы читали ссылку, которую я связал выше? – Abhitalks

0
 protected void Page_Load(object sender, EventArgs e) 
      { 
       (!Page.IsPostBack) 
       { 
        string qry = "SELECT TOP(5)xxx, xxxx FROM dbo.xxxxxx "; 
        DataSet ds = new DataSet(); 
        ds = SqlHelper.ExecInDS(qry); 
        drpDwn.DataSource = ds.Tables[0]; 
        drpDwn.DataValueField = Convert.ToString(ds.Tables[0].Columns["xxx"]); 
        drpDwn.DataTextField = Convert.ToString(ds.Tables[0].Columns["xxx"]);     
        drpDwn.DataBind(); 
       } 
       //Here You will get selected value from dropdown 
       string sss= Request.Form["drpDwn"]; 
    } 
0

Если вы хотите DropDownList работать без ViewState, вы можете связать элемент управления в Page_Load только один раз, как указано ниже:

 protected void Page_Load(object sender, EventArgs e) 
      {   
    //whatever you use declarative binding (in aspx page), or define data source here 
       if (!IsPostBack) 
       { 
        ddl.DataBind(); //fire databinding events and fill items, and selectedvalue has a value. 
       } 

       //you can get the selectedvalue 
       var sv=ddl.SelectedValue ; // 
      }   
  • В случае (ViewState отключен), Asp.net FrameWork извлекайте элементы с задней стороны с каждым PostBack.

  • В случае (ViewState включен), Asp.net FrameWork извлекать предметы из ViewState, не попав в заднюю часть с каждым PostBack

нормально, Рамочная Asp.net огнь связывания данных события в событии PreRender: Прочитано ASP.NET Page Life Cycle Overview

Вы можете подтвердить это поведение, включив функцию Trace.

SelectedValue не полагается непосредственно на ViewState от source code of ListControl, НО зависит от элементов, как описано выше.