본문 바로가기
Programming/C#

C#(WPF) - GUI 연습하기(with Material Design)

by Wilkyway 2021. 10. 29.
반응형

오늘은 아래 유튜브 영상의 데스크탑 어플리케이션을 구현해보겠습니다.

https://www.youtube.com/watch?v=sgEhK3mbDYo

 

 

1. 라이브러리 설치

이번 영상에서는 Material Design과 LiveCharts를 사용합니다. 아래의 명령으로 Package를 설치해줍니다.

dotnet add package MaterialDesignThemes --version 4.2.1 // material Design 설치
dotnet add package LiveCharts.Wpf --version 0.9.7 // live chart 설치

또는 Nuget GUI Manager 를 설치 후

 

Shift + Ctrl + P 로 명령창에서 Nuget 입력 시 나타나는 명령을 수행합니다.

그리고 Nuget Package Manager에서 아래와 같이 설치해줍니다. Material Design Themes와 Livecharts.wpf로 검색되는 패키지를 설치해줍니다.


2. 라이브러리 적용

Material Design을 적용해야합니다. 적용하는 방법은 구글에서 < material design xaml >이라고 검색하면 나오는데, 여기 사이트를 참조하시면 되겠습니다. 그리고, 나중에 livechart에서 사용할 스타일도 정의해놓겠습니다.

<App.xaml>

<Application x:Class="wpf_test04UT1.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:wpf_test04UT1"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
         <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml" />
                <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
                <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.DeepPurple.xaml" />
                <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.Lime.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

 

추가로, WS Simple Gallifreyan 폰트가 강좌 중간에 필요합니다. 적당히 다운받아 사용 가능한데, 이번엔 패스하겠습니다.

 

3. 구현

<MainWindow.xaml>

<Window x:Class="wpf_test04UT1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
        xmlns:MetroChart="clr-namespace:De.TorstenMandelkow.MetroChart;assembly=De.TorstenMandelkow.MetroChart"
        xmlns:local="clr-namespace:wpf_test04UT1"
        mc:Ignorable="d"
        Title="MainWindow" Height="800" Width="1024"
        WindowStyle="None">
        
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="200" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="30"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <Grid Grid.Column="1" Grid.Row="1" Background="#FFE6E6E6">
            <ScrollViewer>
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="200"/>
                        <RowDefinition Height="*"/>
                        <RowDefinition Height="*"/>
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="1*"/>
                        <ColumnDefinition Width="1*"/>
                        <ColumnDefinition Width="1*"/>
                    </Grid.ColumnDefinitions>
                    
                    <Grid Grid.Column="0">
                        <Rectangle Height="120" Margin="20" Fill="White" RadiusY="10" RadiusX="10">
                            <Rectangle.Effect>
                                <DropShadowEffect BlurRadius="20"/>
                            </Rectangle.Effect>
                        </Rectangle>
                        <Grid Margin="25" Height="120">
                            <Grid Width="35" Height="50" Background="#FFFFAF24" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="20 0">
                                <Grid.Effect>
                                    <DropShadowEffect BlurRadius="20"/>
                                </Grid.Effect>
                                <materialDesign:PackIcon Kind="ContentCopy" HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="5" Foreground="White" Width="20" Height="20"/>
                            </Grid>
                            <TextBlock Text="Espaco Usado" HorizontalAlignment="Right" FontFamily="Champagne &amp; Limousines" Margin="5" VerticalAlignment="Top" Foreground="Gray"/>
                            <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="10 20">
                                <TextBlock Text="49/50" FontFamily="Champagne &amp; Limousines" VerticalAlignment="Center" Foreground="Gray" FontSize="50"/>
                                <TextBlock Text="GB" FontFamily="Champagne &amp; Limousines" Margin="0 5" VerticalAlignment="Bottom" Foreground="Gray" FontSize="20" />
                            </StackPanel>
                            <StackPanel Orientation="Horizontal" VerticalAlignment="Bottom" Margin="20" Cursor="Hand">
                                <materialDesign:PackIcon Kind="AlertOutline" Foreground="Red" Width="10" Height="10" VerticalAlignment="Center" Margin="5 0"/>
                                <TextBlock Text="AAdquirir mais espaco" FontSize="10" Foreground="#FF8522BD"/>
                            </StackPanel>
                        </Grid>
                    </Grid>

                    <Grid Grid.Column="1">
                        <Rectangle Height="120" Margin="20" Fill="White" RadiusY="10" RadiusX="10">
                            <Rectangle.Effect>
                                <DropShadowEffect BlurRadius="20"/>
                            </Rectangle.Effect>
                        </Rectangle>
                        <Grid Margin="25" Height="120">
                            <Grid Width="35" Height="50" Background="#FF41A43C" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="20 0">
                                <Grid.Effect>
                                    <DropShadowEffect BlurRadius="20"/>
                                </Grid.Effect>
                                <materialDesign:PackIcon Kind="Store" HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="5" Foreground="White" Width="20" Height="20"/>
                            </Grid>
                            <TextBlock Text="Receita" HorizontalAlignment="Right" FontFamily="Champagne &amp; Limousines" Margin="5" VerticalAlignment="Top" Foreground="Gray"/>
                            <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="10 30">
                                <TextBlock Text="R$" FontFamily="Champagne &amp; Limousines" VerticalAlignment="Bottom" Margin="0 2" Foreground="Gray" FontSize="20"/>
                                <TextBlock Text="35.674,00" FontFamily="Champagne &amp; Limousines"  VerticalAlignment="Bottom" Foreground="Gray" FontSize="25" />
                            </StackPanel>
                            <StackPanel Orientation="Horizontal" VerticalAlignment="Bottom" Margin="20" Cursor="Hand">
                                <materialDesign:PackIcon Kind="Calendar" Foreground="Gray" Width="10" Height="10" VerticalAlignment="Center" Margin="5 0"/>
                                <TextBlock Text="Ultimas 24h" FontSize="10" Foreground="Gray"/>
                            </StackPanel>
                        </Grid>
                    </Grid>

                    <Grid Grid.Column="2">
                        <Rectangle Height="120" Margin="20" Fill="White" RadiusY="10" RadiusX="10">
                            <Rectangle.Effect>
                                <DropShadowEffect BlurRadius="20"/>
                            </Rectangle.Effect>
                        </Rectangle>
                        <Grid Margin="25" Height="120">
                            <Grid Width="35" Height="50" Background="#FFCF1F1F" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="20 0">
                                <Grid.Effect>
                                    <DropShadowEffect BlurRadius="20"/>
                                </Grid.Effect>
                                <materialDesign:PackIcon Kind="InformationOutline" HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="5" Foreground="White" Width="20" Height="20"/>
                            </Grid>
                            <TextBlock Text="Erros Corrigidos" HorizontalAlignment="Right" FontFamily="Champagne &amp; Limousines" Margin="5" VerticalAlignment="Top" Foreground="Gray"/>
                            <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="10 30">                                
                                <TextBlock Text="75" FontFamily="Champagne &amp; Limousines"  VerticalAlignment="Center" Foreground="Gray" FontSize="40" />
                            </StackPanel>
                            <StackPanel Orientation="Horizontal" VerticalAlignment="Bottom" Margin="20" Cursor="Hand">
                                <materialDesign:PackIcon Kind="Github" FontSize="15" Foreground="Gray" Width="10" Height="10" VerticalAlignment="Center" Margin="5 0"/>
                                <TextBlock Text="Monitorado pelo Git Hub" FontSize="11" Foreground="Gray"/>
                            </StackPanel>
                        </Grid>
                    </Grid>     

                    <Grid Grid.Row="1" Grid.RowSpan="2" Grid.ColumnSpan="3" HorizontalAlignment="Center" Width="580" Height="550"> 
                        <Grid Background="White" Margin="20 50 20 20">
                            <Grid.OpacityMask>
                                <VisualBrush Visual="{ Binding ElementName=BorderG1 }"/>
                            </Grid.OpacityMask>
                            <Border x:Name="BorderG1" CornerRadius="5" Background="White" />
                            <StackPanel VerticalAlignment="Bottom">
                                <TextBlock Text="Receita Diaria" FontFamily="Champagne &amp; Limousines" Margin="20 10" VerticalAlignment="Bottom" Foreground="Gray" FontSize="30"/>
                                <StackPanel Orientation="Horizontal" Margin="20 5" >
                                    <materialDesign:PackIcon Kind="ArrowUp" Foreground="Green" VerticalAlignment="Center"/>
                                    <TextBlock Text="55%" FontFamily="Champagne &amp; Limousines" VerticalAlignment="Bottom" Foreground="Green" FontSize="15"/>
                                    <TextBlock Text="Crescimento nas vendas hoje" Margin="20 0" FontFamily="Champagne &amp; Limousines" VerticalAlignment="Bottom" Foreground="Gray" FontSize="20"/>   
                                </StackPanel>
                                <StackPanel Orientation="Horizontal" Margin="10 5" >
                                    <materialDesign:PackIcon Kind="Clock" Foreground="Gray" VerticalAlignment="Center"/>                                    
                                    <TextBlock Text="Atualizado a 4 minutos" Margin="5 0" FontFamily="Champagne &amp; Limousines" VerticalAlignment="Bottom" Foreground="Gray" FontSize="20"/>   
                                </StackPanel>
                            </StackPanel>                            

                        </Grid>
                        <Grid Margin="50 20 50 200">
                            <Grid.OpacityMask>
                                <VisualBrush Visual="{ Binding ElementName=BorderG2 }"/>
                            </Grid.OpacityMask>
                            <Border x:Name="BorderG2" CornerRadius="15" Background="#FF340051" />

                            <MetroChart:RadialGaugeChart Background="{x:Null}" ChartTitle="Consumo" ChartSubTitle="" Foreground="LightGray" HorizontalAlignment="Center">
                                <MetroChart:RadialGaugeChart.Series>
                                    <MetroChart:ChartSeries
                                        DisplayMember="Titulo"
                                        ItemsSource="{Binding Path=Consumo}"
                                        SeriesTitle="Consumo"
                                        ValueMember="Porcentagem" />
                                </MetroChart:RadialGaugeChart.Series>
                            </MetroChart:RadialGaugeChart>
                        </Grid>                    
                    </Grid>               
                </Grid>
            </ScrollViewer>
        </Grid>

        <Grid Grid.Row="1">
            <Grid.Background>
                <LinearGradientBrush EndPoint="0 1" StartPoint="0 0">
                    <GradientStop Offset="0.0" Color="#aeaeae" />
                    <GradientStop Offset="1.0" Color="#888" />
                </LinearGradientBrush>
            </Grid.Background>
            <Grid.RowDefinitions>
                <RowDefinition Height="100"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <Grid.Effect>
                <DropShadowEffect BlurRadius="20"/>                
            </Grid.Effect>            

            <Grid Background="#ffa46fe4">
                <TextBlock Text="DASHBOARD" HorizontalAlignment="Center" VerticalAlignment="Center" FontFamily="WS Simple Gallifreyan" Foreground="#FFBC96EA" FontSize="16"/>
            </Grid>

            <StackPanel Grid.Row="1">
            
                <Button Margin="10" Background="#FF8522BD" BorderBrush="#FF8522BD">
                    <Grid Width="150">
                        <materialDesign:PackIcon Kind="ViewDashboard" VerticalAlignment="Center"/>
                        <TextBlock HorizontalAlignment="Center" Text="DASHBOARD"/>
                    </Grid>
                </Button>
                
                <Button Margin="10" Background="#FF8522BD" BorderBrush="#FF8522BD">
                    <Grid Width="150">
                        <materialDesign:PackIcon Kind="Account" VerticalAlignment="Center"/>
                        <TextBlock HorizontalAlignment="Center" Text="PROFILE"/>
                    </Grid>
                </Button>

                <Button Margin="10" Background="#FF8522BD" BorderBrush="#FF8522BD">
                    <Grid Width="150">
                        <materialDesign:PackIcon Kind="ContentPaste" VerticalAlignment="Center"/>
                        <TextBlock HorizontalAlignment="Center" Text="TABLES"/>
                    </Grid>
                </Button>

                <Button Margin="10" Background="#FF8522BD" BorderBrush="#FF8522BD">
                    <Grid Width="150">
                        <materialDesign:PackIcon Kind="TruckDelivery" VerticalAlignment="Center"/>
                        <TextBlock HorizontalAlignment="Center" Text="PROVIDERS"/>
                    </Grid>
                </Button>

                <Button Margin="10" Background="#FF8522BD" BorderBrush="#FF8522BD">
                    <Grid Width="150">
                        <materialDesign:PackIcon Kind="Settings" VerticalAlignment="Center"/>
                        <TextBlock HorizontalAlignment="Center" Text="CONFIGURATIONS"/>
                    </Grid>
                </Button>

            </StackPanel>
        </Grid>

        <Grid x:Name="GridBarraTitulo"  Grid.ColumnSpan="2" Background="#FF8522BD" MouseDown="GridBarraTitulo_MouseDown">
            <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Background="{x:Null}" Margin="10,0">
                <Button Style="{StaticResource MaterialDesignFloatingActionMiniAccentButton}" Width="25" Height="25" Background="{x:Null}" BorderBrush="{x:Null}" Foreground="White">
                    <materialDesign:PackIcon Kind="Bell"/>
                </Button>
                <Button Style="{StaticResource MaterialDesignFloatingActionMiniAccentButton}" Width="25" Height="25" Background="{x:Null}" BorderBrush="{x:Null}" Foreground="White">
                    <materialDesign:PackIcon Kind="Account"/>
                </Button>
                <Button x:Name="ButtonFecher" Style="{StaticResource MaterialDesignFloatingActionMiniAccentButton}" Width="25" Height="25" Background="{x:Null}" BorderBrush="{x:Null}" Foreground="White" Click="ButtonFechar_Click">
                    <materialDesign:PackIcon Kind="Power"/>
                </Button>
            </StackPanel>
        </Grid>
    </Grid>
</Window>

 

<MainWindow.xaml.cs (데이터 주입부)>

using System.Windows;
using System.Collections.Generic;

namespace wpf_test04UT1
{
  /// <summary>
  /// Interaction logic for MainWindow.xaml
  /// </summary>
  public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            Consumo consumo = new Consumo();
            DataContext = new ConsumoViewModel(consumo);
        }
        private void ButtonFechar_Click(object sender, RoutedEventArgs e){
            Application.Current.Shutdown();
        }
        private void GridBarraTitulo_MouseDown(object sender, RoutedEventArgs e){
            DragMove();
        }


    }
    internal class ConsumoViewModel{
        public List<Consumo> Consumo { get;  private set; }

        public ConsumoViewModel(Consumo consumo){
            Consumo = new List<Consumo>();
            Consumo.Add(consumo);
    }
    }

    internal class Consumo {
        public string Titulo { get; private set; }
        public int Porcentagem{ get; private set; }
        public Consumo(){
        Titulo = "Consum, Atual";
        Porcentagem = CalcularPorcentagem();

        }
        private int CalcularPorcentagem(){
            return 47; //
        }
  }
}

 

4. 결과

커맨드창에서 

dotnet build
dotnet run

하면 아래와 같이 이쁜 UI가 실행됩니다.

...이거 하느라...3시간 반 동영상보며 따라했네요..ㅠㅠ. 그래도 이쁜 결과물이 나와줘서 뿌듯합니다.

 

~~~끝~~~

반응형

댓글