2009-06-16 2 views
3

Я пытаюсь найти метку на странице aspx из пользовательского элемента управления (ascx) на указанной странице aspx. Очевидно, что Page.FindControl («lablel1») не работает. Нужно ли добавлять где-нибудь в ClientID? Благодарю.Найти элемент управления aspx с ascx

+1

Я полагаю, что опечатка в вашем вопросе (вы используете «lablel1») не является источником вашей проблемы? –

+0

вы считаете правильным – halp

ответ

14

Я думаю, вы должны остановиться и подумать о своем дизайне. Ваши элементы управления никогда не должны знать ничего о странице, которая их содержит, - то, что вам нужно найти элемент управления на странице из другого элемента управления, говорит мне, что вы должны переосмыслить проблему.

Лучшее, что я могу вам сказать (с тем, что мало знаю о вашей архитектуре), заключается в том, что вы должны передать ссылку на элемент управления, который вы надеетесь найти в своем пользовательском контроле. Таким образом, ваш контроль не должен знать о вещах вне себя.

+1

Возможно, но это не вопрос. В этом случае есть страница с надписью «Error/Status Label», значение которой задается любым пользовательским элементом управления на странице. Раньше к нему обращались статически по индексу, теперь я пытаюсь изменить его, чтобы использовать какой-то FindControl. – halp

+0

+1, переход к ссылке на метку ошибки - лучший способ пойти сюда. –

3

При использовании FindControl() вне контекста непосредственных родительского элемента управления, вам нужно будет ходить по дереву управления, чтобы узнать, какой уровень ваших label жизни и вызвать .FindControl() на соответствующем уровне.

Это, пожалуйста, возьмите совет @ Andrew Hare и пересмотрите свои архитектурные решения. Вероятно, существует лучший способ взаимодействия вашего UserControl со своей потребительской страницей.

Например, вы можете открыть публичное мероприятие в своем UserControl и добавить обработчик событий на свою страницу потребления (или базовую страницу/главную страницу). При создании события вы можете сделать подпись, что захотите, поэтому включите текст ошибки, который нужно пройти.

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

Пример событие:

Public Event UserErrorOccured(ByVal ErrorText as String) 

Пример ошибка:

If Not Page.IsValid Then 
    RaiseEvent("The page is not valid") 
End If 

Образца Handler:

protected sub UserEventHandler(ByVal ErrorText as String) Handles MyUserControl.UserErrorOccured 
    errorLabel.Text = ErrorText 
End Sub 
2

Что-то, как это должно работать, если иерархия предсказуема.

Me.Owner.FindControl("controlName") 

или ...

Me.Owner.Parent.FindControl("controlName") 

или ...

Me.Owner.Parent.Parent.FindControl("controlName") 

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

Вот пример в VB для поиска по дереву в обратном направлении (от ребенка к родителю) и нахождении управления:

Protected Function FindControlByID(ByRef childControl As Control, ByVal ID As String) As Control 
    Dim ctrl As Control = childControl.FindControl(ID) 
    If Not ctrl Is Nothing Then 
     Return ctrl 
    Else 
     If Not childControl.Parent Is Nothing Then 
     Return FindControlByID(childControl.Parent, ID) 
     Else 
     Return Nothing 
     End If 
    End If 
    End Function 

Я назвал бы это так:

Dim lbl As Label = FindControlByID(Me.Owner, "label1") 
+0

Когда иерархия предсказуема для более чем одного или двух обновлений исходного кода? –

+0

Ну, из того, что я видел в прошлом, иерархия изменяется, когда вы перемещаете элемент управления в контейнер или из него (заполнитель, панель, пользовательский контроль и т. Д.). Пока вы этого не делаете, это довольно предсказуемо. Конечно, с другой стороны, это один из тех дрянных решений, что когда что-то меняется, оно сломается, и вы не можете вспомнить, почему. Но это просто повод, чтобы избежать этого, если можно. –

+0

Я добавил функцию, которая будет искать элемент управления через все дерево. –

1

Изнутри пользовательское управление

Me.NamingContainer.FindControl("label1") 
0

На ум приходит пара других идей. В классе страницы есть коллекция «Элементы», которая может использоваться для хранения значения или объекта Session для аналогичной мысли. Другой способ - открыть публичный метод на странице для обновления метки. Могут быть проблемы AJAX с этой архитектурой, поскольку я не уверен, насколько хорошо обратный вызов может одновременно обновлять несколько областей страницы, поэтому это всего лишь предупреждение, и я не говорю, что у меня была эта проблема.

Ответ TheSteve также работает и как я это делал, когда мне приходилось в прошлом, хотя это может быть сложным броском вокруг элементов управления. Тем не менее, я бы повторил ответ Эндрю.

2

Создайте интерфейс, такие как:

public interface IStatusDisplayer 
{ 
    Label StatusLabel { get; } 
} 

Реализовать интерфейс на любой странице, которая отображает метку ошибки/статус. Если элемент управления пользователь должен получить доступ к этикетке вы можете сделать это:

var statusDisplayer = this.Page as IStatusDisplayer; 
if (statusDisplayer != null) 
{ 
    statusDisplayer.StatusLabel.Text = "Hello World!"; 
} 
1
Control ct = WebUserControl11.FindControl("DropDownList1"); 

DropDownList dt = (DropDownList)ct; 

TextBox1.Text = dt.SelectedValue.ToString(); 
0

Это просто, сначала вы должны получить доступ к главной страницы ContentPlaceHolder:

Dim ContentPlaceHolder1 As ContentPlaceHolder = TryCast(Page.Master.FindControl("ContentPlaceHolder1"), ContentPlaceHolder) 

Затем с помощью ContentPlaceHolder вам теперь можете найти идентификатор элемента управления на странице aspx:

TryCast(ContentPlaceHolder1.FindControl("LiteralOnParentASPXPage"), Literal).Text = "some text" 
0

Это грубая сила, встреченная корыто, но это работает, когда элемент управления глубоко захоронены в иерарха управления:

private Control GetTextEditor(ControlCollection controls) 
{ 
    foreach (Control ctrl in controls) 
    { 
     if (ctrl.ID != null && ctrl.ID == "teMessage") 
      return ctrl; 
     if (ctrl.Controls.Count > 0) 
     { 
      Control inner = GetTextEditor(ctrl.Controls); 
      if (inner != null) 
       return inner; 
     } 
    } 
    return null; 
} 
0

Для доступа средства включить/отключить элементы управления из .ascx в файле .aspx, Попробуйте этот код это также решение.

protected void Page_Load(object sender, EventArgs e) 
{ 
    Control ct = PEM.FindControl("btnInsert"); 
    Button btn = (Button)ct; 
    btn.Enabled = false; 
} 
Смежные вопросы