private Button currentButton;
        
        private void ButtonClick(object sender, EventArgs e)
        {
            ActiveButton(sender);
        }
        
        private void DisableButton()
        {
            foreach (Control previousBtn in panelMenu.Controls)
            {
                if (previousBtn.GetType() != typeof(Button))
                    continue;
                // 클릭 전 버튼 상태로 복구
                previousBtn.BackColor = Color.FromArgb(51, 51, 76);
                previousBtn.ForeColor = Color.White;
                previousBtn.Font = new System.Drawing.Font("Arial", 12F, System.Drawing.FontStyle.Bold);
            }
        }

        private void ActiveButton(object btnSender)
        {
            if (btnSender == null || currentButton == (Button)btnSender)
                return;
            DisableButton();
            currentButton = (Button)btnSender;
            // 클릭 후 버튼 상태로 변화
            currentButton.Font = new System.Drawing.Font("Arial", 14F, System.Drawing.FontStyle.Bold);
        }

C#의 기본 WinForm에서 맨위에 테두리 창이 디자인 적으로 예쁘지 않기 때문에 해당 부분을 없애고 따로 창을 움직일 수 있는 이벤트를 주고자 한다.

MouseDown 이벤트 더블클릭

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace TestWinForm
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        [DllImport("user32.DLL", EntryPoint = "ReleaseCapture")]
        private extern static void ReleaseCapture();

        [DllImport("user32.DLL", EntryPoint = "SendMessage")]
        private extern static void SendMessage(System.IntPtr hWnd, int wMsg, int wParam, int IParam);

        private void Form1_MouseDown(object sender, MouseEventArgs e)
        {
            ReleaseCapture();
            SendMessage(this.Handle, 0x112, 0xf012, 0);
        }
    }
}

주의점: 창 내리기, 전체화면, 끄기 버튼은 따로 구현해야 한다.

MetroForm Ui: MIT 라이선스의 Winform의 UI를 예쁘게 바꿀 수 있는 UI 프레임워크  

해당 플러그인을 설치 후 Winform의 Form을 상속 받는 코드를 다음과 같이 수정하면 끝

원본 깃허브 링크: https://github.com/dennismagno/metroframework-modern-ui

 

GitHub - dennismagno/metroframework-modern-ui: My humble attempt to bring the new Modern UI alias Metro UI of Windows 8 to .NET

My humble attempt to bring the new Modern UI alias Metro UI of Windows 8 to .NET Windows Forms applications. - GitHub - dennismagno/metroframework-modern-ui: My humble attempt to bring the new Mode...

github.com

 

상황: 버튼을 누르면 같은 프로젝트 내의 다른 Form을 띄우고자 할 때

C#의 프로그램 파일 계층 구조

여기서 버튼을 누르면 같은 솔루션의 HomeWork3Update의 RoiForm을 화면에 나오게 하고자 한다.

참조 추가 그 후

namespace callTestForm
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            RoiForm roiForm = new RoiForm();
            roiForm.ShowDialog();
        }
    }
}

+ 만약 해당 폼을 열었을 때 다른 폼을 클릭 가능하게 하고 싶다면 ShowDialog() 대신 Show()로 하면 된다.

실행 모습

WinForm을 다루다 보면 간혹 Tap 순서가 엉망으로 되어있어서 불편한 경우가 있는데 순서를 임의로 조정하는 법과 Tap으로 받지 못 하게 하는 방법을 알게되어 정리 해두고자 한다..  

WinForm에서는 TabIndex 가 낮은 순서 부터 차례대로 Tap키 입력시 이동하게 되어있다.

만약 TabStop에 False 를 주게 된다면 해당 컴포넌트는 Tap키를 받을 수 없게 된다.

C# 윈도우 폼에서 특정 부분의 폰트를 설정하는 창을 만들어보자. 

Form만 Load 이벤트 핸들러를 달아주고 나머지 박스들은 더블 클릭을 통해 자동으로 만들어진 껍질 사용

 

운영체제에 설치된 폰트 목록을 가져와 콤보박스에 넣는 함수  

 // Form1의 load 이벤트 핸들러 
        private void addFont(object sender, EventArgs e)
        {
            // 운영체제에 설치되어 있는 폰트 목록 가져오기
            FontFamily[] fonts = FontFamily.Families;
            // foreach 문을 통해 conboBox에 하나씩 넣기
            foreach (FontFamily font in fonts)
                comboFontBox.Items.Add(font.Name);
        }

폰트 설정 변경에 공통으로 사용할 함수

 void changeFont()
        {
            FontStyle style = FontStyle.Regular; // FontStyle 일반 스타일 설정
            
            if(boldCheckBox.Checked)
                style |= FontStyle.Bold; // Bold 효과 추가
            if (italicCheckBox.Checked)
                style |= FontStyle.Italic; // Italic 효과 추가
            if (underlineCheckBox.Checked)
                style |= FontStyle.Underline; // Underline 효과 추가

            // 설정한 폰트로 바꾸기 Font("폰트 이름", int(사이즈), FontStyle); 
            textBox.Font = new Font((string)comboFontBox.SelectedItem, 12, style);
        }

 

전체코드:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace FontBox
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        // Form1의 load 이벤트 핸들러 
        private void addFont(object sender, EventArgs e)
        {
            // 운영체제에 설치되어 있는 폰트 목록 가져오기
            FontFamily[] fonts = FontFamily.Families;
            // foreach 문을 통해 conboBox에 하나씩 넣기
            foreach (FontFamily font in fonts)
                comboFontBox.Items.Add(font.Name);
        }
        // 폰트 변화에 공통적으로 사용할 함수
        void changeFont()
        {
            FontStyle style = FontStyle.Regular; // FontStyle 일반 스타일 설정
            
            if(boldCheckBox.Checked)
                style |= FontStyle.Bold; // Bold 효과 추가
            if (italicCheckBox.Checked)
                style |= FontStyle.Italic; // Italic 효과 추가
            if (underlineCheckBox.Checked)
                style |= FontStyle.Underline; // Underline 효과 추가

            // 설정한 폰트로 바꾸기 Font("폰트 이름", int(사이즈), FontStyle); 
            textBox.Font = new Font((string)comboFontBox.SelectedItem, 12, style);
        }

        // Bold 체크 박스 클릭 이벤트 핸들러
        private void boldCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            changeFont();
        }
        // Italic 체크 박스 클릭 이벤트 핸들러
        private void italicCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            changeFont();
        }
        // 콤보박스 클릭 이벤트 핸들러
        private void comboFontBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            changeFont();
        }
        // 밑줄 체크 박스 클릭 이벤트 핸들러
        private void underlineCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            changeFont();
        }
    }
}

 

 

C#의 WinForm의 경우는 Java의 JFrame과는 다르게

폼 디자이너 툴을 제공하여 프로그래머가 일일이 컴포넌트를 구현할 필요 없이 그림 그리듯 GUI를 만드는 것이 가능하며

이를 WYSIWYG(What You See Is What You Get)방식의 개발이라고 합니다.

 

java: 간단한 로그인 화면 만들기

import javax.swing.*;
import java.awt.*;

public class SimpleLoginForm extends JFrame {
   public SimpleLoginForm(){
           JPanel p = new JPanel();
           Label lid = new Label("id");
           Label lpwd= new Label("pass");
           add(lid);
           add(lpwd);
           TextField tid = new TextField();
           TextField tpwd = new TextField();
           add(tid);
           add(tpwd);
           JButton jsave = new JButton("저장");
           add(jsave);
           lid.setBounds(80, 120, 40, 40);
           lpwd.setBounds(80,190,60,40);
           
           tid.setBounds(160, 120, 200, 40);
           tpwd.setBounds(160, 190, 200, 40);        
           jsave.setBounds(165, 480, 80, 30);
      add(p);
      setSize(600,600);
      setTitle("회원가입");
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      setVisible(true);
   }    
   public static void main(String args[]) {
	   new SimpleLoginForm();
   }
}

JFrame을 상속 받고 일일이 컴포넌트들을 코딩하여 붙이고 위치 혹은 간격 설정을 프로그래머가 해주어야 한다.

정말 손이 많이 가고 번거롭다.

 

C#: 간단한 로그인 화면 만들기

이제 옆의 도구 상자에서 원하는 컴포넌트를 드래그 앤 드롭 하여 붙여넣고

적당히 클릭하여 내용을 바꿔주고 실행시키면

다음과 같이 자바와는 다르게 정말 간단하게 화면을 만들 수가 있다.

이것이 C#이다 교재를 바탕으로 윈도우 폼을 공부하던 중 초기에 콘솔 앱으로 프로젝트를 만들어 WinForm을 실행 하는 예제가 상속도 인식이 되지 않고 실행도 매끄럽게 되지 않아서 여러모로 조사하여 해결법을 찾게 공유하고자 한다. 

 

<Project Sdk="Microsoft.NET.Sdk">

	<PropertyGroup>
		<OutputType>Exe</OutputType>
		<TargetFramework>net6.0-windows</TargetFramework>
		<ImplicitUsings>enable</ImplicitUsings>

		<UseWindowsForms>true</UseWindowsForms>
		<ImportWindowsDesktopTargets>true</ImportWindowsDesktopTargets>

		<Nullable>enable</Nullable>
	</PropertyGroup>

</Project>

 

해당 내용을 다음과 같이 ]net.6.0 에 -windows 옵션 추가 및  useWindowsForms 옵션 true

ImportWindowsDesktopTargets 옵션 true를 주면

 

예시 코드:

using System;
using System.Windows.Forms;

namespace UsingApplication
{
    class MainApp : Form
    {
        static void Main(string[] args)
        {
            MainApp form = new MainApp();

            form.Click += new EventHandler((sender, eventArgs) =>
            {
                Console.WriteLine("Console Window...");
                Application.Exit();
            });

            Console.WriteLine("Starting Window Application ...");
            Application.Run(form);
            Console.WriteLine("Exiting Window Application ...");
        }
    }
}

 

다음과 같이 잘 작동되는 것을 알 수가 있다.

+ Recent posts