Можно ли установить стиль в XAML, который избирательно влияет на элементы управления? - PullRequest
9 голосов
/ 29 марта 2009

В <Window.Resources> Я определил следующий стиль:

    <Style x:Key="textBlockStyle" TargetType="TextBlock">
        <Setter Property="Margin" Value="5,0,5,0"/>
    </Style>

Я определил некоторую сетку, где у меня есть четыре TextBlocks:

    <WrapPanel>
        <TextBlock Style="{StaticResource textBlockStyle}">Server</TextBlock>
        <TextBlock Style="{StaticResource textBlockStyle}">IP</TextBlock>
        <TextBlock Style="{StaticResource textBlockStyle}">Port</TextBlock>
        <TextBlock Style="{StaticResource textBlockStyle}">Status</TextBlock>
    </WrapPanel>

Проблема: Мне нужно сослаться на textBlockStyle четыре раза.

Вопрос: Можно ли установить этот стиль только один раз в WrapPanel или где-то еще, не повторяя ссылку на стиль?

Может быть, что-то вроде:

    <WrapPanel Style="{StaticResource textBlockStyle}">
        <TextBlock>Server</TextBlock>
        <TextBlock>IP</TextBlock>
        <TextBlock>Port</TextBlock>
        <TextBlock>Status</TextBlock>
    </WrapPanel>

Я не ищу глобального решения! Я могу удалить это свойство x:Key="textBlockStyle", но это повлияет на all TextBlocks в окне. Мне нужен более избирательный механизм, но без этого ужасного дублирования кода.

Ответы [ 2 ]

17 голосов
/ 29 марта 2009

У вас есть несколько вариантов, представленных здесь в порядке их масштабирования.

Вариант 1: определение стиля без ключа на более низком уровне

Вы можете закрепить ресурс на уровне WrapPanel, чтобы он влиял только на элементы управления внутри этого WrapPanel:

<WrapPanel>
    <WrapPanel.Resources>
        <Style TargetType="TextBlock">
            <Setter Property="Margin" Value="5,0,5,0"/>
        </Style>
    </WrapPanel.Resources>

    <!-- TextBlocks here -->
</WrapPanel>

Обратите внимание на отсутствие ключа. Это Style будет применяться ко всем TextBlock в пределах WrapPanel.

Вариант 2: определить стиль с помощью ключа и снова без на более низком уровне

Если вы определяете Style на более высоком уровне с помощью клавиши, вы можете затем определить еще один Style на более низком уровне без ключа и основывать это Style на более высоком уровне:

<Window>
    <Window.Resources>
        <Style TargetType="TextBlock" x:Key="textBlockStyle">
            <Setter Property="Margin" Value="5,0,5,0"/>
        </Style>
    </Window.Resources>

    <WrapPanel>
        <WrapPanel.Resources>
            <Style TargetType="TextBlock" BasedOn="{StaticResource textBlockStyle"/>
        </WrapPanel.Resources>

        <!-- TextBlocks here -->
    </WrapPanel>
</Window>

В результате Style автоматически применяется к TextBlock с внутри WrapPanel, но не снаружи. Кроме того, вы не дублируете детали Style - они хранятся на более высоком уровне.

Вариант 3: Поместить стили в ResourceDictionary и выборочно объединить его

Наконец, вы можете поместить Style в отдельный ResourceDictionary и выборочно объединить этот словарь в коллекцию Resources элемента управления:

<!-- TextBlockStyles.xaml -->
<ResourceDictionary>
    <Style TargetType="TextBlock">
        <Setter Property="Margin" Value="5,0,5,0"/>
    </Style>
</ResourceDictionary>

<!-- Window.xaml -->
<Window>
    <WrapPanel>
        <WrapPanel.Resources>
            <ResourceDictionary>
                <ResourceDictionary.MergedDictionaries>
                    <ResourceDictionary Source="TextBlockStyles.xaml"/>
                </ResourceDictionary.MergedDictionaries>
            </ResourceDictionary>
        </WrapPanel.Resources>
    </WrapPanel>
</Window>

<!-- Alternative Window.xaml if you have only one RD to merge in -->
<Window>
    <WrapPanel>
        <WrapPanel.Resources>
            <ResourceDictionary Source="TextBlockStyles.xaml"/>
        </WrapPanel.Resources>
    </WrapPanel>
</Window>

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

2 голосов
/ 29 марта 2009

Да, вы можете сделать это. У вас почти есть правильная идея. Вы делаете это так ...

<WrapPanel>
< WrapPanel. Resources >
<Style TargetType="{x:Type TextBlock}">
        <Setter Property="Margin" Value="5,0,5,0"/>
    </Style>
</WrapPanel.Resources/>
        <TextBlock Server</TextBlock>
        <TextBlock >IP</TextBlock>
        <TextBlock >Port</TextBlock>
        <TextBlock >Status</TextBlock>
    </WrapPanel>

С помощью синтаксиса {x: type} вам не нужен ключ x: он установит стиль для всех текстовых блоков в оболочке. Если вы хотите использовать разные стили, вы все равно можете использовать x: key и explicity, чтобы установить стиль для текстового блока.

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