Использование свойства стиля BasedOn в DynamicResources

Интересно, есть ли способ использовать свойство basedOn стилей wpf с динамическими ресурсами. например

<Style BasedOn="{DynamicResource somestyle}">
   <Setter Property="SomeProp" Value="SomeValue"/>
</Style>

это например выдает ошибку, указывающую на то, что использование динамических ресурсов в сочетании со стилями BasedOn невозможно. интересно, как кто-то мог это сделать? Благодарность


person Joachim Kerschbaumer    schedule 25.02.2009    source источник


Ответы (2)


Думаю, основная причина - опломбированные объекты. Если у вас есть иерархия стилей:

       Style A
      /       \
  Style A1  Style A2

это может быть не сложный сценарий. Вы обращаетесь к StyleA с помощью динамического ресурса, поэтому всякий раз, когда этот ресурс изменяется, Style A1 и Style A2 должны изменить свое свойство BasedOn. Однако, как только в вашем приложении используется стиль, он становится запечатанным объектом. Style A становится неизменным.

Одно из возможных решений:

  1. Style A нужно изменить.
  2. Создайте новый объект Style, который будет новым ресурсом Style A.
  3. Создайте новую версию Style A1 и Style A2. Вам нужно будет написать процедуру копирования, которая делает копии всех Setters, Resources и т. Д. Установите BasedOn на новую версию Style A.
  4. Обновите коллекцию ресурсов, чтобы в ней присутствовали три новых стиля.

{DynamicResource StyleA1} и {DynamicResource StyleA2} должны теперь уловить факт изменения этих ресурсов (с шага 4) и автоматически обновить все ссылки.

Обратите внимание, что это очень простой сценарий. Иерархии стилей реального мира могут быть более сложными, особенно если они распределены по нескольким файлам и взяты из объединенных словарей.

Надеюсь, я понял вашу проблему и помог.

person Szymon Rozga    schedule 25.02.2009
comment
Как насчет этого сценария - другая (Ux) команда создает базовые стили ... разработчик хочет установить пару свойств в дополнение к базовому стилю. В идеале это сценарий, в котором мог бы помочь DevStyle BasedOn DynamicResource UxStyle. Если это невозможно, каковы альтернативы объединению двух стилей перед их применением к элементу управления? - person Gishu; 14.10.2012

Я обнаружил, что, поскольку вы не можете использовать BasedOn на DynamicResource, вы можете «преобразовать» DynamicResource в StaticResource путем слияния ResourceDictionary, содержащего ваши «родительские» ресурсы, с вашим текущим Window / UserControl / чем-то еще. Таким образом, теперь вы можете ссылаться на объект ресурса (например, Style), используя StaticResource. Таким образом, вы можете использовать Datatriggers на DynamicResource (через преобразование).

Пример:

<Window.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="/MyProject.Styles;component/ButtonStyles.xaml"/>
        </ResourceDictionary.MergedDictionaries>
        [*Your other resources can be put here*]
    </ResourceDictionary>
</Window.Resources>

...

<Button Command="{Binding MyCommandInViewModel, RelativeSource={RelativeSource AncestorType=Window}}">
    <Button.Style>
        <Style BasedOn="{StaticResource StyleFromButtonStyles}" TargetType="Button">
            <Style.Triggers>
                <DataTrigger Binding="{Binding SomeBool}" Value="True">
                    <Setter Property="Button.Content" Value="{StaticResource SomeImage}"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding SomeBool}" Value="False">
                    <Setter Property="Button.Content" Value="{StaticResource SomeOtherImage}"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Button.Style>
</Button>

Следовательно, Datatriggers применяются к кнопке со стилем в импортированном ResourceDictionary.

Надеюсь это поможет!

person ruNury    schedule 17.02.2012