Я думаю, что решение, используемое @ maxy-B, выглядит великолепно. Однако для меня это не удалось с вложенными включениями. Например, если config_1.yaml включает config_2.yaml, который включает config_3.yaml, возникла проблема с загрузчиком. Однако, если вы просто указываете новый класс загрузчика на себя при загрузке, он работает! В частности, если мы заменим старую функцию _include очень немного измененной версией:
def _include(self, loader, node):
oldRoot = self.root
filename = os.path.join(self.root, loader.construct_scalar(node))
self.root = os.path.dirname(filename)
data = yaml.load(open(filename, 'r'), loader = IncludeLoader)
self.root = oldRoot
return data
После размышлений я согласен с другими комментариями, что вложенная загрузка не подходит для yaml в целом, поскольку входной поток может не быть файлом, но это очень полезно!
У Рика Стрэла есть хорошее объяснение (и пример кода) здесь - http: // www.west-wind.com/Weblog/posts/5127.aspx
Я использую этот код для рекурсивного доступа к файлам:
/// <summary>
/// Recursively iterate through the controls collection to find the child controls of the given control
/// including controls inside child controls. Return all the IDs of controls of the given type
/// </summary>
/// <param name="control"></param>
/// <param name="controlType"></param>
/// <returns></returns>
public static List<string> GetChildControlsId(Control control, Type controlType)
{
List<string> FoundControlsIds = new List<string>();
GetChildControlsIdRecursive(FoundControlsIds, control, controlType);
// return the result as a generic list of Controls
return FoundControlsIds;
}
public static List<string> GetChildControlsIdRecursive(List<string> foundControlsIds, Control control, Type controlType)
{
foreach (Control c in control.Controls)
{
if (controlType == null || controlType.IsAssignableFrom(c.GetType()))
{
// check if the control is already in the collection
String FoundControl = foundControlsIds.Find(delegate(string ctrlId) { return ctrlId == c.ID; });
if (String.IsNullOrEmpty(FoundControl))
{
// add this control and all its nested controls
foundControlsIds.Add(c.ID);
}
}
if (c.HasControls())
{
GetChildControlsIdRecursive(foundControlsIds, c, controlType);
}
}
Я стараюсь избегать FindControl, если нет альтернативы, и обычно есть более аккуратный способ.
Как насчет включения пути к вашей главной странице вверху дочерней страницы
<%@ MasterType VirtualPath="~/MasterPages/PublicUI.Master" %>
Это позволит вам напрямую вызывать код из кода главной страницы позади.
Затем из кода главной страницы позади вы можете заставить свойство возвращать ваш контроль, или сделать метод на главной странице, чтобы получить ваш контроль и т. Д.
public Label SomethingLabel
{
get { return lblSomething; }
}
//or
public string SomethingText
{
get { return lblSomething.Text; }
set { lblSomething.Text = value; }
}
Относится к метке на главной странице.
<asp:Label ID="lblSomething" runat="server" />
Использование:
Master.SomethingLabel.Text = "some text";
//or
Master.SomethingText = "some text";