.NET MAUI - XAML 동적 리소스 사용 및 업데이트

2022. 7. 15. 00:00MAUI

반응형

StaticResource Mark-up Extension 은 사전 조회를 한번만 수행하므로 UI 를 동적으로 업데이트 할 수 없다.

또한 key 가 ResourceDictionary에 없는 경우 예외를 발생시킨다.

이러한 문제를 처리 하는 것이 동적 리소스(dynamic resources) 이다.

 

런타임에 리소스를 업데이트하는 방법

<ContentPage.Resources>
    <Color x:Key="PanelBackgroundColor">Blue</Color>
</ContentPage.Resources>

응용 프로그램이 실행되는 동안 PanelBackgroundColor 리소스의 값을 변경하려고 한다고 가정한다. 

페이지의 코드 숨김 파일에 아래와 같은 코드를 추가하여 Resources 속성에 액세스할 수 있다. 

다음 코드는 리소스 값을 다른 색으로 업데이트 한다.

 

this.Resources["PanelBackgroundColor"] = Colors.Green;

DynamicResource는 리소스 값이 변경되면 자동으로 UI를 업데이트한다. 

StaticResource와 달리 키값이 없어도 오류가 아니며 예외를 throw 하지 않는다.

** StaticResource 에 비해 약간의 성능 저하가 있다.

만약 리소스가 runtime 에 변경되지 않는다면 StaticResource 를 사용하자 **

<ContentPage ...>
    <ContentPage.Resources>
        <Color x:Key="PanelBackgroundColor">Blue</Color>
    </ContentPage.Resources>

    <StackLayout BackgroundColor="{DynamicResource PanelBackgroundColor}">
    ...
    </StackLayout>
</ContentPage>

예제)

MainPage.xaml.cs 를 열자

아래 부분을 찾아보자

각 컨트롤의 색상 설정에 대해 반복되는 코드를 확인하자

위의 코드를 아래와 같이 수정해 보자

void OnLight(object sender, EventArgs e)
{
    Resources["fgColor"] = colorNavy;
    Resources["bgColor"] = colorSilver;
}
void OnDark(object sender, EventArgs e)
{
    Resources["fgColor"] = colorSilver;
    Resources["bgColor"] = colorNavy;
}

코드를 실행하고 button 을 눌러도 변경이 되지 않는다. 

StaticResource 를 사용하였기 때문이다. DynamicResource 를 사용하도록 XAML 코드를 수정하자

MainPage.Xaml

<Grid x:Name ="LayoutRoot" BackgroundColor="{DynamicResource bgColor}" Padding="10">
...
<Label x:Name="billLabel"  Text="Bill"  TextColor="{DynamicResource fgColor}" ... />
<Label x:Name="tipLabel"   Text="Tip"   TextColor="{DynamicResource fgColor}" ... />
<Label x:Name="totalLabel" Text="Total" TextColor="{DynamicResource fgColor}" ... />
...

 

최종 코드

DynamicResource/MainPage.Xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MauiApp1.Xaml.DynamicResource.MainPage"
             Title="MainPage">
    <ContentPage.Resources>
        <ResourceDictionary>
            <Color x:Key="bgColor">#C0C0C0</Color>
            <Color x:Key="fgColor">#0000AD</Color>
            <x:Double x:Key="fontSize">22</x:Double>
        </ResourceDictionary>
    </ContentPage.Resources>
    
    <Grid x:Name ="LayoutRoot" BackgroundColor="Silver" Padding="10"
          ColumnDefinitions="*, 3*"
          RowDefinitions="Auto, Auto, Auto, Auto, *">


        <!-- Left column = static labels -->
        <Label x:Name="billLabel"  Text="Bill"  
               TextColor="{DynamicResource fgColor}" 
               FontSize="{DynamicResource fontSize}"
               FontAttributes="Bold" Grid.Row="0" Grid.Column="0" />
        <Label x:Name="tipLabel"   Text="Tip"   
               TextColor="{DynamicResource fgColor}" 
               FontSize="{DynamicResource fontSize}" 
               FontAttributes="Bold" Grid.Row="1" Grid.Column="0" />
        <Label x:Name="totalLabel" Text="Total" 
               TextColor="{DynamicResource fgColor}" 
               FontSize="{DynamicResource fontSize}" 
               FontAttributes="Bold" Grid.Row="2" Grid.Column="0" />

        <!-- Right column = user input and calculated-value output -->
        <Entry x:Name="billInput"   Placeholder="Enter Amount" 
               Keyboard="Numeric" TextColor="Gray" Grid.Row="0" Grid.Column="1" />
        <Label x:Name="tipOutput"   Text="0.00" 
               TextColor="{DynamicResource fgColor}" 
               FontSize="{DynamicResource fontSize}"  
               Grid.Row="1" Grid.Column="1" />
        <Label x:Name="totalOutput" Text="0.00" 
               TextColor="{DynamicResource fgColor}" 
               FontSize="{DynamicResource fontSize}"   
               Grid.Row="2" Grid.Column="1" />

        <!-- Navigate to advanced-view page -->
        <Button Text="Use Custom Calculator" Clicked="GotoCustom" 
                TextColor="White" Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" />

        <!-- Swap the foreground/background colors of this page -->
        <HorizontalStackLayout HorizontalOptions="Center" VerticalOptions="End" 
                               Spacing="100" Grid.Row="4" Grid.ColumnSpan="2">
            <Button Clicked="OnLight" Text="Light" TextColor="White" Grid.Column="0" />
            <Button Clicked="OnDark"  Text="Dark"  TextColor="White" Grid.Column="1" />
        </HorizontalStackLayout>

    </Grid>
</ContentPage>

DynamicResource/MainPage.Xaml.cs

namespace MauiApp1.Xaml.DynamicResource;

public partial class MainPage : ContentPage
{
    private Color colorNavy = Colors.Navy;
    private Color colorSilver = Colors.Silver;

    public MainPage()
    {
        InitializeComponent();
    }
    void CalculateTip()
    {
        double bill;

        if (Double.TryParse(billInput.Text, out bill) && bill > 0)
        {
            double tip = Math.Round(bill * 0.15, 2);
            double final = bill + tip;

            tipOutput.Text = tip.ToString("C");
            totalOutput.Text = final.ToString("C");
        }
    }

    void OnLight(object sender, EventArgs e)
    {
        LayoutRoot.BackgroundColor = colorSilver;

        tipLabel.TextColor = colorNavy;
        billLabel.TextColor = colorNavy;
        totalLabel.TextColor = colorNavy;
        tipOutput.TextColor = colorNavy;
        totalOutput.TextColor = colorNavy;
    }

    void OnDark(object sender, EventArgs e)
    {
        LayoutRoot.BackgroundColor = colorNavy;

        tipLabel.TextColor = colorSilver;
        billLabel.TextColor = colorSilver;
        totalLabel.TextColor = colorSilver;
        tipOutput.TextColor = colorSilver;
        totalOutput.TextColor = colorSilver;
    }

    async void GotoCustom(object sender, EventArgs e)
    {
        await Shell.Current.GoToAsync(nameof(CustomTipPage));
    }
}

 

실행

 

관련영상

https://youtu.be/tzTR0Jft0jw

 

반응형