728x90
반응형
    private async void OnButtonClicked(object sender, EventArgs e)
    {
        // 확장자 기준 파일만
        PickOptions option = new PickOptions();
        option.PickerTitle = "Select File";
        option.FileTypes = FilePickerFileType.Pdf;
        var fileResult1 = await PickAndShow(option);

        // 이미지 파일만
        var fileResult = await PickAndShow(PickOptions.Images);

        if (fileResult != null)
        {
            var stream = await fileResult.OpenReadAsync();
            image.Source = ImageSource.FromStream(() => { return stream; });
        }
    }

    public async Task<FileResult> PickAndShow(PickOptions options)
    {
        try
        {
            var result = await FilePicker.Default.PickAsync(options);
            if (result != null)
            {
                if (result.FileName.EndsWith("jpg", StringComparison.OrdinalIgnoreCase) ||
                    result.FileName.EndsWith("png", StringComparison.OrdinalIgnoreCase))
                {
                    using var stream = await result.OpenReadAsync();
                    var image = ImageSource.FromStream(() => stream);
                }
            }

            return result;
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.ToString());
        }

        return null;
    }
반응형
728x90
반응형
var fileResult = await MediaPicker.PickPhotoAsync();
var stream = await fileResult.OpenReadAsync();
image.Source = ImageSource.FromStream(() => { return stream; });
반응형
728x90
반응형

QGIS 를 사용하기위해 기본적으로 지도정보를 가져와 사용할수 있어야하는데
우리나라 지도 같은 경우는 QGIS 의 플러그 인으로 제공하는 TMS for Korea 를 설치하면 Naver, Kakao 등의 맵정보를 불러와 사용할 수 있다.

설치는 간단하다.

QGIS 가 실행된 상태에서 플러그인>플러그인 관리 및 설치 를 선택한다

플로그인 창의 상단 검색창에 TMS for Korea 를 검색하면 아래처럼 나오고 플로그인 설치를 하면 된다. (현재 설치된 상태)

위 화면을 보면 알겠지만 업그레이드 여기서 가능하다.

위 플로그인을 설치하게되면 QGIS 메뉴의 웹>TMS for Korea 에서 원하는 맵을 선택하면 된다.

선택하면 레이어가 추가되면서 우리나라 지도가 나타난다. (Kakao Maps > Kakao Street)
(처음에 우리나라 전체 지도가 나오며 아래는 확대한 상태)

무료 프로그램이고 맵정보가 상당하다 보니 로딩에 시간이 좀 걸린다.

반응형
728x90
반응형

메뉴 > 플러그인 관리 및 설치 이동


Processing 을 찾아 체크

체크를 하면 메뉴에 '공간 처리' 항목이 표시된다.
공간 처리 > 툴박스 를 선택하면 공간처리 툴박스가 우측에 나타난다.

 

반응형
728x90
반응형

1. WPF .NET 6 프로젝트 생성

2. Nuget 설치
Syncfusion.PdfViewer.WPF 
System.Drawing.Common

3. PdfViewer 를 이용한 pdf 파일 로드
MainWindow.xaml

<Window x:Class="PdfTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:syncfusion="clr-namespace:Syncfusion.Windows.PdfViewer;assembly=Syncfusion.PdfViewer.WPF"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800"
        WindowState="Maximized">
    <Grid>
        <syncfusion:PdfViewerControl x:Name="pdfViewer"></syncfusion:PdfViewerControl>
    </Grid>
</Window>

MainWindow.xaml.cs

PdfLoadedDocument pdfLoadedDocument = new PdfLoadedDocument(@"test.pdf");
pdfViewer.ItemSource = pdfLoadedDocument;

 

4. Text Insert (폰트 유의 - 한글지원 폰트)
5페이지의 해당 좌표위치에 '테스트 테스트' 문자열을 추가합니다.

PdfLoadedPage page = pdfLoadedDocument.Pages[5] as PdfLoadedPage;

var graphics = page.Graphics;

// 1. Text Insert
PdfFont font = new PdfCjkStandardFont(PdfCjkFontFamily.HanyangSystemsShinMyeongJoMedium, 13);
graphics.DrawString("테스트도 테스트시", font, PdfBrushes.Black, new PointF(170, 107));

5. Image Insert
5페이지의 해당 좌표위치에 'kei.jpg' 이미지를 추가합니다.

PdfLoadedPage page = pdfLoadedDocument.Pages[5] as PdfLoadedPage;

var graphics = page.Graphics;

// 2. Image Insert
PdfBitmap image = new PdfBitmap("kei.jpg");
graphics.DrawImage(image, 110, 190);

6. Table Insert
Sample Data

DataTable table = new DataTable();
table.Columns.Add("순위/구분");
table.Columns.Add("시간/수량(mm)");
table.Columns.Add("시간/일시");
table.Columns.Add("일/수량(mm)");
table.Columns.Add("일/일시");

table.Rows.Add(new string[] { "1", "95", "1998.08.12", "407", "1998.08.12" });
table.Rows.Add(new string[] { "2", "67", "2020.08.28", "202", "2003.07.09" });
table.Rows.Add(new string[] { "3", "66", "1997.08.03", "197", "2016.07.04" });


PdfLightTable 사용

PdfLightTable pdfLightTable = new PdfLightTable();
pdfLightTable.DataSource = table;
pdfLightTable.Draw(graphics, new PointF(100, 200));


PdfGrid 사용

PdfGrid pdfGrid = new PdfGrid();
pdfGrid.DataSource = table;

pdfGrid.Columns[0].Width = 80;
pdfGrid.Columns[1].Width = 100;
pdfGrid.Columns[2].Width = 80;
pdfGrid.Columns[3].Width = 100;
pdfGrid.Columns[4].Width = 80;

PdfStringFormat format = new PdfStringFormat();
format.Alignment = PdfTextAlignment.Center;
format.LineAlignment = PdfVerticalAlignment.Bottom;

pdfGrid.Columns[0].Format = format;
pdfGrid.Columns[1].Format = format;
pdfGrid.Columns[2].Format = format;
pdfGrid.Columns[3].Format = format;
pdfGrid.Columns[4].Format = format;

PdfGridRowStyle pdfGridRowStyle = new PdfGridRowStyle();
pdfGridRowStyle.Font = new PdfCjkStandardFont(PdfCjkFontFamily.HanyangSystemsShinMyeongJoMedium, 13);
pdfGrid.Rows[0].Style = pdfGridRowStyle;
pdfGrid.Rows[1].Style = pdfGridRowStyle;
pdfGrid.Rows[2].Style = pdfGridRowStyle;
pdfGrid.Headers[0].Style = pdfGridRowStyle;

pdfGrid.Draw(graphics, new PointF(80, 400));

반응형
728x90
반응형

반복적인 using 처리를 하나의 파일에 global using 으로 정의해 주면 같은 프로젝트의 모든 파일들은 using 을 하지 않아도 된다.

기존

using System.Diagnostics;

namespace Test;

public class TestA
{
    public TestA()
    {
        Debug.Write("A");
    }
}
using System.Diagnostics;

namespace Test;

public class TestB
{
    public TestB()
    {
        Debug.Write("B");
    }
}


파일 2개에 using System.Diagnostics; 이 되어있는데 이를 GlobalUsings.cs 파일을 하나 추가하여 아래와 같이 해주면

global using System.Diagnostics;

프로젝트에 속한 모든 파일에 using 을 하지 않아도 using 이 된것처럼 사용이 가능하다

결과

namespace Test;

public class TestA
{
    public TestA()
    {
        Debug.Write("A");
    }
}
namespace Test;

public class TestB
{
    public TestB()
    {
        Debug.Write("B");
    }
}
반응형
728x90
반응형

- 커밋내역 보기
git log

- 과거로 돌아가기 (커밋해시는 처음 문자열 5,6 가지만 넣어도 됨)
git reset --hard 커밋해시

- 과거 커밋내용 삭제 (과거 커밋내용이 사라지는게 아니라 삭제하는 커밋이 추가됨)
git revert  커밋해시

- 브랜치 목록 보기
git branch 

- 브랜치 생성 (branch1)
git branch branch1

- 브랜치 이동
branch switch branch1

- 브랜치 생성 이동 (동시에)
git switch -c branch1

- 브랜치 이름 변경 (branch1 -> branch2)
git branch -m branch1 branch2  

- 브랜치 삭제
git branch -d branch1

- 브랜치 merge : 브랜치 작업을 main 에 머지 (머지커밋이 추가됨)
- 브랜치 rebase : 브랜치 작업을 main 에 이어붙임. 브랜치의 히스토리가 유지됨

- commit 메세지 변경 (최근거)
git commit --amend -m '메세지'

- 과거 commit 수정
git rebase -i 커밋해시
pick 을 r 로 변경 :wq
커밋메세지 수정 :wq

- 각 라인별 누가 수정했는지 알아내기
git blame 파일명

- 특정부분 누가 수정했는지 알아내기
git blame -L 시작라인번호,끝라인번호 파일명

- Tag 남기기 : 버전명을 Tag 로 남겨서 Release 할때 버전을 표시할때 사용
git tag v2.0.0
- Tag 목록보기
git tag

 

 

 

 

 

 

반응형
728x90
반응형

.NET 6.0 으로 프로젝트를 구성하면

string 에도 ? 를 붙이라는 에러가 나타난다.

이를 무시하고 싶을때 아래처럼 프로젝트 속성의 빌드>일반 탭에서 'Null 허용' 을 사용안함으로 처리하면된다.

반응형
728x90
반응형

> Serilog 적용하기

1. 콘솔 프로젝트 생성(.NET 6.0)

2. Nuget 설치
   Serilog.Sinks.Console
   Serilog.Sinks.File

3. Log 설정

using Serilog;
using Serilog.Core;

namespace SerilogTest;

class Program
{
    static void Main(string[] args)
    {
        var levelSwitch = new LoggingLevelSwitch();

        Log.Logger = new LoggerConfiguration()
                    // 최소 지정 로그 레벨 : Info 레벨 이상 로그를 기록한다는 의미
                    .MinimumLevel.Information()
                    // 콘솔에도 내용을 남김
                    .WriteTo.Console()
                    //파일로 기록할 로그 파일명을 입력
                    .WriteTo.File(@"c:\log\log.txt", rollingInterval: RollingInterval.Day, rollOnFileSizeLimit: true)
                    .CreateLogger();

        for (int idx = 0; idx < 100; idx++)
        {
            Log.Information($"{idx} - Serilog Test");
        }

        Log.CloseAndFlush();
    }
}

4. 결과


> Seq 연동하기

1. Seq 설치
https://datalust.co/download

 

Seq — centralized structured logs for .NET, Java, Node.js

Seq is the intelligent search, analysis, and alerting server built specifically for modern structured log data.

datalust.co

2.  설치 후 관리자 설정

Browse Seq 버튼을 클릭하면 웹이사이트가 열리고 아까 지정한 아이디와 비밀번호를 입력한다.

3. Seq 설정을 끝났고 프로젝트에 Nuget 설치
  Serilog.Sinks.Seq

4. Serilog 를 이용해 Seq 연동
.WriteTo.Seq("http://localhost:5341") 코드를 추가하면된다.

using Serilog;
using Serilog.Core;

namespace SerilogTest;

class Program
{
    static void Main(string[] args)
    {
        var levelSwitch = new LoggingLevelSwitch();

        Log.Logger = new LoggerConfiguration()
                    // 최소 지정 로그 레벨 : Info 레벨 이상 로그를 기록한다는 의미
                    .MinimumLevel.Information()
                    // 콘솔에도 내용을 남김
                    .WriteTo.Console()
                    //파일로 기록할 로그 파일명을 입력
                    .WriteTo.File(@"c:\log\log.txt", rollingInterval: RollingInterval.Day, rollOnFileSizeLimit: true)
                    // Seq 에 로그 정보 입력
                    .WriteTo.Seq("http://localhost:5341", controlLevelSwitch: levelSwitch)
                    .CreateLogger();

        for (int idx = 0; idx < 100; idx++)
        {
            Log.Information($"{idx} - Serilog Test");
        }

        Log.CloseAndFlush();
    }
}

프로그램을 실행하고 웹사이트를 리프레쉬하면 아래처럼 로그 내용이 보여지게된다.

 

소스

https://github.com/kei-soft/KJunBlog/tree/master/SerilogTest

 

GitHub - kei-soft/KJunBlog

Contribute to kei-soft/KJunBlog development by creating an account on GitHub.

github.com

 

반응형
728x90
반응형

LoginPage 는 FlyoutItem 에 포함시킬것이 아니기 때문에 FlyoutItem 밖에 선언해준다.

AppShell.xaml

<?xml version="1.0" encoding="UTF-8" ?>
<Shell
    x:Class="Maui.LoginPage.AppShell"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:Maui.LoginPage.Views"
    Shell.FlyoutBehavior="Disabled">

    <Shell.Resources>
        <Style x:Key="BaseStyle" TargetType="Element">
            <Setter Property="Shell.NavBarHasShadow" Value="False"/>
            <Setter Property="Shell.BackgroundColor" Value="#285083" />
            <Setter Property="Shell.ForegroundColor" Value="White" />
            <Setter Property="Shell.TitleColor" Value="White" />
            <Setter Property="Shell.DisabledColor" Value="#B4FFFFFF" />
            <Setter Property="Shell.UnselectedColor" Value="Gray" />
            <Setter Property="Shell.NavBarIsVisible" Value="True" />
            <Setter Property="Shell.TabBarIsVisible" Value="True" />

            <Setter Property="Shell.TabBarBackgroundColor" Value="#376199" />
            <Setter Property="Shell.TabBarForegroundColor" Value="White" />
            <Setter Property="Shell.TabBarTitleColor" Value="White" />
            <Setter Property="Shell.TabBarDisabledColor" Value="Black" />
            <Setter Property="Shell.TabBarUnselectedColor" Value="Gray" />
        </Style>
        
        <Style TargetType="TabBar" BasedOn="{StaticResource BaseStyle}" />
        <Style TargetType="ShellItem" BasedOn="{StaticResource BaseStyle}" />
    </Shell.Resources>

    <ShellContent
        Title="Login"        
        ContentTemplate="{DataTemplate local:LoginPage}"
        Route="LoginPage" />

    <FlyoutItem 
        Title="App" 
        Route="App" 
        FlyoutDisplayOptions="AsMultipleItems">
        
        <ShellContent
            Title="Main"
            Icon="dotnet_bot.png"
            Style="{StaticResource BaseStyle}"
            ContentTemplate="{DataTemplate local:MainPage}"
            Route="MainPage" />
        
        <ShellContent
            Title="About"
            Icon="kei.png"
            Style="{StaticResource BaseStyle}"
            ContentTemplate="{DataTemplate local:AboutPage}"
            Route="AboutPage" />

    </FlyoutItem>
</Shell>

LoginPage 화면 구성

<?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="Maui.LoginPage.Views.LoginPage" 
             BackgroundColor="#376199">
    
    <Shell.TabBarIsVisible>false</Shell.TabBarIsVisible>
    <Shell.NavBarIsVisible>false</Shell.NavBarIsVisible>
    
    <StackLayout BackgroundColor="#285083">

        <Frame BackgroundColor="Transparent" BorderColor="Transparent" Margin="40">
            <StackLayout>
                <Label LineBreakMode="WordWrap" HorizontalOptions="Center">
                    <Label.FormattedText>
                        <FormattedString>
                            <Span Text="L" TextColor="White" FontAttributes="Bold"  FontSize="50"/>
                            <Span Text="ogin" FontSize="25" TextColor="LightGray"/>
                        </FormattedString>
                    </Label.FormattedText>
                </Label>
                <Label LineBreakMode="WordWrap" HorizontalOptions="Center">
                    <Label.FormattedText>
                        <FormattedString>
                            <Span Text="Pag" FontSize="25" TextColor="LightGray"/>
                            <Span Text="E" TextColor="White" FontAttributes="Bold"  FontSize="50"/>
                        </FormattedString>
                    </Label.FormattedText>
                </Label>
            </StackLayout>
        </Frame>
        
        <Frame BorderColor="#376199" Margin="20,10" Padding="0" BackgroundColor="#376199">
            <StackLayout BackgroundColor="#376199" VerticalOptions="Center">

                <Frame Margin="15" Padding="0" BackgroundColor="#376199" CornerRadius="10" BorderColor="White" HeightRequest="45">
                    <Entry Background="#376199" Margin="10,1" Placeholder="Id" PlaceholderColor="LightGray" VerticalOptions="Center" TextColor="White"/>
                </Frame>

                <Frame Margin="15" Padding="0" BackgroundColor="#376199" CornerRadius="10" BorderColor="White" HeightRequest="45">
                    <Entry Background="#376199" Margin="10,1" Placeholder="Password" PlaceholderColor="LightGray" VerticalOptions="Center" TextColor="White" IsPassword="True" MaxLength="10"/>
                </Frame>

                <Button Text="LOGIN" TextColor="White" FontSize="15" BackgroundColor="#1295DB" HorizontalOptions="FillAndExpand" Margin="15,15" HeightRequest="40" FontAttributes="Bold"
                        Command="{Binding MenuCommand}" CommandParameter="MainPage"/>
                
            </StackLayout>
        </Frame>
        <Label Text="Create acount?" HorizontalOptions="Center" TextColor="White" FontAttributes="Bold">
            <Label.GestureRecognizers>
                <TapGestureRecognizer Command="{Binding MenuCommand}" CommandParameter="MainPage"/>
            </Label.GestureRecognizers>
        </Label>

    </StackLayout>
</ContentPage>

LoginPageModel.cs

using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Input;

namespace Maui.LoginPage.ViewModels
{
    public class LoginPageModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public ICommand MenuCommand => new Command<string>(p=>OnMenuCommand(p));

        private void OnMenuCommand(string menu)
        {
            Shell.Current.GoToAsync("//App/" + menu);
        }
    }
}

소스
https://github.com/kei-soft/KJunBlog/tree/master/Maui.LoginPage

반응형

+ Recent posts