시각적 상태
.NET 다중 플랫폼 앱 UI(.NET MAUI) Visual State Manager는 코드에서 사용자 인터페이스를 시각적으로 변경하는 구조화된 방법을 제공합니다. 대부분의 경우 앱의 사용자 인터페이스는 XAML에 정의되며, 이 XAML에는 Visual State Manager가 사용자 인터페이스의 시각적 개체에 미치는 영향을 설명하는 태그가 포함될 수 있습니다.
Visual State Manager는 시각적 상태의 개념을 소개합니다. A와 같은 Button .NET MAUI 보기는 기본 상태에 따라 여러 가지 시각적 모양을 가질 수 있습니다.(비활성화되었든 누르든 입력 포커스가 있든 관계없이). 단추의 상태입니다. 시각적 상태는 시각적 상태 그룹에서 수집됩니다. 시각적 상태 그룹 내의 모든 시각적 상태는 상호 배타적입니다. 시각적 상태와 시각적 상태 그룹은 모두 간단한 텍스트 문자열로 식별됩니다.
.NET MAUI Visual State Manager는 다음 시각적 상태로 명명된 CommonStates
시각적 상태 그룹을 정의합니다.
- 일반
- 사용 안 함
- 포커스
- 선택한 상태
- PointerOver
Normal
, Disabled
, Focused
및 PointerOver
시각적 상태는 기본 클래스인 에서 파생되는 모든 클래스 View 에서 VisualElement지원됩니다Page. 또한 고유한 시각적 상태 그룹 및 시각적 상태를 정의할 수도 있습니다.
Visual State Manager를 사용하여 코드 숨김에서 직접 시각적 요소에 액세스하는 대신 모양을 정의하는 장점은 모든 UI 디자인을 한 위치에 유지하는 XAML에서 시각적 요소가 완전히 다른 상태에 반응하는 방식을 제어할 수 있다는 것입니다.
참고 항목
트리거는 보기의 속성 변경 또는 이벤트 발생에 따라 사용자 인터페이스의 시각적 개체를 변경할 수도 있습니다. 그러나 트리거를 사용하여 이러한 변경 내용의 다양한 조합을 처리하는 것은 혼란스러울 수 있습니다. Visual State Manager를 사용하면 시각적 상태 그룹 내의 시각적 상태는 항상 상호 배타적입니다. 언제든지 각 그룹의 상태 하나만 현재 상태입니다.
일반적인 시각적 상태
Visual State Manager를 사용하면 보기가 정상이거나, 비활성화되어 있거나, 입력 포커스가 있거나, 마우스 커서를 마우스로 가리키지만 누르지 않는 경우 보기의 시각적 모양을 변경할 수 있는 태그를 XAML 파일에 포함할 수 있습니다. 이를 공통 상태로 알려져 있습니다.
예를 들어 페이지에 보기가 Entry 있고 시각적 모양이 Entry 다음과 같은 방식으로 변경되도록 하려는 경우를 가정해 보겠습니다.
- Entry 사용할 수 없는 경우 분홍색 배경이 Entry 있어야 합니다.
- 일반적으로 Entry 라임 배경이 있어야합니다.
- Entry 입력 포커스가 있는 경우 정상 높이의 두 배로 확장해야 합니다.
- Entry 마우스 커서를 마우스로 가리키지만 누르지 않은 경우 연한 파란색 배경이 있어야 합니다.
Visual State Manager 태그를 개별 보기에 연결하거나 여러 보기에 적용되는 경우 스타일에서 정의할 수 있습니다.
보기에서 시각적 상태 정의
클래스는 VisualStateManager
뷰에 VisualStateGroups
시각적 상태를 연결하는 데 사용되는 연결된 속성을 정의합니다. 속성은 VisualStateGroups
개체 컬렉션인 형식 VisualStateGroupList
입니다 VisualStateGroup
. 따라서 연결된 속성의 VisualStateManager.VisualStateGroups
자식은 개체입니다 VisualStateGroup
. 이 개체는 x:Name
그룹의 이름을 나타내는 특성을 정의합니다. 또는 클래스는 VisualStateGroup
대신 사용할 수 있는 속성을 정의 Name
합니다. 연결된 속성에 대한 자세한 내용은 연결된 속성을 참조 하세요.
클래스는 VisualStateGroup
개체 컬렉션 VisualState 인 명명States
된 속성을 정의합니다. States
는 클래스의 VisualStateGroups
콘텐츠 속성이므로 개체를 VisualState 의 자식으로 포함할 VisualStateGroup
수 있습니다. 각 VisualState 개체는 사용하거나 Name
.를 사용하여 x:Name
식별해야 합니다.
클래스는 VisualState 개체 컬렉션 Setter 인 명명Setters
된 속성을 정의합니다. 이러한 개체는 개체에서 사용하는 것과 동일한 Setter 개체입니다 Style . Setters
는 콘텐츠 속성이 아니므로 속성 VisualState에 대한 Setters
속성 요소 태그를 포함해야 합니다. Setter 개체를 다음의 Setters
자식으로 삽입해야 합니다. 각 Setter 개체는 해당 상태가 현재 상태일 때 속성의 값을 나타냅니다. 개체에서 참조하는 Setter 모든 속성은 바인딩 가능한 속성으로 지원되어야 합니다.
Important
시각적 상태 개체가 올바르게 VisualStateGroup
작동하려면 상태에 Setter 대한 Normal
개체를 VisualState 포함해야 합니다. 이 시각적 상태에 개체가 Setter 없으면 빈 시각적 상태(<VisualState Name="Normal" />
)로 포함해야 합니다.
다음 예제에서는 다음에 정의된 Entry시각적 상태를 보여줍니다.
<Entry FontSize="18">
<VisualStateManager.VisualStateGroups>
<VisualStateGroupList>
<VisualStateGroup Name="CommonStates">
<VisualState Name="Normal">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Lime" />
</VisualState.Setters>
</VisualState>
<VisualState Name="Focused">
<VisualState.Setters>
<Setter Property="FontSize" Value="36" />
</VisualState.Setters>
</VisualState>
<VisualState Name="Disabled">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Pink" />
</VisualState.Setters>
</VisualState>
<VisualState Name="PointerOver">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="LightBlue" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</VisualStateManager.VisualStateGroups>
</Entry>
다음 스크린샷은 정의된 네 가지 시각적 상태의 상태를 보여줍니다 Entry .
Entry 상태가 되면 배경은 Normal
라임입니다. 게인 Entry 입력 포커스가 발생하면 글꼴 크기가 두 배로 증가합니다. 비활성화 Entry 되면 배경이 분홍색이 됩니다. 입력 포커스를 얻을 때 라임 배경은 Entry 유지되지 않습니다. 마우스 포인터를 마우스로 가리키 Entry지만 누르지 않으면 배경이 Entry 연한 파란색이 됩니다. Visual State Manager가 시각적 상태 간에 전환되면 이전 상태에서 설정한 속성이 설정되지 않습니다. 따라서 시각적 상태는 함께 사용할 수 없습니다.
라임 배경이 Entry 상태에 있도록 하려면 해당 시각적 상태에 다른 Setter 배경을 Focused
추가합니다.
<VisualState Name="Focused">
<VisualState.Setters>
<Setter Property="FontSize" Value="36" />
<Setter Property="BackgroundColor" Value="Lime" />
</VisualState.Setters>
</VisualState>
스타일에서 시각적 상태 정의
두 개 이상의 보기에서 동일한 시각적 상태를 공유해야 하는 경우가 많습니다. 이 시나리오에서는 시각적 상태를 에 정의 Style할 수 있습니다. 이 작업은 속성에 대한 VisualStateManager.VisualStateGroups
개체를 Setter 추가하여 수행할 수 있습니다. 개체의 Setter 콘텐츠 속성은 해당 Value
속성이므로 개체의 Setter 자식으로 지정할 수 있습니다. VisualStateGroups
속성은 형식이므로 개체의 Setter 자식은 개체를 포함하는 VisualState 추가할 수 있는 자식VisualStateGroupList
입니다 VisualStateGroup
VisualStateGroupList
.
다음 예제에서는 공통 시각적 상태를 정의하는 암시적 스타일을 Entry 보여 줍니다.
<Style TargetType="Entry">
<Setter Property="FontSize" Value="18" />
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup Name="CommonStates">
<VisualState Name="Normal">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Lime" />
</VisualState.Setters>
</VisualState>
<VisualState Name="Focused">
<VisualState.Setters>
<Setter Property="FontSize" Value="36" />
<Setter Property="BackgroundColor" Value="Lime" />
</VisualState.Setters>
</VisualState>
<VisualState Name="Disabled">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Pink" />
</VisualState.Setters>
</VisualState>
<VisualState Name="PointerOver">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="LightBlue" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
이 스타일이 페이지 수준 리소스 사전에 포함되면 개체가 Style 페이지의 모든 Entry 개체에 적용됩니다. 따라서 페이지의 모든 Entry 개체는 시각적 상태에 동일한 방식으로 응답합니다.
.NET MAUI의 시각적 상태
다음 표에서는 .NET MAUI에 정의된 시각적 상태를 나열합니다.
클래스 | 상태 | 추가 정보 |
---|---|---|
Button | Pressed |
단추 시각적 상태 |
CarouselView | DefaultItem , CurrentItem , PreviousItem NextItem |
CarouselView 시각적 상태 |
CheckBox | IsChecked |
CheckBox 시각적 상태 |
CollectionView | Selected |
CollectionView 시각적 상태 |
ImageButton | Pressed |
ImageButton 시각적 상태 |
RadioButton | Checked , Unchecked |
RadioButton 시각적 상태 |
Switch | On , Off |
시각적 상태 전환 |
VisualElement | Normal , Disabled , Focused PointerOver |
공통 상태 |
여러 요소에 상태 설정
이전 예제에서 시각적 상태는 단일 요소에 연결되고 작동되었습니다. 그러나 단일 요소에 연결되어 있지만 동일한 범위 내의 다른 요소에 대한 속성을 설정하는 시각적 상태를 만들 수도 있습니다. 이렇게 하면 상태가 작동하는 각 요소에 대해 시각적 상태를 반복할 필요가 없습니다.
형식에는 Setter TargetName
시각적 상태에 대해 조작할 대상 개체를 나타내는 형식 string
의 Setter 속성이 있습니다. 속성이 TargetName
정의되면 정의된 TargetName
개체의 집합 Property
은 다음과 같습니다Value
Setter.
<Setter TargetName="label"
Property="Label.TextColor"
Value="Red" />
이 예제에서는 명명 label
된 Label 속성이 TextColor
.로 Red
설정됩니다. 속성을 설정할 때는 TargetName
속성의 전체 경로를 Property
지정해야 합니다. 따라서 속성을 LabelProperty
설정 TextColor
하려면 .로 Label.TextColor
지정됩니다.
참고 항목
개체에서 참조하는 Setter 모든 속성은 바인딩 가능한 속성으로 지원되어야 합니다.
다음 예제에서는 단일 시각적 상태 그룹에서 여러 개체의 상태를 설정하는 방법을 보여 있습니다.
<StackLayout>
<Label Text="What is the capital of France?" />
<Entry x:Name="entry"
Placeholder="Enter answer" />
<Button Text="Reveal answer">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="CommonStates">
<VisualState Name="Normal" />
<VisualState Name="Pressed">
<VisualState.Setters>
<Setter Property="Scale"
Value="0.8" />
<Setter TargetName="entry"
Property="Entry.Text"
Value="Paris" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Button>
</StackLayout>
이 예제에서는 Normal
눌렀을 때 Button 상태가 활성 상태이고 응답을 입력 Entry할 수 있습니다. Pressed
누를 때 Button 상태가 활성화되고 해당 Scale
속성이 기본값 1에서 0.8로 변경되도록 지정합니다. 또한 명명 entry
된 Entry 속성은 Text
파리로 설정됩니다. 따라서 눌렀을 때 Button 크기가 약간 작게 조정되고 파리가 Entry 표시됩니다.
그런 다음 릴리스 Button 되면 기본값 1로 다시 크기가 조정되고 Entry 이전에 입력한 텍스트가 표시됩니다.
Important
속성 경로는 속성을 지정 TargetName
하는 요소에서 Setter 지원되지 않습니다.
사용자 지정 시각적 상태 정의
사용자 지정 시각적 상태는 공통 상태에 대한 시각적 상태를 정의하는 것처럼 정의하고 선택한 이름을 사용하여 구현한 다음 상태를 활성화하기 위해 메서드를 호출 VisualStateManager.GoToState
하여 구현할 수 있습니다.
다음 예제에서는 입력 유효성 검사에 Visual State Manager를 사용하는 방법을 보여줍니다.
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="VsmDemos.VsmValidationPage"
Title="VSM Validation">
<StackLayout x:Name="stackLayout"
Padding="10, 10">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="ValidityStates">
<VisualState Name="Valid">
<VisualState.Setters>
<Setter TargetName="helpLabel"
Property="Label.TextColor"
Value="Transparent" />
<Setter TargetName="entry"
Property="Entry.BackgroundColor"
Value="Lime" />
</VisualState.Setters>
</VisualState>
<VisualState Name="Invalid">
<VisualState.Setters>
<Setter TargetName="entry"
Property="Entry.BackgroundColor"
Value="Pink" />
<Setter TargetName="submitButton"
Property="Button.IsEnabled"
Value="False" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Label Text="Enter a U.S. phone number:"
FontSize="18" />
<Entry x:Name="entry"
Placeholder="555-555-5555"
FontSize="18"
Margin="30, 0, 0, 0"
TextChanged="OnTextChanged" />
<Label x:Name="helpLabel"
Text="Phone number must be of the form 555-555-5555, and not begin with a 0 or 1" />
<Button x:Name="submitButton"
Text="Submit"
FontSize="18"
Margin="0, 20"
VerticalOptions="Center"
HorizontalOptions="Center" />
</StackLayout>
</ContentPage>
이 예제에서는 시각적 상태가 연결 StackLayout되고 두 개의 상호 배타적인 상태와 이름이 Valid
지정됩니다 Invalid
. Entry 유효한 전화 번호가 없으면 현재 상태가 Invalid
분홍색 배경이 있고 Entry 두 번째 Label 가 표시되고 Button 비활성화됩니다. 유효한 전화 번호를 입력하면 현재 상태가 됩니다 Valid
. 라임 Entry 배경을 가져오고Button, 두 번째 Label 배경이 사라지고, 이제 활성화됩니다.
코드 숨김 파일은 TextChanged
.Entry 처리기는 정규식을 사용하여 입력 문자열이 유효한지 여부를 확인합니다. 코드 숨김 파일의 메서드는 GoToState
개체에서 정적 VisualStateManager.GoToState
메서드를 StackLayout 호출합니다.
public partial class VsmValidationPage : ContentPage
{
public VsmValidationPage()
{
InitializeComponent();
GoToState(false);
}
void OnTextChanged(object sender, TextChangedEventArgs args)
{
bool isValid = Regex.IsMatch(args.NewTextValue, @"^[2-9]\d{2}-\d{3}-\d{4}$");
GoToState(isValid);
}
void GoToState(bool isValid)
{
string visualState = isValid ? "Valid" : "Invalid";
VisualStateManager.GoToState(stackLayout, visualState);
}
}
이 예제에서는 GoToState
상태를 초기화하기 위해 생성자에서 메서드를 호출합니다. 항상 현재 상태가 있어야 합니다. 그런 다음 코드 숨김 파일은 시각적 상태를 정의하는 개체에서 상태 이름을 사용하여 호출 VisualStateManager.GoToState
합니다.
시각적 상태 트리거
시각적 상태는 적용해야 하는 조건을 정의하는 특수한 트리거 그룹인 상태 트리거를 VisualState 지원합니다.
상태 트리거는 VisualState의 StateTriggers 컬렉션에 추가됩니다. 이 컬렉션은 단일 상태 트리거 또는 여러 상태 트리거를 포함할 수 있습니다. 컬렉션의 상태 트리거가 활성 상태인 경우 VisualState가 적용됩니다.
상태 트리거를 사용하여 시각적 상태를 제어하는 경우 .NET MAUI는 다음 우선 순위 규칙을 사용하여 활성 상태인 트리거(및 해당 VisualState)를 결정합니다.
- StateTriggerBase에서 파생되는 모든 트리거.
- MinWindowWidth 조건을 충족하여 활성화되는 AdaptiveTrigger.
- MinWindowHeight 조건을 충족하여 활성화되는 AdaptiveTrigger.
여러 트리거가 동시에 활성화된 경우(예: 두 개의 사용자 지정 트리거) 태그에 선언된 첫 번째 트리거가 우선적으로 적용됩니다.
상태 트리거에 대한 자세한 내용은 상태 트리거를 참조하세요.
.NET MAUI