Silverlight 4 — использовать StaticResource из одного ResourceDictionary в другой

#silverlight #resourcedictionary #staticresource

#silverlight #resourcedictionary #staticresource

Вопрос:

Если у меня есть эти словари:

dict1.xaml: <Color x:Key="Color1">Red</Color>

dict2.xaml: <SolidColorBrush x:Key="Brush1" Color={StaticResource Color1} />

Это работает:

App.xaml:

 <MergedDictionaries>
  <ResourceDictionary Source="dict1.xaml"/>
<MergedDictionaries>
  

SomePage.xaml:

 <UserControl.Resources>
  <MergedDictionaries>
    <ResourceDictionary Source="dict2.xaml"/>
  </MergedDictionaries>
</UserControl.Resources>
  

Это не:

App.xaml объединяет оба на уровне приложения.

Я получаю сообщение об ошибке о том, что Color1 не найден.

Почему это? / Есть ли способ обойти это? Я знаю, что этот пример упрощенный, но реальный был бы слишком длинным. По сути, я просто пытаюсь упорядочить свои стили и шаблоны в разных файлах:

  • Один для цветов
  • Один для неявных стилей
  • Много для явных стилей

редактировать: любопытно, что если я делаю это в коде на Application_Startup , перед установкой RootVisual свойства, я не получаю ошибку… Я просто озадачен тем, почему!

Ответ №1:

К сожалению, вы столкнулись с досадным ограничением в системе ресурсов Silverlight, которое, я могу только предположить, является какой-то проблемой оптимизации. Похоже, что здесь наблюдается некоторое асинхронное поведение, когда каждый словарь в MergedDictionaries загружается параллельно, следовательно, при загрузке «dict2.xaml» вы не можете полагаться на присутствие содержимого «dict1.xaml».

Самое простое решение — включить объединение Dict1 в Dict2:-

App.xaml:

 <ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="dict2.xaml" />
<ResourceDictionary.MergedDictionaries>
  

Dict2.xaml:

 <ResourceDictionary>
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="dict1.xaml" />
    </ResourceDictionary.MergedDictionaries>
    .... <!-- dict2 resource -->
</ResourceDictionary>
  

Ответ №2:

Это было бы в App.xaml

 <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="dict1.xaml" />
                <ResourceDictionary Source="dict2.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
  

пока вы определяете словарь перед другим, я немного удивлен, что что-то подобное вышеупомянутому не сработает.

Комментарии:

1. Я уже пробовал это, прежде чем публиковать это, поскольку это было бы очевидным виновником. Однако, такой удачи нет. Кажется, что он пытается разрешить это одновременно, что просто до смешного бесит меня, потому что я не вижу ни одного случая, когда вы ХОТИТЕ такого поведения, особенно если MS не дает нам DynamicResource

2. может быть полезно просмотреть ваш app.xaml таким, какой он у вас есть, когда он выходит из строя. Я сделал это сам и не вижу или не думаю о чем-то особенном, что я должен был сделать, чтобы заставить это работать

3. Это все, что есть в моем приложении xaml, кроме объявления файла (материал, который я не трогал). Когда вы говорите, что сделали это, были ли у вас словари, в которых один ссылается на ресурс, определенный в другом? Потому что буквально я воспроизвел это в совершенно новом проекте, в котором БОЛЬШЕ ничего нет, кроме двух dicts, mergeddictionaries и одной страницы с одним текстовым блоком, использующим стиль в одном из словарей (хотя я не думаю, что это заходит так далеко)

Ответ №3:

Вы можете сделать это способом, предложенным @Anthony, но здесь есть одно предостережение — если вы используете свой первый словарь ресурсов, например, в 5 других словарях, то он будет загружен 5 раз, и у вас будет 6 копий одного и того же словаря ресурсов (это в случае, если вы ссылались на него в App.xaml), что не очень хорошо для производительности. Это может быть исправлено с помощью небольшого подкласса словаря ресурсов silverlight отсюда — http://softnotes.wordpress.com/2011/04/05/shared-resourcedictionary-for-silverlight / .

Ответ №4:

В этом я согласен с Тэмом. «Логика поиска ресурсов в коллекции объединенных словарей ресурсов является последней, первая выходит». Другими словами, если у вас есть несколько словарей, где один ссылается на другой, то словарь, содержащий ресурсы, на которые даны ссылки, должен находиться в верхней части стека. Убедитесь, что вы ссылаетесь на них в правильном порядке, и будьте осторожны, чтобы словари в верхней части стека не зависели от словарей в нижней части стека

 <Application.Resources>         
 <ResourceDictionary>
  <ResourceDictionary.MergedDictionaries>                                     
   <ResourceDictionary Source="Dict1.xaml" /> 
   <ResourceDictionary Source="dependsOnDict1.xaml" />                   
  </ResourceDictionary.MergedDictionaries>         
 </ResourceDictionary>     
</Application.Resources> 
  

Комментарии:

1. Это не показанное поведение. Если бы это было так, не было бы никаких проблем, и я бы не опубликовал этот вопрос почти год назад. Попробуйте и убедитесь 🙂