private TextBlock _caption = new TextBlock();
public TextBlock Caption
{
get { return _caption; }
set { _caption = value; }
}
<l:CustomPanel>
<l:CustomPanel.Caption Text="Caption text" FontSize="18" Foreground="White" />
</l:CustomPanel>
Выдает следующую ошибку:
Невозможно установить свойства для элементов свойств.
Если я использую:
<l:CustomPanel>
<l:CustomPanel.Caption>
<TextBlock Text="Caption text" FontSize="18" Foreground="White" />
</l:CustomPanel.Caption>
</l:CustomPanel>
Мой TextBlock отображается нормально, но он вложен в другой TextBlock, поэтому кажется, что он даже добавляет себя за пределы свойства Caption:
<l:CustomPanel>
<l:CustomPanel.Caption>
<TextBlock>
<InlineUIContainer>
<TextBlock Text="Caption text" FontSize="18" Foreground="White" />
</InlineUIContainer>
</TextBlock>
</l:CustomPanel.Caption>
<TextBlock>
<InlineUIContainer>
<TextBlock Text="Caption text" FontSize="18" Foreground="White" />
</InlineUIContainer>
</TextBlock>
</l:CustomPanel>
Как вы, возможно, уже догадались, я хочу, чтобы мой код устанавливал свойство Caption из XAML на настраиваемой панели, если это возможно.
Я также пробовал тот же код с DependencyProperty безрезультатно.
Итак, кто может помочь мне с этой проблемой?
Ответ 1 · рейтинг 15 · Ray Burns
Я могу объяснить, что происходит не так и как это исправить.
Первый,
<l:CustomPanel>
<l:CustomPanel.Caption Text="Caption text" FontSize="18" Foreground="White" />
является простой синтаксической ошибкой. Синтаксис <l:CustomPanel.Caption> не принимает XML-атрибуты - значение свойства должно находиться внутри элемента.
Это правильный синтаксис элемента свойства:
<l:CustomPanel>
<l:CustomPanel.Caption>
<TextBlock Text="Caption text" FontSize="18" Foreground="White" />
</l:CustomPanel.Caption>
</l:CustomPanel>
но:
- Синтаксис элемента свойства работает только с DependencyProperties (поэтому он не работает с вашим свойством CLR) и
- Синтаксис элемента свойства всегда учитывает ContentPropertyAttribute типа свойства.
Поскольку TextBlock имеет [ContentPropertyAttribute("Inlines")], синтаксис элемента свойства пытается добавить TextBlock в коллекцию Inlines.
Решение простое: объявите свое свойство как DependencyProperty типа UIElement вместо типа TextBlock. Это имеет дополнительное преимущество, заключающееся в том, что отображение содержимого не ограничивается только текстовым блоком. Если вы действительно хотите ограничить его только TextBlock, вы можете использовать обратный вызов проверки.
public UIElement Content { get { ...
public static readonly DependencyProperty ContentProperty = ...
Ответ 2 · рейтинг 2 · Willy
Только что получил неидеальный обходной путь от моего коллеги. Это включает в себя объявление свойства Caption в качестве ресурса, например:
<Page.Resources>
<TextBlock x:Key="test" Text="Caption text" FontSize="18" Foreground="White" />
</Page.Resources>
<l:CustomPanel Caption="{StaticResource test}" />
Я все еще хотел бы знать, почему я не могу использовать два предыдущих варианта, поэтому, если кто-нибудь знает, пожалуйста, ответьте. :)
Ответ 3 · Drew Noakes
Кажется, вы можете получить эту ошибку (по крайней мере, в Silverlight 4 и 5), если вы укажете пространство имен для элемента. Например:
<Path>
<MapLayer.Position xmlns="clr-namespace:Microsoft.Maps.MapControl">
...
В этом случае MapLayer.Position является прикрепленным свойством. Похоже, парсер Silverlight требует, чтобы пространство имен определялось с помощью префикса:
<Path xmlns:map="clr-namespace:Microsoft.Maps.MapControl">
<map:MapLayer.Position>
...