Переключение между именованными стилями - PullRequest
3 голосов
/ 05 декабря 2011

Несколько месяцев назад в приложении на C # я начал использовать ListBox в качестве контейнера для некоторых пользовательских панелей. Когда панель была выбрана, она была выделена, как и любой элемент списка. Я нашел следующий XAML, который я смог добавить, чтобы дать всем элементам прозрачный фон (не уверен, где я изначально нашел это, или я бы связал его)

<Application.Resources>
    <Style TargetType="ListBoxItem">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ListBoxItem}">
                    <Border x:Name="border" Background="Transparent">
                        <ContentPresenter />
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsSelected" Value="true">
                            <Setter TargetName="border" Property="Background">
                                <Setter.Value>Transparent</Setter.Value>
                            </Setter>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Application.Resources>

Это работало нормально, но теперь мне иногда нужно иметь цвет фона вместо прозрачного фона. Существует только 1 список и содержимое меняется, поэтому я хочу программно изменить стиль в коде позади.

Я нашел примеры изменения стиля в коде, но я не смог создать два одинаковых стиля. Я дал ему ax: name = "transparentListbox", скопировал его, а другой дал x: name = "normalListbox" с фоном Blue, но я получаю исключение синтаксического анализа XML, имеющее два элемента стиля, возможно, потому что они оба обычно пытается изменить каждый список.

Как я могу иметь два именованных стиля, которые выполняют одно и то же (изменение фона при выборе элемента), с которыми я могу переключаться в коде по мере необходимости?


Edit:

В каждом случае мой список используется для хранения пользовательских панелей. Я добавляю их в список с помощью lstPanels.Items.Add (p), где p - это экземпляр класса, производного от UserPanel.

Когда я впервые сделал приложение, было несколько окон, поэтому окна, которые требовали прозрачности, имели этот стиль, а те, которые требовали выбора элементов, - нет. Управление несколькими окнами стало трудоемким, поэтому оно было повторно преобразовано в одно окно, и при смене режима список будет очищен и загружен различными типами панелей. Некоторым по-прежнему требовался прозрачный фон, а теперь - нет.

Программное назначение именованного стиля для списка в целом, когда режим меняется, будет в порядке. Присвоение стиля каждому ListBoxItem повлечет за собой обновления большого количества кода по мере распространения этой функциональности.

Возможно, решение будет состоять в том, чтобы поддерживать единый стиль, но нужно ли свойство background быть привязанным к varaible, если это вообще возможно?

Ответы [ 3 ]

2 голосов
/ 05 декабря 2011

Я всегда создавал стиль в своем разделе UserControl.Resources.

В вашем случае:

<Style x:Key="ListBoxStyle1" TargetType="MyDerivedListBoxItem">

...

<Style x:Key="ListBoxStyle2" TargetType="MyDerivedListBoxItem">

...

и в коде позади я установил стили таким образом.

If Not MyListBox.ItemContainerStyle.Equals(CType(Resources("ListBoxStyle1"), Style)) Then
                    MyListBox.ItemContainerStyle= CType(Resources("ListBoxStyle1"), Style)
1 голос
/ 05 декабря 2011

Вам нужно установить различные директивы x:Key, если стили являются ресурсами, то Name в любом случае довольно бесполезен.Если вы не установите ключ, вместо него будет использоваться TargetType, что приведет к коллизии.Чтобы применить один из стилей в коде, вы можете вызвать FindResource с соответствующей клавишей.

1 голос
/ 05 декабря 2011

Я бы не стал связываться с попытками изменить стили в вашем коде.Это может быть выполнимо и даже работать, но мне это кажется болезненным миром.Одна идея, которая может помочь, заключается в том, что вы можете наследовать от ListBoxItem, определяя свой собственный элемент управления.Затем вы можете поместить свойство зависимости в этот наследник, например UseAlternateBackgroundColor типа bool или что-то в этом роде.

Затем вы измените свой стиль:

<Style TargetType="MyDerivedListBoxItem">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type MyDerivedListBoxItem}">
                <Border x:Name="border" Background="Transparent">
                    <ContentPresenter />
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsSelected" Value="true">
                        <Setter TargetName="border" Property="Background">
                            <Setter.Value>Transparent</Setter.Value>
                        </Setter>
                    </Trigger>
                    <Trigger Property="UseAlternateBackgroundColor" Value="true">
                        <Setter TargetName="border" Property="Background">
                            <Setter.Value>Black</Setter.Value>
                        </Setter>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Вообще говоря, я лично стараюсь избегатькак можно больше разбираться с особенностями компоновки и визуального стиля в коде.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...