Я нашел объяснение здесь , прибегая к помощи «windows ini» «раздел по умолчанию». Резюме: все, что вы помещаете в раздел [DEFAULT], распространяется на все остальные разделы. Используя пример со ссылочного веб-сайта, допустим, у меня есть файл конфигурации с именем test1.ini:
[host 1]
lh_server=192.168.0.1
vh_hosts = PloneSite1:8080
lh_root = PloneSite1
[host 2]
lh_server=192.168.0.1
vh_hosts = PloneSite2:8080
lh_root = PloneSite2
Я могу прочитать это с помощью ConfigParser:
>>> cp = ConfigParser.ConfigParser()
>>> cp.read('test1.ini')
['test1.ini']
>>> cp.get('host 1', 'lh_server')
'192.168.0.1'
Но я заметил, что lh_server одинаково в обоих разделах; и действительно, я понимаю, что это будет то же самое для большинства хостов, которые я мог бы добавить. Так что я могу сделать это, как test2.ini:
[DEFAULT]
lh_server=192.168.0.1
[host 1]
vh_root = PloneSite1
lh_root = PloneSite1
[host 2]
vh_root = PloneSite2
lh_root = PloneSite2
Несмотря на то, что разделы не имеют ключей lh_server, я все равно могу получить к ним доступ:
>>> cp.read('test2.ini')
['test2.ini']
>>> cp.get('host 1', 'lh_server')
'192.168.0.1'
Прочитайте связанную страницу для дальнейшего Пример использования подстановки переменных в разделе DEFAULT для еще большего упрощения INI-файла.
Я могу объяснить, что происходит не так, и как это исправить.
Во-первых,
<l:CustomPanel>
<l:CustomPanel.Caption Text="Caption text" FontSize="18" Foreground="White" />
- это простая синтаксическая ошибка. Синтаксис
не принимает атрибуты XML - значение свойства должно находиться внутри элемента.
Это правильный синтаксис элемента свойства:
<l:CustomPanel>
<l:CustomPanel.Caption>
<TextBlock Text="Caption text" FontSize="18" Foreground="White" />
</l:CustomPanel.Caption>
</l:CustomPanel>
но:
Поскольку TextBlock имеет [ContentPropertyAttribute ("Inlines")], синтаксис элемента свойства пытается добавить TextBlock в коллекцию Inlines.
Решение простое: объявите свойство как DependencyProperty типа UIElement вместо типа TextBlock . Это дает дополнительное преимущество, заключающееся в том, что отображение содержимого не ограничивается только TextBlock. Если вы действительно хотите ограничить его только TextBlock, вы можете использовать обратный вызов проверки.
public UIElement Content { get { ...
public static readonly DependencyProperty ContentProperty = ...
Только что получил от моего коллеги неидеальный обходной путь. Он включает объявление свойства Caption как ресурса, например:
<Page.Resources>
<TextBlock x:Key="test" Text="Caption text" FontSize="18" Foreground="White" />
</Page.Resources>
<l:CustomPanel Caption="{StaticResource test}" />
Я все еще хотел бы знать, почему я не могу использовать два предыдущих варианта, поэтому, если кто-нибудь знает, ответьте. :)