WinUI 3 리소스 딕셔너리 버그?

WinUI 3 프로그래밍 중 이상한 버그를 경험을 해서 혹시나 동일하게 발생하는 증상인지 여쭤보려고 합니다.

스타일을 정의해두고 쓰려고 리소스 딕셔너리를 만들었는데, muxc의 몇몇 리소스 키는 리소스를 찾는 과정에서 예외가 발생합니다.

SampleStyle.xaml

// 생략
<Style x:Key="MyBorderStyle"
		   TargetType="Border">
	<Setter Property="Background" Value="{ThemeResource LayerFillColorDefaultBrush}"/>

</Style>

가령 위와 같이 리소스 딕셔너리 내에서 위와 같이 muxc의 리소스 키인 LayerFillColorDefaultBrush를 Background 값으로 주게 되면 자동 완성을 지원할 뿐더러 빌드도 정상적으로 되지만 실행 시에는 예외가 발생합니다.

리소스 딕셔너리에서 muxc를 merge 해주면 정상적으로 동작하기 때문에 처음에는 리소스 딕셔너리 파일 안에서 반드시 merge를 해줘야 하는구나 싶었는데 다른 소스코드를 보면 그건 또 아닌 것 같아서 여러 케이스를 테스트 해보니 혹시나 Style 관련 버그일 수도 있겠다는 생각이 듭니다.

[재현 방법]

  1. 리소스 딕셔너리 안에 Style 요소를 정의한다.
  2. 프로퍼티 setter에 특정 리소스 키를 사용한다. (LayerFillColorDefaultBrush 등)
<Style x:Key="MyBorderStyle" TargetType="Border">
	<Setter Property="Background" Value="{ThemeResource LayerFillColorDefaultBrush}"/>
</Style>
  1. App.xaml에 merge 후 앱 시작 시 충돌이 발생
<Application.Resources>
	<ResourceDictionary>
		<ResourceDictionary.MergedDictionaries>
			<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls"/>
			<ResourceDictionary Source="/Styles/SampleStyle.xaml"/>
		</ResourceDictionary.MergedDictionaries>
	</ResourceDictionary>
</Application.Resources>

[재현 조건]

  1. 리소스 딕셔너리 안에 정의된 요소가 하나 뿐이며, 그 요소가 Style인 경우
    두 개 이상의 요소가 있다면 충돌이 발생하지 않습니다. 가령 Style이 한 개일 때는 충돌이 발생하는 LayerFillColorDefaultBrush를, 다른 Style을 한 개 더 정의해 같이 사용할 때는 충돌이 발생하지 않습니다. 또한 DataTemplate 등 다른 요소는 한 개뿐이더라도 충돌이 발생하지 않는 것으로 보입니다.

  2. muxc의 특정 리소스 키를 참조하는 경우
    지금까지 확인해 본 바로는 LayerFillColorDefaultBrush, CardBackgroundFillColorDefaultBrush 같은 일부 키만 충돌하며, ApplicationPageBackgroundThemeBrush 같은 레거시 키는 Style 개수와 무관하게 충돌이 발생하지 않습니다.

  3. muxc를 리소스 딕셔너리 안에서 merge하지 않고 App.xaml에서 merge하는 경우
    리소스 딕셔너리 안에서 muxc를 merge하면 충돌이 발생하지 않습니다.

재현 코드(App.xaml)
<Application.Resources>
	<ResourceDictionary>
		<ResourceDictionary.MergedDictionaries>
			<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls"/>
			<ResourceDictionary Source="/Styles/SampleStyle.xaml"/>
		</ResourceDictionary.MergedDictionaries>
	</ResourceDictionary>
</Application.Resources>
재현 코드(SampleStyle.xaml)
	<!--// sol 1. muxc를 merge 해주면 정상적으로 동작. //-->
	<!--<ResourceDictionary.MergedDictionaries>
		<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls"/>
	</ResourceDictionary.MergedDictionaries>-->

	<!--// sol 2. 스타일을 하나 더 정의해 주면 정상적으로 동작 //-->
	<!--<Style x:Key="MyBorderStyleB"
		   TargetType="Border">
		<Setter Property="BorderThickness" Value="1"/>
	</Style>-->

	<!--// sol 3. Style이 아닌 요소는 개수에 무관하게 정상적으로 동작 //-->
	<!--<DataTemplate x:Key="MyDataTemplate" x:DataType="c:MyClass">
		<Grid Background="{ThemeResource LayerFillColorDefaultBrush}"/>
	</DataTemplate>-->
	
	<Style x:Key="MyBorderStyle"
		   TargetType="Border">

		<!--// 몇몇 ResourceKey는 오류 발생 //-->
		<Setter Property="Background" Value="{ThemeResource CardBackgroundFillColorDefaultBrush}"/>
		
		<!--// ApplicationPageBackgroundThemeBrush는 별다른 작업없이 정상적으로 동작 //-->
		<!--<Setter Property="Background" Value="{ThemeResource ApplicationPageBackgroundThemeBrush}"/>-->

	</Style>
4개의 좋아요

아래의 이슈와 연관이 있어 보입니다. 저도 유사한 문제를 겪었으며 현재는 뾰족한 효과적인 방법이 없습니다.

문제의 요지는 아래 글입니다.

3개의 좋아요

그렇군요… 가급적 데이터템플릿을 이용하는 쪽으로 해야겠네요 ㅠ

3개의 좋아요