Подтвердить что ты не робот

Использование свойства StyleOn Style в динамических ресурсах

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

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

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

4b9b3361

Ответ 1

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

       Style A
      /       \
  Style A1  Style A2

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

Один способ обхода, который вы можете использовать, это:

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

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

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

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

Ответ 2

Я обнаружил, что, поскольку вы не можете использовать BasedOn в DynamicResource, вы можете "преобразовать" DynamicResource в StaticResource, объединив ResourceDictionary с вашими "родительскими" ресурсами на ваш текущее окно/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.

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