2014-01-20 13 views
1

Мне нужно установить Content свойство ContentPresenter на DynamicResource, ключ которого известен во время выполнения. DynamicResource «s 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 «s 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, но это вопрос вкуса.

+0

Единственная проблема с конвертером заключается в том, что он не имеет непосредственного доступа к ресурсам. Мне пришлось бы вручную присоединить 'ResourceDictionary' при создании экземпляра конвертера, не так ли? Или, может быть, есть еще более хитроумный трюк, чтобы предоставить конвертеру доступ к ресурсам? – Spook

+0

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

+0

В любом случае; обмен «ContentPresenter» с 'ContentControl' полностью разрешил мою проблему; спасибо за помощь, сэр :) – Spook

 Смежные вопросы

  • Нет связанных вопросов^_^