Как наследовать свойство XAML и переопределить свойство дочернего элемента?
мы только начали работать с XAML и по-прежнему боремся с основными проблемами:
Исходя из CSS, мы хотели бы определить общий стиль кнопки с настраиваемым шаблоном управления, а затем второй стиль наследуем все, начиная с первого стиля, используя "basedon". Этот второй стиль затем должен переопределять такие свойства, как "цвет переднего плана" (который работает) но также свойства дочерних элементов в нашем пользовательском шаблоне, такие как "цвет фона", например, включенный элемент границы и т.д. (который не работает).
Каков общий подход к подобным вещам? Как далеко мы можем пойти с каскадными стилями?
Ура!
Ответы
Ответ 1
Вы можете использовать унаследованный стиль без ссылки на ключ:
<Grid>
<Grid.Resources>
<!-- Definition of default appearance of a button -->
<Style TargetType="Button" x:Key="Default">
<Setter Property="Background" Value="Red"></Setter>
<Setter Property="FontFamily" Value="Segoe Black" />
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="FontSize" Value="32pt" />
<Setter Property="Foreground" Value="#777777" />
</Style>
<!-- Define general style that based is base on the default style of the button without a key reference-->
<Style TargetType="Button" BasedOn="{StaticResource Default}"/>
<!-- In sub style override the properties you need -->
<Style BasedOn="{StaticResource Default}" TargetType="Button" x:Key="SubButton" >
<Setter Property="FontSize" Value="8pt" />
</Style>
</Grid.Resources>
<Button Content="Main" Height="51" HorizontalAlignment="Left" Margin="154,72,0,0" Name="button1" VerticalAlignment="Top" Width="141" />
<Button Content="Sub" Style="{StaticResource SubButton}" Height="51" HorizontalAlignment="Left" Margin="154,162,0,0" Name="button2" VerticalAlignment="Top" Width="141" />
</Grid>
Ответ 2
У меня есть (в моем приложении WPF) стили default (base), определенные в ResourceDictionary в App.xaml(в проекте запуска). Например, для кнопки следующим образом.
<Style TargetType="Button">
<Setter Property="Margin" Value="5"/>
<Setter Property="FontWeight" Value="DemiBold"/>
<Setter Property="FontSize" Value="16"/>
</Style>
Во всех представлениях я использую (по умолчанию) этот общий стиль (автоматически унаследованный)! Когда мне нужно изменить или добавить какое-либо свойство в стиле по умолчанию (определенное в App.xaml), я создаю новый стиль, основанный на стиле по умолчанию.
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<!-- change -->
<Setter Property="Margin" Value="10" />
<!-- add -->
<Setter Property="Foreground" Value="Red" />
</Style>
Когда мне нужен скрытый или сильно переопределенный стиль по умолчанию (в некотором смысле), я создаю новый стиль (основанный на ничего).
<Style TargetType="Button"/>
Вы, конечно, можете продолжить наследование в App.xaml или в определенном представлении. Вы можете создать новый стиль с именем по умолчанию и использовать новый стиль по имени. Например, стиль RedButton и GreenButton.
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}" x:Key="RedButton">
<Setter Property="Foreground" Value="Red" />
</Style>
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}" x:Key="GreenButton">
<Setter Property="Foreground" Value="Green" />
</Style>
Etc...
ПРИМЕЧАНИЕ: вместо этого определите свой стиль в App.xaml, вы можете использовать автономную библиотеку (dll) только с стилями и ResourceDictionary из вашей библиотеки в App.xaml ResourceDictionary.MergedDictionaries.
Ответ 3
Стандартным подходом к созданию настраиваемого шаблона управления является использование TemplateBinding в шаблоне для привязки к свойствам элемента управления, а затем для установки этих свойств в дочерних стилях.
Например, это создает шаблон кнопки с элементом управления границей и привязывает фон границы к свойству Background Button. Установив свойство Background для Button в других стилях, он изменит свойство Background на границе.
<StackPanel>
<StackPanel.Resources>
<Style x:Key="BaseButtonStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}">
<ContentPresenter/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="BlueButtonStyle" TargetType="Button"
BasedOn="{StaticResource BaseButtonStyle}">
<Setter Property="Background" Value="Blue"/>
</Style>
<Style x:Key="RedButtonStyle" TargetType="Button"
BasedOn="{StaticResource BaseButtonStyle}">
<Setter Property="Background" Value="Red"/>
</Style>
</StackPanel.Resources>
<Button Style="{StaticResource RedButtonStyle}">Red</Button>
<Button Style="{StaticResource BlueButtonStyle}">Blue</Button>
</StackPanel>
Многие из свойств в Control предназначены для использования в шаблонах управления и не будут влиять на другое поведение, если они изменены. Это BorderBrush, BorderThickness, Background, Padding, HorizontalContentAlignment и VerticalContentAlignment.