Мне нужно установить для свойства Content
ContentPresenter
значение DynamicResource
, ключ которого известен во время выполнения. DynamicResource
Key
не является свойством зависимости, поэтому я не могу вставить туда привязку, поэтому я создал прикрепленное свойство, которое служит прокси для Content
:
public static class ContentPresenterHelper {
private static void ContentResourceKeyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
var element = d as ContentPresenter;
if (element != null) {
element.SetResourceReference(ContentPresenter.ContentProperty, e.NewValue);
}
}
public static readonly DependencyProperty ContentResourceKeyProperty = DependencyProperty.RegisterAttached("ContentResourceKey",
typeof(object),
typeof(ContentPresenterHelper),
new PropertyMetadata(String.Empty, ContentResourceKeyChanged));
public static void SetContentResourceKey(ContentPresenter element, object value) {
element.SetValue(ContentResourceKeyProperty, value);
}
public static object GetContentResourceKey(ContentPresenter element) {
return element.GetValue(ContentResourceKeyProperty);
}
}
Я использую его следующим образом:
<ContentPresenter u:ContentPresenterHelper.ContentResourceKey="{Binding SomeProp}" />
Я использовал аналогичный подход при динамическом присвоении изображения из ресурсов свойству Image
Source
, и это сработало.
Однако в этом конкретном случае попытка решить проблему способом, который я показал, приводит к бесконечной рекурсии:
PresentationFramework.dll!System.Windows.FrameworkElement.IsLoaded.get() Unknown
PresentationFramework.dll!MS.Internal.FrameworkObject.IsLoaded.get() Unknown
PresentationFramework.dll!System.Windows.BroadcastEventHelper.IsParentLoaded(System.Windows.DependencyObject d) Unknown
PresentationFramework.dll!System.Windows.FrameworkElement.IsLoaded.get() Unknown
PresentationFramework.dll!MS.Internal.FrameworkObject.IsLoaded.get() Unknown
PresentationFramework.dll!System.Windows.BroadcastEventHelper.IsParentLoaded(System.Windows.DependencyObject d) Unknown
PresentationFramework.dll!System.Windows.FrameworkElement.IsLoaded.get() Unknown
PresentationFramework.dll!MS.Internal.FrameworkObject.IsLoaded.get() Unknown
...
Почему это так? Как я могу решить эту проблему?
1 ответ
Когда возитесь с ContentPresenter
, всегда помните, что ContentPresenter.Content
- особенное свойство: оно влияет на DataContext
. В сочетании с привязкой данных это может производить всевозможные странные эффекты. Вообще говоря, привязка ContentPresenter.Content
через DataContext
ненадежна, и ее следует избегать. Попробуйте использовать ContentControl
, поскольку он не соединяет свой DataContext
с Content
таким образом. Кроме того, вместо присоединенного свойства я бы написал конвертер, который будет искать ваш динамический ресурс по ключу и использовать его для непосредственной привязки Content
, но это дело вкуса.
Похожие вопросы
Новые вопросы
c#
C # (произносится как «резкий») - это высокоуровневый, статически типизированный язык программирования с несколькими парадигмами, разработанный Microsoft. Код C # обычно нацелен на семейство инструментов и сред выполнения Microsoft .NET, включая, среди прочего, .NET Framework, .NET Core и Xamarin. Используйте этот тег для вопросов о коде, написанном на C # или в формальной спецификации C #.
ResourceDictionary
при создании экземпляра конвертера, не так ли? Или, может быть, есть более хитрый способ предоставить конвертеру доступ к ресурсам?MarkupExtension
. Однако с шаблонами бывает сложно. В любом случае, преобразователь или вложенное свойство - дело вкуса.ContentPresenter
наContentControl
полностью решил мою проблему; спасибо за помощь, сэр :)