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

WPF не применяет стиль к первому элементу

У меня есть простое окно WPF, на котором есть 12 кнопок. Я хочу, чтобы один и тот же стиль применялся ко всем из них. Этот код создает ту же ошибку:

<Window x:Class="TestApp.TestWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="TestWindow" Height="400" Width="500"
        WindowStyle="None" WindowState="Maximized">
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Resources/AllResources.xaml"/>
                <ResourceDictionary>
                    <Style TargetType="{x:Type Button}">
                        <Setter Property="FontSize" Value="100"/>
                    </Style>
                </ResourceDictionary>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Button Grid.Column="0" Content="1" Name="Button1"/>
        <Button Grid.Column="1" Content="2" Name="Button2"/>
    </Grid>
</Window>

Первая кнопка не получает стиль, применяемый к ней, но второй делает. Я мог установить ключ и использовать его на каждой кнопке, но я бы предпочел, чтобы WPF обрабатывал это для меня. Я просто узнал при написании этого, что, когда я не включаю внешний ResourceDictionary, он работает так, как ожидалось. Это будет проблемой в будущем, так как мое приложение расширяется, поскольку у меня есть несколько окон, которым необходимо разделить одни и те же ресурсы. Измененный код выглядит следующим образом:

<Window x:Class="TestApp.TestWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="TestWindow" Height="400" Width="500"
        WindowStyle="None" WindowState="Maximized">
    <Window.Resources>
        <Style TargetType="{x:Type Button}">
            <Setter Property="FontSize" Value="100"/>
        </Style>
    </Window.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Button Grid.Column="0" Content="1" Name="Button1"/>
        <Button Grid.Column="1" Content="2" Name="Button2"/>
    </Grid>
</Window>

Он также работает, если я (вместо удаления объединенных словарей) добавляю атрибут x: Key = "key" и затем явно назначаю этот стиль каждой кнопке.

В чем проблема? Почему первый пропускает "Button1", а второй не?

4b9b3361

Ответ 1

Я видел эту проблему пару раз раньше, и это довольно странная "ошибка". Это происходит, когда вы помещаете Style непосредственно в ResourceDictionary внутри <ResourceDictionary.MergedDictionaries>. Style пропускается для первого элемента. Этот код дает тот же результат, стиль пропускается для первого ListBoxItem

<Window.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary>
                <Style TargetType="{x:Type ListBoxItem}">
                    <Setter Property="Foreground" Value="Green"/>
                </Style>
            </ResourceDictionary>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Window.Resources>
<ListBox>
    <ListBoxItem Content="Item 1"/>
    <ListBoxItem Content="Item 2"/>
    <ListBoxItem Content="Item 3"/>
</ListBox>

Чтобы работать как с стилями, так и с MergedDictionaries, сделайте это как обычно:

<Window.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Resources/AllResources.xaml"/>
        </ResourceDictionary.MergedDictionaries>
        <Style TargetType="{x:Type Button}">
            <Setter Property="FontSize" Value="100"/>
        </Style>
    </ResourceDictionary>
</Window.Resources>
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>
    <Button Grid.Column="0" Content="1" Name="Button1"/>
    <Button Grid.Column="1" Content="2" Name="Button2"/>
</Grid>

Ответ 2

Хотя это не приводит к ошибке, согласно документации:

словарь, используемый в объединенных словарях, не должен содержать контент и должен использовать свойство Source, чтобы косвенно ссылаться на другой словарь. Фактически, если вы помещаете Style в словарь ресурсов и ссылаетесь на оба из них в слиянии, он работает так, как должен.

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