XAML 결합 스타일은 BasedOn을 넘어서는가?
XAML에서 여러 스타일을 조합하여 원하는 설정을 모두 갖춘 새로운 스타일을 만들 수 있는 방법이 있습니까?
예를 들어 (의사 코드);
<Style x:key="A">
...
</Style>
<Style x:key="B">
...
</Style>
<Style x:key="Combined">
<IncludeStyle Name="A"/>
<IncludeStyle Name="B"/>
... other properties.
</Style>
나는 알고 있다.BasedOn
스타일에 대한 속성이지만, 그 기능은 어디까지만 사용할 수 있습니다.저는 이러한 '결합' 스타일을 만들기 위한 쉬운 방법을 찾고 있습니다.하지만 아까도 말했지만, 그런 말을 들어본 사람이 없는 이상 존재는 의심스럽군요?
스타일 특성과 트리거를 단일 스타일로 병합하는 사용자 정의 마크업 확장을 만들 수 있습니다.필요한 것은 다음 명령어를 추가하는 것 뿐입니다.MarkupExtension
- 를 사용하여 이름 공간에 대한 파생 클래스MarkupExtensionReturnType
속성이 정의되어 있고 실행 중입니다.
다음은 "css-like" 구문을 사용하여 스타일을 병합할 수 있는 확장입니다.
MultiStyleExtension.cs
[MarkupExtensionReturnType(typeof(Style))]
public class MultiStyleExtension : MarkupExtension
{
private string[] resourceKeys;
/// <summary>
/// Public constructor.
/// </summary>
/// <param name="inputResourceKeys">The constructor input should be a string consisting of one or more style names separated by spaces.</param>
public MultiStyleExtension(string inputResourceKeys)
{
if (inputResourceKeys == null)
throw new ArgumentNullException("inputResourceKeys");
this.resourceKeys = inputResourceKeys.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
if (this.resourceKeys.Length == 0)
throw new ArgumentException("No input resource keys specified.");
}
/// <summary>
/// Returns a style that merges all styles with the keys specified in the constructor.
/// </summary>
/// <param name="serviceProvider">The service provider for this markup extension.</param>
/// <returns>A style that merges all styles with the keys specified in the constructor.</returns>
public override object ProvideValue(IServiceProvider serviceProvider)
{
Style resultStyle = new Style();
foreach (string currentResourceKey in resourceKeys)
{
object key = currentResourceKey;
if (currentResourceKey == ".")
{
IProvideValueTarget service = (IProvideValueTarget)serviceProvider.GetService(typeof(IProvideValueTarget));
key = service.TargetObject.GetType();
}
Style currentStyle = new StaticResourceExtension(key).ProvideValue(serviceProvider) as Style;
if (currentStyle == null)
throw new InvalidOperationException("Could not find style with resource key " + currentResourceKey + ".");
resultStyle.Merge(currentStyle);
}
return resultStyle;
}
}
public static class MultiStyleMethods
{
/// <summary>
/// Merges the two styles passed as parameters. The first style will be modified to include any
/// information present in the second. If there are collisions, the second style takes priority.
/// </summary>
/// <param name="style1">First style to merge, which will be modified to include information from the second one.</param>
/// <param name="style2">Second style to merge.</param>
public static void Merge(this Style style1, Style style2)
{
if(style1 == null)
throw new ArgumentNullException("style1");
if(style2 == null)
throw new ArgumentNullException("style2");
if(style1.TargetType.IsAssignableFrom(style2.TargetType))
style1.TargetType = style2.TargetType;
if(style2.BasedOn != null)
Merge(style1, style2.BasedOn);
foreach(SetterBase currentSetter in style2.Setters)
style1.Setters.Add(currentSetter);
foreach(TriggerBase currentTrigger in style2.Triggers)
style1.Triggers.Add(currentTrigger);
// This code is only needed when using DynamicResources.
foreach(object key in style2.Resources.Keys)
style1.Resources[key] = style2.Resources[key];
}
}
다음으로 예를 제시하겠습니다.
<Style x:key="Combined" BasedOn="{local:MultiStyle A B}">
... other properties.
</Style>
빌트인 내에서 다른 두 가지 스타일 "A"와 "B"를 병합하여 "Combined"라는 새로운 스타일을 정의했습니다.BasedOn
속성(스타일 상속에 사용)필요에 따라 새로운 "Combined" 스타일에 다른 속성을 추가할 수 있습니다.
기타 예:
여기서는 4개의 버튼 스타일을 정의하며, 반복이 적은 다양한 조합으로 사용할 수 있습니다.
<Window.Resources>
<Style TargetType="Button" x:Key="ButtonStyle">
<Setter Property="Width" Value="120" />
<Setter Property="Height" Value="25" />
<Setter Property="FontSize" Value="12" />
</Style>
<Style TargetType="Button" x:Key="GreenButtonStyle">
<Setter Property="Foreground" Value="Green" />
</Style>
<Style TargetType="Button" x:Key="RedButtonStyle">
<Setter Property="Foreground" Value="Red" />
</Style>
<Style TargetType="Button" x:Key="BoldButtonStyle">
<Setter Property="FontWeight" Value="Bold" />
</Style>
</Window.Resources>
<Button Style="{local:MultiStyle ButtonStyle GreenButtonStyle}" Content="Green Button" />
<Button Style="{local:MultiStyle ButtonStyle RedButtonStyle}" Content="Red Button" />
<Button Style="{local:MultiStyle ButtonStyle GreenButtonStyle BoldButtonStyle}" Content="green, bold button" />
<Button Style="{local:MultiStyle ButtonStyle RedButtonStyle BoldButtonStyle}" Content="red, bold button" />
"를 사용할 수도 있습니다..
" 구문을 사용하여 유형(표준에 따라 다름)의 "현재" 기본 스타일을 몇 가지 추가 스타일과 병합합니다.
<Button Style="{local:MultiStyle . GreenButtonStyle BoldButtonStyle}"/>
위는 다음 기본 스타일을 병합합니다.TargetType="{x:Type Button}"
두 가지 보조 스타일이 있습니다.
신용 거래
나는 그 아이디어의 원안을 찾았다.MultiStyleExtension
bea.stollnitz.com에 접속해, 「」를 서포트하도록 변경했습니다..
현재 스타일을 참조하기 위한 표기법.
다음과 같이 BasedOn 속성을 스타일로 사용할 수 있습니다.
<Style x:Key="BaseButtons" TargetType="{x:Type Button}">
<Setter Property="BorderThickness" Value="0"></Setter>
<Setter Property="Background" Value="Transparent"></Setter>
<Setter Property="Cursor" Value="Hand"></Setter>
<Setter Property="VerticalAlignment" Value="Center"></Setter>
</Style>
<Style x:Key="ManageButtons" TargetType="{x:Type Button}" BasedOn="{StaticResource BaseButtons}">
<Setter Property="Height" Value="50"></Setter>
<Setter Property="Width" Value="50"></Setter>
</Style>
<Style x:Key="ManageStartButton" TargetType="{x:Type Button}" BasedOn="{StaticResource BaseButtons}">
<Setter Property="FontSize" Value="16"></Setter>
</Style>
및 용도:
<Button Style="{StaticResource ManageButtons}"></Button>
<Button Style="{StaticResource ManageStartButton}"></Button>
언급URL : https://stackoverflow.com/questions/5745001/xaml-combine-styles-going-beyond-basedon
'programing' 카테고리의 다른 글
다른 열이 null인 경우 열을 선택하십시오. (0) | 2023.04.17 |
---|---|
UITableView 헤더 섹션 커스터마이즈 (0) | 2023.04.17 |
Postgre 최적화신속한 테스트를 위한 SQL (0) | 2023.04.17 |
Linux에서 아이폰 앱 개발을 시작하시겠습니까? (0) | 2023.04.17 |
클릭하는 요소에 관계없이 WPF 창을 끌 수 있도록 설정 (0) | 2023.04.17 |