2013-03-23 2 views
2

От this page, я прочитал:Совместное использование приложений Ресурсы в WPF

Если ваше приложение использует пользовательские элементы управления и определяет ресурсы в ResourceDictionary (или узел XAML ресурсов), то рекомендуется либо определить ресурсы на Уровня приложения или окна или определить их в теме по умолчанию для пользовательских элементов управления. Определение ресурсов в ResourceDictionary настраиваемого элемента управления влияет на производительность каждого экземпляра этого элемента управления.

Хорошо ... Теперь у меня есть UserControl, который определяет следующие ресурсы:

<UserControl ...> 
    <UserControl.Resources> 
     <Namespace:ImagesConverter x:Key="ImagesConverter" ... 
     <Storyboard x:Key="AnimationHide" ... 
    </UserControl.Resources> 

Таким образом, из-за того факта, я создаю не менее 100 экземпляров из них во время выполнения, так как в учебнике MSDN, было бы лучше переместить эти ресурсы на MainWindow или App level. Где лучше всего их переместить? Уровень MainWindow, уровень приложения или файл ресурсов? И почему?

А потом ... как я могу использовать их со своего нового места? Скажем, у меня есть этот код внутри моего UserControl:

m_AnimationHide = (Storyboard)Resources["AnimationHide"]; 

Как я должен изменить его, чтобы отразить эти изменения? И как мне изменить следующий фрагмент UserControl XAML?

Source="{Binding Source={x:Static Properties:Resources.MyImage}, Converter={StaticResource ImagesConverter}}" 

ответ

2

Лично я предпочитаю использовать App.xaml или индивидуальный ResourceDictionary над добавлением их всех к Window.Resources, это устраняет беспорядок в вашем Window XAML.

Это также позволяет легко создавать Themes для вашего приложения, как вы их все в одном месте, так что вы можете скопировать существующие ResourceDictionary изменения кисти цветов и т.д., то вы можете выбрать то, что ResourceDictionary вы хотите загрузить и и легко изменить все ваше приложение.

Что касается доступа к Resouces в вашей Usercontrol нет никакой разницы на стороне XAML, вы будете продолжать использовать {StaticResource resourceKey}, как при вызове StaticResource он ищет хотя Resource иерархии, чтобы найти Resource.

Так что, если вы двигаетесь вы ресурс от UserControl.Resources к Window.Resources или Application.Resources вам не нужно ничего менять в своем XAML коде, обращающаяся хотя {StaticResource resourceKey}.

Что касается доступа в коде позади вы будете использовать FindResource("resourceKey") вместо Resources["resourceKey"] в FindResource будет искать иерархию для Resource как StaticResource делает в XAML.

Пример:

m_AnimationHide = (Storyboard)FindResource("AnimationHide"); 

Если вы хотите изменить какие-либо из этих ресурсов в определенном контроле и они заморожены, вы можете просто создать копию для этого экземпляра

Пример

var animation = FindResource("AnimationHide") as Storyboard; 

m_AnimationHide = animation.Clone(); 
m_AnimationHide.Completed += m_AnimationHide_Completed; 

Вы также можете установить x:Shared="false", это будет каждый раз возвращать новый экземпляр анимации из ресурсов, это сохранит копию/вставку того же анимати на througout приложения, если у вас есть сложный ресурс, который нужно изменить значения.

<Storyboard x:Key="AnimationHide" x:Shared="false" /> 

Тогда вы будете иметь возможность изменять ресурс локально.

+0

Мне понравилось, что вы сказали, но что-то не так. У меня есть код в моем UserControl, который выглядит так: 'animation.Completed + = обработчик;'. Всякий раз, когда я достигаю этого. моя ошибка приложения говорит мне: 'DoubleAnimation должен иметь значение IsFrozen для false для изменения'. Эти анимации должны что-то сделать в UserControl, которые уволили их после завершения. Как это исправить? –

+0

Это потому, что вы не можете изменить статический ресурс как замороженный, я добавил обходной путь к моему ответу –

+0

Спасибо! Я пробовал первый подход (все в App), и он работает как шарм. Теперь я пытаюсь со вторым (все в MainWindow) ... но я получаю неурегулированные ошибки ресурсов всякий раз, когда я пытаюсь ссылаться на ресурс MainWindow в свой пользовательский UserControl. Зачем? –

1

Я хотел бы немного рассказать о том, как вывести ресурсы из управления xaml.

Как вы читаете в библиотеке MSDN, единственной технической причиной перемещения чего-либо на более высокий уровень является резервное копирование ресурсов (т. Е. Памяти). Каждая запись в ResourceDictionary создается как объект (= экземпляр!) Во время выполнения и занимает память, а инициализация занимает несколько циклов процессора.

Теперь улов с чем-то вроде StoryBoard: для каждого экземпляра объекта должен быть создан объект, который хранит данные, которые имеют отношение к определенному экземпляру элемента управления или даже подключен к определенному экземпляру элемента управления - например, экземпляр исполняющей анимации. контроль должен двигаться. Если вы не хотите, чтобы все ваши элементы управления анимировались одинаково и параллельно.

Для меня не имеет смысла использовать Clone в коде, а не просто поставить эту вещь в xaml в первую очередь. Метод xaml требует немного копирования/вставки и, следовательно, будет означать изменение анимации в более чем одном месте (если вы даже можете повторно использовать что-то подобное на элементах управления), но он удалит требование кода и все равно сделает то же: создать экземпляр Storyboard для каждого экземпляра элемента управления.

+0

Ну, это имеет смысл «клонировать» или использовать «x: Shared» (xaml-версия клона), потому что если у вас есть приложение «Themed», как бы вы тему, которая копирует/вставляет «Ресурс» легко в нескольких местах. используя либо xaml, либо code clone, вам нужно изменить ресурс в Themed Dictonaries, а не на все приложение. –