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", а второй не?
Ответы
Ответ 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
в словарь ресурсов и ссылаетесь на оба из них в слиянии, он работает так, как должен.
Мы можем только догадываться, почему это не поддерживается, но поскольку это не так, и поскольку обходной путь прост, мы не можем жаловаться слишком горько, за исключением того, что мы хотим получить ошибку во время компиляции.