wlstmddn74의 등록된 링크

키자드에 등록된 총 417개의 포스트를 확인하실 수 있습니다.

Naver Blog

[C#] Dictionary<T> 제네릭 클래스

Dictionary 클래스는 키/값 쌍을 갖는 컨테이너 생성을 위한 템플릿이다. Dictionary를 구성하려면, 해당 키의 형식과 값의 형식을 생성자에 전달한다. 예를 들면, 키로 string을 취하고 값으로 int를 취하는 Dictionary를 생성하면 아래와 같다. Dictionary<string, int> dic = new Dictionary<string, int>(); 다른 컬렉션 형식처럼, 키/값 쌍을 Dictionary에 추가하는 Add 메소드와 모든 요소를 제거하는 Clear 메소드를 갖고 있다. 값을 가져오려면, Item 속성을 사용한다. 예를 들어, Dictionary에서 수도/국가 쌍을 포함한다면, 값을 가져오기 위해 다음 구문을 사용한다. Dictionary<string, string> countryDictionary = new Dictionary<string, string>(); countryDictionary.Add("서울", "대한민국"); countryD

Naver Blog

[C#] Queue<T> 제네릭 클래스

Queue는 FIFO(First-In-First-Out)으로 먼저 들어간 요소가 먼저 나온다. 쉽게 예를 들면, 맛집에 가서 웨이팅을 할 때 가장 먼저온 사람부터 들어가는 경우, 마트나 편의점에 먼저 들어온 제품이 앞에 나열되어 있는것과 같다. 유용한 메소드 public void Enqueue(T item) Enqueue 메소드는 Queue의 끝(Rear)에 item을 추가한다. 추가하는 item은 null도 가능하다. public T Dequeue() Dequeue 메소드는 Queue의 시작(Front)에 위치한 item을 반환하고, 그 item을 Queue에서 제거한다. public T Peek() Peek 메소드는 Queue의 시작(Front)에 위치한 item을 제거하지 않고 반환한다. public bool Contains(T item) Contains 메소드는 item이 Queue에 있는지 여부를 확인하여 반환한다. public void Clear() Clear 메

Naver Blog

[C#] HashSet<T> 제네릭 클래스

집합은 특정 순서가 없는 값을 저장하면서 중복을 허용하지 않는 데이터 구조다. 해시 집합은 해시 테이블을 사용해 구현한 집합이다. 해시는 요소의 인덱스를 계산하는 데 사용하는 함수를 말하며 해당 요소를 빠르게 가져올 수 있다. .NET 프레임워크에서 HashSet 클래스는 해시 집합을 나타낸다. HashSet은 List와 비슷하며 List의 Add와 Clear 메소드와 같은 동작을 수행하고 요소의 수를 반환하는 Count 속성이 있다. 하지만 List와 달리 HashSet은 중복을 허용하지 않기 때문에 특정 인덱스에서 항목을 추가하거나 제거하지 못하고, 지정한 위치에서 요소를 가져오게 해주는 Item도 없다. 한편 HashSet은 IsSubsetOf와 IsSuperSetOf 처럼 집합을 다루는 데 유용한 메소드를 제공한다. 유용한 메소드 public bool Add(T item) Add 메소드는 HashSet에 item을 추가한다. 추가된 항목이 이미 HashSet에 있다면, 다시

Naver Blog

[C#] List<T> 제네릭 클래스

List 클래스 우리는 동일한 형식의 객체들을 그룹으로 작업하는 경우가 있다. 배열의 경우 크기를 정해놓으면 변경하지 못하므로 유연성이 부족하다. 이를위해 .NET 프레임워크는 List 제네릭 클래스를 제공한다. List는 배열과 비슷하지만 요소를 추가할 때, 새로운 요소가 들어갈 공간이 없다면 크기가 자동으로 증가한다. List는 제네릭 클래스로 저장하려는 객체의 종류를 컴파일러에 알려줘야 한다. 다음은 문자열의 List를 생성하는 방법이다. List<string> animals = new List<string>(); List<string> names = new List<string>(10); // 초기 크기를 10으로 지정 만약, List에 저장하는 요소의 수가 얼마나 되는지 미리 안다면, 크기 조정에 시간이 소모되는 것을 방지하기 위해 최대 요소 수에 대한 초기 크기를 지정하는 것이 좋다. List에서 요소를 가져오려면 배열에서처럼 List 변수에 인덱스를 전달해 호출한다. n

Naver Blog

[C#] 제네릭(Generic)

제네릭은 매개변수를 받는 형식을 작성하고 하나의 형식이나 여러 형식을 넘겨 인스턴스를 생성할 수 있다. 이때의 제약사항은 객체가 해당 형식이어야 한다는 점이다. 또한 매개변수를 받는 메소드도 지원한다. 제네릭 형식 선언은 제네릭 형식용 형식 변수 목록을 감싸는 꺾쇠(<>) 괄호를 사용하여 표현한다. 예들 들면, System.Collections.Generic.List를 선언하려면 다음과 같이 작성한다. List<T> myList T는 형식 변수, 즉 어떤 형식을 대체하는 변수다. 제네릭 형식에서 형식 변수를 대체하는 값을 인수 형식이나 메소드의 반환 형식으로 사용한다. List 클래스의 경우 인스턴스가 생성될 때, 형식 변수인 T는 Add나 다른 메소드의 인수 형식으로 사용된다. public void Add<T item> // 인수 형식으로 사용된다. public T Find(Predicate<T> match) // 반환 및 인수 형식으로 사용된다. 만약, string을 형식 변수로

Naver Blog

[C#] enum

열거형은 열거한 값을 유지하는 데 사용하는 .NET 프레임워크의 데이터 형식이다. 변수에 할당하는 값이나 메소드에서 반환되는 값을 제한할 때 주로 열거형을 사용한다. 키워드 enum을 사용해 필드나 메소드에 쓰는 유효한 일련의 값을 생성한다. 예를 들면, EmployeeType에 맞는 가능한 값은 FullTime, PartTime, Permanent, Contractor라고 보는 것이다. enum 형식을 독립적으로 쓰거나 클래스의 일부로 쓸 수 있다. 애플리케이션의 여러 곳에서 사용해야 하는 경우라면 독립적으로 만드는 것이 좋다. 한 클래스 내에서만 사용하는 경우라면, 클래스의 일부로 만드는 편이 더 좋다. 다음 예제는 열거형을 클래스의 멤버로 독립적으로 사용하는 경우이다. class Employee { public enum EmployeeType { FullTime, PartTime, Permanent, Contractor } private EmployeeType employeeT

Naver Blog

[C#] 추상클래스

인터페이스에서는 실제 동작을 수행하는 구현 클래스를 작성해야 했다. 인터페이스에 메소드가 많다면, 사용하지 않는 메소드를 재정의하는 데 시간을 낭비할 수 있다. 추상클래스는 인터페이스의 역할과 비슷해서 서비스 공급자와 클라이언트 간의 계약을 제공하지만, 부분 구현을 제공할 수 있다. 명시적으로 재정의해야 하는 메소드는 abstract로 선언한다. 추상 클래스의 인스턴스를 생성할 수 없기 때문에 여전히 구현 클래스를 생성해야 하지만, 사용하거나 변경하고 싶지 않은 메소드는 재정의할 필요가 없다. 클래스 선언에서 abstract 한정자를 사용해 추상 클래스를 생성한다. 추상 메소드를 생성하려면, 메소드 선언 앞에 abstract 한정자를 사용한다. 다음은 DefaultPrinter 추상 클래스이다. public abstract class DefaultPrinter { public string GetDescription() { return "Use this to print document

Naver Blog

[C#] IComparable

System.Array 클래스에서 배열의 요소를 정렬할 수 있는 정적 메소드 Sort를 제공하고 있다. 그러나 정렬하는 객체에 대해 아무것도 모르면서 Sort 메소드에서 객체를 정렬하는 방법을 어떻게 알까?? 배열에서 정렬할 수 있는 객체를 원한다면, 해당 객체 클래스에서 IComparable 인터페이스를 구현하도록 함으로써 이들 객체를 IComparable로 형변환할 수 있도록 해야 한다. IComparable에는 CompareTo라는 하나의 메소드만 있으며, 재정의를 통해 객체를 정렬하는 방법을 결정할 수 있다. 다음의 예제는 Student 클래스가 IComparable 인터페이스를 구현하여 lastName 순으로 정렬하고, 같은 경우 firstName 순으로 정렬한다. class Student : IComparable { private string firstName; private string lastName; public Student(string firstName, stri

Naver Blog

[C#] 인터페이스(interface)

인터페이스를 interface 키워드로 선언하고 메소드 본문에 아무것도 없는 클래스와 같은 것이라고만 본다면 큰 그림을 놓치는 것이다. 인터페이스에 대한 더 알맞은 정의는 서비스 공급자(서버)와 그 서비스 사용자(클라이언트) 간의 계약이다. 현실의 예제를 생각해보자. 마이크로소프트의 윈도우는 오늘날 가장 인기 있는 운영체제이지만, 마이크로소프트에서 프린터를 만들지는 않는다. 인쇄를 위해 여전히 HP나 삼성, 캐논과 같은 회사에 의존한다. 이들 프린터 제조사 각각은 자시체 기술을 사용하지만 윈도우 애플리케이션에서 문서를 인쇄하는데 사용될 수 있다. 그 이유는 윈도우에서 프린터하길 원한다면 IPrintable 인터페이스를 구현해야 한다고 정해놨기 때문에 프린터 제조사에서는 이 인터페이스를 각 회사의 기술로 구현하기만 하면 된다. 인터페이스의 기술적 관점 C#에서 인터페이스도 클래스처럼 하나의 형식이다. interface 인터페이스이름 { } · 인터페이스는 메소드의 시그니처와 속성, 이

Naver Blog

[C#] 날짜(DateTime)와 시간(TimeSpan)

.NET 프레임워크 클래스 라이브러리에는 날짜와 시간을 다루는 데 사용할 수 있는 System.DateTime 구조체와 System.TimeSpan 구조체가 있다. 이 두가지는 구문 분석과 서식 적용을 위한 메소드를 제공하며 다룰 수 있는 데이터의 범위만 다르다. System.DateTime DateTime은 시간의 어떤 시점을 나타내는데, '2022년 8월 18일 오후 7시 56분'과 같은 식이다. 아래의 예제는 DateTime을 사용해 날짜를 구문분석하고 서식을 적용하는 방법을 나타냈다. Console.Write("MM/dd/yyyy 형식으로 날짜를 입력하세요 : "); DateTime selectedDate; string dateString = Console.ReadLine(); string format = "MM/dd/yyyy"; CultureInfo provider = CultureInfo.InvariantCulture; try { selectedDate = DateTime

Naver Blog

[C#] 숫자 구문 분석(Parse)

숫자 구문 분석 우리는 프로그래밍을 하다보면 입력받은 문자열을 숫자로 변환해야한다. 변환을 하기전에 해당 문자열을 읽고 숫자를 만들 수 있는 문자만 포함하는지 확인해야 한다. 예를 들어 "123abc"는 숫자로 시작하기는 했지만 숫자가 아니다. 이와 같이 문자열을 숫자로 변환하는 것을 숫자 구문 분석(Parsing)이라 한다. 숫자 형식을 나타내는 모든 구조체의 Parse 메소드를 사용해 문자열을 구문 분석할 수 있다. Parse의 반환 형식은 Parse 메소드를 포함하는 구조체와 동일하다. 이를테면 System.Int32의 Parse 메소드는 Int32를 반환한다. 만약, 구문 분석이 실패하면 System.FormatException 예외가 발생한다. Console.Write("숫자를 입력하세요 : "); String input = Console.ReadLine(); try { int i = Int32.Parse(input); Console.WriteLine("입력한 숫자 : "

Naver Blog

[C#] 에러처리(try-catch-finally)

에러 처리는 모든 프로그래밍 언어에서 중요한 기능이다. 좋은 에러 처리 메커니즘은 프로그래머가 견고한 애플리케이션을 작성하고 예상치 않은 기능을 추가하는 과정에서 버그를 예방하도록 해준다. 예외잡기 try문을 사용해 런타임 에러를 일으킬 수 있는 코드를 격리하는데, 일반적으로 catch와 finally문이 포함된다. 에러를 만나면 try 블록의 처리를 중단하고 catch 블록으로 건너뛴다. catch 블록에서 에러를 처리하거나 System.Exception 객체를 발생시켜 사용자에게 알려준다. try { [예외를 발생시킬 수 있는 코드] } [catch (ExceptionType1 [e]) { [ExceptionType1이 발생할 때 실행되는 코드] }] ... [catch (ExceptionTypeN [e]) { [ExceptionTypeN이 발생할 때 실행되는 코드] }] [finally { [예외 발생 여부에 상관없이 실행되는 코드] } 에러 처리를 위한 단계를 요약하면 다음과

Naver Blog

[C#] 구조체

구조체는 클래스와 같이 필드, 메소드를 가질 수 있다. 하지만, 클래스와 달리 구조체는 값 형식이며 상속하거나 상속될 수 없다. 또한 2개의 변수에서 동일한 구조체 인스턴스를 가리킬 수 없다. 구조체를 새로운 변수에 할당하면 해당 구조체의 새로운 인스턴스를 생성한다. .NET 프레임워크는 Byte, Char, Int32, DateTime과 같은 중요한 구조체를 정의하여 제공해준다. 구조체는 new를 사용해 인스턴스를 생성한다. 값 형식이므로 스택이나 인라인에서 할당되고 범위를 벗어나면 할당이 해제된다. 값 형식은 일반적으로 생성 비용이 더 싸지만, 박싱과 언박싱이 많이 수반되면 참조 형식보다 더 나쁜 성능을 보인다. 모든 구조체는 System.ValueType에서 암시적으로 파생된다. 다음은 Point라는 사용자 지정 구조체의 코드를 나타낸다. 이 구조체는 2개의 필드(X, Y)와 Move, Print라는 2개의 메소드를 가지고 있다. public struct Point { publ

Naver Blog

[C#] 메소드 재정의(Method Overriding)

클래스를 상속하여 확장할 때, 부모 클래스의 메소드 동작을 변경할 수 있다. 메소드 재정의라고 부르는 이 변경은 부모 클래스의 메소드와 동일한 시그니처를 갖는 메소드를 자식 클래스에서 작성할 때 일어난다. 만약, 메소드 이름은 동일하지만 인수의 목록이 동일하지 않다면 메소드 오버로딩이다. 부모 클래스의 public과 protected 메소드를 재정의할 수 있다. 만약, 해당 자식클래스와 부모클래스가 동일한 어셈블리에 있다면, internal 액세스 수준을 사용해 메소드를 재정의할 수 있다. 아래는 메소드 재정의 예제이다. public class Shape { public void WhatAmI() { Console.WriteLine("난 모양"); } } public class Oval : Shape { new public void WhatAmI() { Console.WriteLine("난 타원"); } } Oval 클래스는 Shape를 확장하고 WhatAmI 메소드를 재정의한다.

Naver Blog

[C#] 상속

상속은 가장 중요한 객체 지향 프로그래밍(OOP)의 특징이다. 이 특징은 모든 OOP 언어에서 코드를 확장성있게 만든다. C#에서 기본적으로 모든 클래스는 확장할 수 있지만, sealed 키워드를 사용해 클래스의 상속을 방지할 수 있다. 상속을 했을 시 클래스 명칭 기존 클래스 : 부모 클래스, 베이스 클래스, 수퍼 클래스 상속을 받은 새로운 클래스 : 자식 클래스, 서브 클래스, 파생 클래스 자식클래스에서 새로운 메소드와 새로운 필드, 새로운 속성을 추가할 수 있을 뿐만 아니라 기존 메소드를 재정의해서 동작을 변경할 수 있다. 클래스 확장 클래스 선언에서 해당 클래스 이름과 부모 클래스 이름 사이에 콜론(:)을 사용해 클래스를 확장한다. 다음 예제는 Child 클래스가 Parent 클래스를 상속받아 확장한 것이다. public class Parent { } // Parent 클래스 상속 public class Child : Parent { } C#에서 클래스는 하나의 다른 클래스

Naver Blog

[C#] 배열

C#에서 동일한 형식의 기본형이나 객체를 묶는 데 배열을 사용한다. 배열은 System.Array에서 파생된 클래스의 인스턴스로 크기를 변경할 수 없다. 배열은 객체이므로 참조하는 변수를 다른 참조 변수처럼 다룬다. 한가지 예를 들면, 배열을 null과 비교할 수 있다. string[] names; if(names == null) // true로 평가 배열 선언은 다음 구문을 사용한다. type[] arrayName; // ex) long[] numbers; 위와 같은 배열 선언은 배열을 생성하거나 배열의 구성 요소를 위한 공간을 할당하지 않고, 컴파일러는 단순히 배열 참조만을 생성한다. 배열을 만드는 한 가지 방식은 new 키워드를 사용하는 것이다. 다음처럼 생성할 배열의 크기를 지정해야 한다. long[] numbers = new long[3]; 배열의 구성 요소를 참조하려면, 변수 이름 다음에 인덱스를 사용한다. 배열은 0에서 시작하는데, 이는 배열의 첫 번째 요소의 인덱스가

Naver Blog

[C#] StringBuilder 클래스

String 객체는 변경이 불가능하며 이 객체에 문자를 덧붙이거나 삽입해야 한다면 좋은 선택이 아니다. StringBuilder는 포함할 수 있는 문자의 수를 지정해 인스턴스 생성을 시작한다. 문자나 문자열을 덧붙일 때, 시스템은 더하는 연산에서 아직 충분한 공간이 있는 한 새로운 인스턴스를 생성하지 않는다. 만약, 초기에 설정한 공간을 초과하면 자동으로 공간을 늘리지만 비용이 든다. 따라서 초기에 StringBuilder생성할 때, 충분한 공간을 제공해 만들어야 한다. 문자열 처리를 끝내고 나면, ToString 메소드를 통해 StringBuilder를 문자열로 변환할 수 있다. StringBuilder 클래스의 생성자 StringBuilder 클래스는 6개의 생성자를 가지고 있다. public StringBuilder() : 인수 없는 생성자로 16개의 문자 크기를 갖는 StrigBuilder를 생성한다. public StringBuilder(int capacity) : 초기 크

Naver Blog

[C#] String 클래스

System.String 클래스를 사용하지 않는 C# 프로그램이 없을 정도로 자주 사용되면서 중요한 클래스 중 하나다. String 객체는 텍스트의 일부인 문자열을 나타낸다. 문자를 갖지 않는 String을 빈 문자열이라고 한다. 중요한 점은 String 객체는 상수여서 생성하고 나면 값을 변경하지 못한다. 이 때문에 String 인스턴스를 불변이라고 한다. new 키워드와 String 클래스의 생성자 중 하나를 사용해 String 객체를 생성할 수 있지만, 일반적이진 않다. 대부분은 간단히 문자열 리터럴을 String 변수에 할당한다. String s = ".NET is cool"; String을 생성하는 또 다른 방법은 string 형식을 사용하는 것으로 String 클래스에 대한 별칭이다. 별칭을 사용하여 다음처럼 쓸 수 있다.(일반적으로 이렇게 사용하고 컴파일러도 단순화하도록 유도함) 왜 굳이 String이 있는데 string 별칭을 사용하는가 의문을 가질 수 있다. 나의 생

Naver Blog

[C#] 메소드 오버로딩

C#의 메소드 오버로딩을 통해 다른 인수 형식의 집합을 갖는 동일한 이름의 메소드를 가질 수 있다. 다음 예제를 보면 하나의 클래스에서 동일한 이름을 가진 2개의 메소드가 존재할 수 있다. public void PrintString(String string); public void PrintString(String string, int offset); 메소드 오버로딩에서 주의할 점은 메소드의 반환 값은 고려 대상이 아니다. 이는 메소드가 반환 값을 변수에 할당하지 않고 호출될 수 있기 때문이다. public int CountRows(int number); public string CountRows(int number); 인수 형식이 같기때문에 메소드의 반환 값이 다르더라도 컴파일 에러가 발생한다. 다음은 메소드 시그니처가 매우 유사하여 까다로운 상황의 예제이다. public int PrintNumber(int i) { return i * 2; } public long PrintNum

Naver Blog

[C#] static(정적 클래스, 정적 메소드, 정적 변수)

지금까지 객체를 생성하여 public 필드나 메소드에 접근하였다. Book book = new Book(); // Book의 인스턴스 생성 book.Name = "처음 배우는 C# : 초보자를 위한 입문 가이드"; // book.Review(); // Review 메소드 접근 하지만 우리는 콘솔창에 값을 출력할때 따로 객체를 생성하지 않고 메소드를 호출하였다. Console.WriteLine("객체 생성안했음!!!"); C#은 클래스의 인스턴스를 먼저 만들지 않고도 호출할 수 있는 클래스 멤버인 정적 멤버의 개념을 지원한다. Console 클래스의 WriteLine 메소드는 정적이므로 Console 인스턴스를 먼저 생성하지 않고 사용할 수 있다. 정적 멤버를 생성하려면, 필드나 메소드의 선언 앞에 static 키워드를 사용한다. 접근 한정자가 있다면, static 키워드는 접근 한정자 앞이나 뒤에 올 수 있다. public static int NumberOfPage; // 주로 사용

Naver Blog

[C#] this 키워드

this 키워드는 생성자나 메소드에서 현재 객체를 참조하는데 사용된다. 예를 들어 지역 변수와 동일한 이름의 클래스 수준 필드를 갖고 있다면, this를 사용해 클래스 수준 필드를 참조할 수 있다. public class Box { int Length; int Width; int Height; public Box(int Length, int Width, int Height) { this.Length = Length; this.Width = Width; this.Height = Height; //Length = Length; // 인수 Length에 인수 Length 값을 대입하는 꼴 } } Box 클래스에는 Legth, Width, Height 세 가지 필드가 있다. 이 클래스의 생성자는 해당 필드를 초기화하는데 사용되는 세 가지 인수를 받는다. 그런데 인수와 필드가 동일한 이름이므로 this 키워드를 이용해 필드를 참조하는 것을 나타내준다. 만약 this 키워드 없이 작성 시 인수

Naver Blog

[C#] 접근 제어 한정자

OOP 원리인 캡슐화는 보호해야 하는 객체 부분을 보호하고 노출에 안전한 부분만 노출하는 메커니즘이다. C#은 접근 제어를 통해 캡슐화를 지원한다. 접근 제어는 접근 제어 한정자의 통제를 받는데, public, protected, internal, private라는 4개의 한정자가 있다. 접근 제어 한정자는 클래스나 클래스 멤버에 적용될 수 있다. 클래스는 public이나 internal 중 하나가 될 수 있다. 명시적으로 public 선언하지 않는 한 internal 접근성을 가진다. public 클래스는 모든 네임스페이스의 다른 형식에서 접근 할 수 있다. 대조적으로 internal 클래스는 현재 어셈블리로 제한된다. 여기서 어셈블리란 .NET 기반 애플리케이션에 대한 배포, 버전 제어, 재사용 등 프로그램의 기본 단위이다. 예로는 실행파일(.exe), 동적 연결 라이브러리(dll)이 있다. // 어셈블리 : MyProject namespace MySpace { internal

Naver Blog

[C#] 네임스페이스

해당 형식에 대한 고유한 이름을 생성하고 이름 충돌을 피하기 위해 네임스페이스로 클래스와 다른 형식을 구성할 수 있다. 네임스페이스는 여러 클래스와 다른 형식, 심지어 또 다른 네임스페이스도 포함할 수 있다. 다음은 네임스페이스 내에서 선언한 클래스다. namespace MyNamespace { class MyClass { } } 만약, 클래스를 네임스페이스에서 선언하지 않는 경우, C# 컴파일러는 전역 네임스페이스라는 기본 네임스페이스를 추가한다. 전역 네임스페이스에 Test 클래스, MyNamespace에 Test 클래스가 있을 수 있다. 왜냐하면 같은 클래스 이름이더라도 네임스페이스가 다르기 때문이다. 또한 네임스페이스는 여러 선언(다른 cs파일)에서 정의할 수 있다. Class1.cs 파일 namespace MyNamespace { class Class1 { } } Class2.cs 파일 namespace MyNamespace { class Class2 { } } .NET 프

Naver Blog

[C#] 메모리상의 객체

프로그램을 실행할 때, 일부 메모리 공간은 데이터용으로 할당된다. 이 데이터 공간은 놀리적으로 힙과 스택이라는 두 부분으로 나뉜다. 값 형식은 스택에 할당되고 객체는 힙에 존재하게 된다. 값 형식에 따라 스택에 몇 바이트가 설정되는지 결정된다. 예를 들어 int는 4바이트, long은 8바이트이다. 참조 변수를 선언할 때 몇 바이트를 스택에 확보하지만, 이 메모리에는 객체의 데이터가 존재하지 않고 힙에 존재하는 객체의 주소를 담고 있다. Book book; Book 클래스 참조 변수인 book은 스택에 할당되고, book의 초기 값은 아직 객체를 할당하지 않았기 때문에 null이다. Book book = new Book(); 위의 경우는 Book의 인스턴스를 생성하면서 힙에 저장하고 참조 변수 book에 인스턴스의 주소를 할당한다. 객체는 하나 이상의 참조 변수에서 참조할 수 있다. 예를 들면 다음과 같다. Book myBook = new Book(); Book yourBook =

Naver Blog

[C#] 클래스

클래스 일상생활에서 객체는 특성과 동작이라는 두 가지 기능을 갖는다. 예로 사람의 경우 특성으로 나이, 몸무게, 성별이 있고, 동작으로 먹기, 걷기가 있을것이다. C#에서 특성을 필드라고 하며, 동작은 메소드라고 한다. 필드와 메소드 모두는 선택적으로 가져도 되고, 안가져도 된다. C#에서 클래스는 동일한 종류의 객체를 생성하기 위한 템플릿이다. 예로 Human 클래스가 있다면, Human 객체를 원하는 데로 생성할 수 있다. 일반적인 클래스 구조 public class Human { public int Age; public double Weight; public string Gender; public string Walk(int speed) { return "현재 속도 : " + speed + "km/h로 걷고 있습니다."; } public void Info() { Console.WriteLine(" } } 필드는 Age, Weight, Gender와 같이 변수로써, 값 형식이나

Naver Blog

[C#] 승격

일부 단항 연산자(+, -, ~ 등)와 이항 연산자(+, -, *, /)는 자동 승격을 일으킨다. 예를 들면, byte를 int라는 더 넓은 형식으로 상승시키는 것이다. sbyte x = 5; sbyte y = -x; // 에러 두 번째 줄은 sbyte가 -5를 받을 수 있지만 단항 연산자 "-"는 -x의 결과를 int로 승격시키기 때문에 에러를 일으킨다. 이 문제를 바로잡으려면, y를 int로 바꾸거나 다음처럼 명시적인 축소 변환을 수행해야 한다. sbyte x = 5; int y = -x; sbyte y2 = (sbyte)-x; 단항 연산자의 경우, 피연산자의 형식이 byte, sbyte, short, char이면 결과가 int로 승격된다. 이항 연산자의 경우, 승격 규칙은 다음과 같다. · 피연산자가 byte, sbyte, short, char 형식이라면, 그때 양쪽 피연산자는 int로 변환되고 결과는 int가 된다. · 피연산자가 long 형식이라면, 그때 다른 피연산자는 l

Naver Blog

[C#] 연산자 우선순위

많은 프로그램에서, 종종 다수의 연산자가 하나의 식에 나타난다. 다음의 표는 연산자의 우선순위를 나타냈다. 동일한 칼럼의 연산자들은 우선순위가 동등하다. 연산자 종류 괄호 () 후위 연산자 [ ] . (params) expr++ expr-- 단항 연산자 ++expr --expr +expr -expr ~ ! 생성 또는 캐스트 new (type)expr 곱셈 * / % 덧셈 / 뺄셈 + - 시프트 << >> 비교 < > <= >= 등가 == != 비트 AND & 배타적 비트 OR ^ 포괄적 비트 OR | 논리적 AND && 논리적 OR || 조건 ? : 할당 = += -= *= /= %= &= ^= |= <<= >>= 출처 처음 배우는 C# : 초보자를 위한 입문 가이드 제이든 카이(지은이), 김도균(옮긴이) | 에이콘출판

Naver Blog

[C#] 연산자

컴퓨터 프로그램은 일정한 기능을 얻게 해주는 연산의 모음이다. C#은 다양한 연산자를 제공한다. 연산자는 하나 또는 둘 이상의 피연산자에 대해 연산을 수행한다. 피연산자는 연산의 대상이며 연산은 동작을 나타내는 기호이다. 연산자는 결과를 반환할 수도 있고 아닐 수도 있다. 단항 연산자 하나의 피연산자에서 연산을 수행한다. · 단항 빼기 연산자 - 피연산자의 부정을 반환한다. 피연산자는 숫자 기본 형식이나 숫자 기본 형식의 변수여야 한다. float x = 4.5f; float y = -x; // -4.5f · 단항 더하기 연산자 + 피연산자 값을 반환한다. 피연산자는 숫자 기본형 또는 숫자 기본형의 변수여야 한다. float x = 4.5f; float y = +x; // 4.5f · 증가 연산자 ++, 감소 연산자 -- 피연산자의 값을 1 증가(++), 1감소(--)시킨다. 피연산자는 숫자 기본형의 변수여야 한다. 연산자는 피연산자 전후에 나올 수 있다. 연산자가 피연산자의 앞에

Naver Blog

[C#] 기본 형식 변환

다른 데이터 형식을 다룰 때, 종종 변환을 수행해야 한다. 동질 변환 양쪽 변수가 동일한 형식이라면, 할당은 항상 성공한다. 이러한 변환을 동질 변환이라 한다. int a = 90; int b = a; // 동질 변환 확대 변환 int(32비트)에서 long(64비트)으로의 변환처럼 한 형식에서 다른 형식으로 변환이 일어날 때, 변환하려는 형식의 크기가 같거나 더 큰 경우에 일어난다. 확대 변환이 일어나는 경우 · byte에서 short, int, long, float, double로 변환할 때 · short에서 int, long, float, double로 변환할 때 · char에서 int, long, float, double로 변환할 때 · int에서 long, float, double로 변환할 때 · long에서 float, double로 변환할 때 · float에서 double로 변환할 때 정수 형식에서 또 다른 정수 형식으로의 확대 변환은 정보 손실의 위험이 없다. floa

Naver Blog

[C#] 리터럴

때때로 int에 숫자 2나 char에 문자 'c'처럼, 프로그램에서 값을 변수에 할당해야 한다. 이 경우 C# 컴파일러에서 인식하는 형식의 값 표현을 작성해야 한다. 이러한 값의 소스 코드 표현을 리터럴이라 한다. 리터럴의 종류 · 기본 형식의 리터럴 · 널 리터럴 · 문자열 리터럴 기본 형식의 리터럴 · 정수 리터럴 정수 리터럴은 10진수나 16진수, 8진수로 작성된다. 10진수의 정수 리터럴은 2, 123과 같이 작성한다. 16진수의 정수 리터럴은 접두어로 0x 또는 0X를 사용하여 0x9E, 0X9E와 같이 작성한다. 8진수의 정수 리터럴은 접두어로 0을 사용하여 0567과 같이 작성한다. 정수 리터럴은 byte와 short, int, long 형식의 변수에 값을 할당하는 데 사용된다. 하지만 변수 크기를 초과하는 값을 할당하면 컴파일 에러를 일으킨다. byte b = 500; // byte의 범위는 0 ~ 255인데 500은 범위를 초과했기 때문에 컴파일 에러가 발생 · 부동

Naver Blog

[C#] 상수

C#에서 const라는 키워드를 변수 선언에 접두어로 붙여 변수의 값이 변하지 못하게 만든다. 예를 들어, 1년이 12개월이라는 사실은 변하지 않으므로 다음과 같이 쓸 수 있다. const int NumberOfMonths = 12; NumberOfMonths = 13; // 컴파일 에러 한 번 값을 할당하고 나면, 해당 값은 변경하지 못한다. 할당된 값을 변경하려고 시도하면 컴파일 에러를 표시한다. 또 다른 예로, 수학 계산을 수행하는 클래스에서 변수 pi의 값을 22 / 7 (원의 지름으로 원의 둘레를 나눈 것으로, 수학에서 그리스 문자 π로 나타낸다)과 같다고 선언할 수 있다. const float pi = (float) 22 / 7; (float) 뒤에 22 / 7을 두어 형변환한 것은 나눈 값을 float으로 변환하는 데 필요하다. 이렇게 하지 않으면, int가 반환되고 pi 상수에는 3.142857이 아니라 3이라는 값이 들어간다. 출처 처음 배우는 C# : 초보자를 위한

Naver Blog

[C#] 변수

C#은 강력한 형식 언어이므로, 모든 변수는 선언된 형식 및 이름(식별자)를 가져야 한다. 데이터 형식 · 기본 형식 : 기본 값을 저장한다. · 참조 형식 : 객체에 대한 참조를 제공한다. 이름(식별자) 규칙 · 길이 제한이 없는 일련의 문자와 숫자다. 반드시 문자나 밑줄로 시작해야 한다. · C# 키워드를 사용해서는 안 된다.(아래의 표) · 해당 범위 내에서 고유해야 한다. · 대소문자 구별한다. abstract do in protected true as double int public false bool enum internal private uint 이외에도 C#에는 다양한 키워드가 존재한다. 키워드 앞에 @을 접두어로 붙이면 식별자로 사용할 수 있다. 적합한 식별자 예 x1 _x2 x_count @int 적합하지 않은 식별자 예 2x // 숫자로 시작 int // 키워드 c#+ // #, + 포함 출처 처음 배우는 C# : 초보자를 위한 입문 가이드 제이든 카이(지은이),

Naver Blog

[C#] 데이터 형식

C#은 강한 형식 언어로, 모든 데이터에 형식이 지정되어야 함을 의미한다. C#은 CTS 호환 및 CTS 비호환 모두 존재하는 내장 데이터 형식을 지원한다. 내장 형식은 .NET 클래스 라이브러리에서 형식에 대한 약식 이름이나 별칭이다. 예를 들면 int는 System.Int32 구조체에 대한 약식 이름이다. C# 형식 .NET 형식 크기(byte) 값/범위 byte Byte 1 0 ~ 255 char Char 2 모든 유니코드 문자 bool Boolean 1 참 또는 거짓 sbyte SByte 1 -128 ~ 127 short Int16 2 -32,768 ~ 32,767 ushort UInt16 2 0 ~ 65,535 int Int32 4 -2,147,483,648 ~ 2,147,483,647 uint UInt32 4 0 ~ 4,294,967,295 long Int64 8 -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775807 ulong U

Naver Blog

[C#] 인코딩 집합

ASCII : 7비트로 128개의 문자를 표시한다. 소문자와 대문자, 라틴어 글자, 숫자, 구두점을 포함한다. 확장 ASCII : 기존의 ASCII에서 독일 문자, 영국 통화 기호와 같은 또 다른 128개의 문자를 포함하도록 확장하여 8비트로 256개의 문자를 나타낸다. 문자당 8비트를 갖는 문자 집합은 바이트 또한 8비트 길이이기 때문에 저장하고 전송하는 것이 가장 효과적이다. 하지만 이외의 문자(한국어, 중국어 등)를 나타낼 수 없기 때문에 세계 모든 언어의 문자를 포함하기 위한 유니코드가 나왔다. 초기에 유니코드 문자는 16비트로 나타냈고 6만 5000개 이상의 다른 문자를 나타내기에 충분했다. 유니코드가 모든 언어에서 사용되는 모든 문자에 대한 충분한 공간을 제공하는 반면, 유니코드 텍스트를 저장하고 전송하는 것은 ASCII 처럼 문자를 저장하고 전송하는 것만큼 효과적이지 않다. 그로인해 문자 인코딩이 나오게 되었다. · UTF-8(Unicode TransformationFo

Naver Blog

[C#] 객체 지향 프로그래밍(OOP)

객체 지향 프로그래밍(OOP, Object Oriented Programming)은 실세계 객체에서 애플리케이션을 모델링하는데 사용한다. OOP의 원리 · 캡슐화 : 비슷한 역할을 하는 속성과 메소드들을 하나의 클래스로 모으는 것. · 상속 : 상위 클래스의 필드와 메소드를 그대로 물려받는 것. · 다형성 : 같은 함수가 상황에 따라 다르게 동작하는 것. OOP의 이점 유지관리의 용이성 : 대규모 프로그램은 서로 다른 부분 간에 상호의존성이 있기 때문에 프로그램의 일부에서 뭔가를 변경했을 때 다른 부분에 어떻게 영향을 끼치는지 깨닫지 못할 수 있다. OOP에서는 애플리케이션을 모듈화를하여 한 클래스가 유사한 기능과 관련 데이터를 포함하여 유지보수가 좋다. 재사용성 : 이전에 작성한 코드에서 제공한 동일한 기능을 최초 작성자와 다른 사람이 재사용할 수 있음을 의미한다. C#의 경우 .NET 프레임워크에서 주의 깊게 설계하고 테스트한 클래스 라이브러리와 애플리 케이션을 설계할 때, 객체

Naver Blog

[C#] .NET 프레임워크

C#은 아주 다양한 기술의 방대한 컬렉션인 .NET 프레임워크의 일부이다. .NET 프레임워크는 공용 언어 인프라(CLI, Common Language Infrastructure)라 불리는 프로그래밍 환경 명세에 대한 널리 알려진 이름이다. 장점 .NET 프레임워크의 장점 중 하나는 C#, C++를 포함해 여러 프로그래밍 언어를 지원하기 때문에 새로운 언어를 배울 필요가 없다. 이외에도 다양한 장점이 있다. · 언어 상호간 통합 · 사용의 용이성 · 플랫폼 독립 · 애플리케이션 개발 속도를 올려주는 많은 클래스 라이브러리 · 보안 · 확장성 · 업계의 광범위한 지원 프로그래밍 환경 전통적인 프로그래밍에서 소스코드는 실행 코드로 컴파일되어 의도한 플랫폼에서만 실행할 수 있기 때문에 대상 플랫폼에 네이티브하다. 즉, 윈도우용으로 작성하고 컴파일한 코드는 윈도우에서만 돌아가는 것이다. 하지만 .NET 프레임워크 프로그램은 공용 중간 언어(CIL, Common Intermediate Lan

Naver Blog

[WPF] 스레드로 인한 NotSupportedException 예외 해결 방법

using System.Collections.ObjectModel; using System.Threading; namespace ThreadError { public class MainWindowVM { ObservableCollection<int> items; Thread thread; public ObservableCollection<int> Items { get { return items; } set { items = value; } } public MainWindowVM() { Items = new ObservableCollection<int>(); Items.Add(0); Items.Add(1); Items.Add(2); thread = new Thread(ThreadMethod); thread.IsBackground = true; thread.Start(); } private void ThreadMethod() { for(int i = 3; i < 100; i++) { I

Naver Blog

[WPF] 의존 프로퍼티(DependencyProperty)

WPF에서 제공하는 컨트롤의 대부분 속성은 의존 프로퍼티로 구현되어있다. 의존 프로퍼티는 XAML, C# 코드 비하인드에서 사용가능하며, 의존 프로퍼티 값이 변경되면 이벤트가 발생하여 작업(데이터 바인딩, 애니메이션, 스타일링 등)을 수행한다. 간단한 예로 콤보박스에서 콤보박스아이템을 클릭하면 윈도우 배경색을 변경해보자. MainWindow.xaml <Window x:Class="DependencyPropertyStudy.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/20

Naver Blog

[WPF] DataGridComboBoxColumn ItemsSource Binding

DataGrid를 다루면서 DataGridComboBoxColumn을 사용할 일이 생겼다. 평소처럼 DataGridComboBoxColumn의 ItemsSource에 바안딩하였지만 값이 안 나오는 현상이 발견되었다! <DataGridComboBoxColumn Header="성별" SelectedItemBinding="{Binding Gender}" ItemsSource="{Binding ComboBoxItems}"/> DataGridComboBoxColumn 바인딩 미적용 이를 해결하기 위해 다음과 같이 바인딩 하면 된다. <DataGridComboBoxColumn Header="성별" SelectedItemBinding="{Binding Gender}"> <DataGridComboBoxColumn.ElementStyle> <Style TargetType="{x:Type ComboBox}"> <Setter Property="ItemsSource" Value="{Binding Path

Naver Blog

[WPF] UpdateSourceTrigger 속성

TextBox 컨트롤을 사용하다 보면 바인딩한 속성값이 즉시 반영되지 않고 TextBox 컨트롤의 포커스가 손실된 후 변경 내용이 업데이트되는 것을 확인할 수 있다. 이것은 UpdateSourceTrigger라는 바인딩의 속성에 의해 제어된다. 기본값은 "Default"이고, 이외에 PropertyChanged, LostFocus, Explict 값을 가질 수 있다. UpdateSourceTrigger 속성이 가질 수 있는 값 Default : 바인딩하는 속성을 기반으로 소스가 업데이트 된다. Text 속성은 대상 요소의 포커스를 잃을 때 업데이트되고, 이외의 모든 속성은 값을 변경하는 즉시 업데이트된다. PropertyChanged : 변경하는 즉시 업데이트된다. LostFocus : 대상 요소의 포커스를 잃을 때 업데이트된다. Explicit : 바인딩에서 UpdateSource를 직접 호출하면 업데이트된다. 실제로 어떻게 동작하는지 예제를 통해 확인해보자. MainWindow.

Naver Blog

[WPF] ComboBox SelectedItem에 Int 속성 바인딩

MainWindow.xaml <Window x:Class="WpfApp1.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:vm="clr-namespace:WpfApp1" mc:Ignorable="d" d:DataContext="{d:DesignInstance vm:MainWIndowVM}" Title="MainWindow" Height="200" Width="400"> <StackPanel> <TextBlock Text="{Binding value}" /

Naver Blog

[WPF] 메소드

View에서의 컨트롤 이벤트에 대한 응답으로 ViewModel에 정의되어 있는 메소드를 호출하는 방법을 배워보겠다!! 우선 프로젝트에서 참조에 dll 파일 2개를 추가해야한다. 1. Microsoft.Expression.Interactions.dll 2. System.Windows.Interactivity.dll 해당 dll파일 추가 방법 프로젝트 마우스 우클릭 -> Nuget 패키지 관리 클릭 2. 찾아보기 탭에서 interactivity 검색하여 설치 3. 참조 추가되었는지 확인 그런 다음, XAML에서 화면(창, 페이지, 사용자 정의 컨트롤)의 루트 요소에 다음 특성을 추가한다. <Window ... xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" ...> 이제 사용자가 XAML에서

Naver Blog

[WPF] 명령(ICommand)

이전에 배웠던 MVVM 패턴 예제에는 TextBox의 Text 속성에 바인딩으로 UpdateSourceTrigger 및 ComboBox 컨트롤의 SelectedItem 속성 덕분에 사용자 상호작용에 대해 알 수 있었다. 하지만, 우리는 종종 사용자가 버튼을 눌렀는지만 알고 싶을 때가 있다. 이때 명령 또는 메소드를 사용하여 처리할 수 있다. 오늘은 그 중 명령에 대해 알아보자~! WPF에는 ICommand 인터페이스가 포함되어 있다. 우리는 ICommand 인터페이스를 구현하는 클래스를 인스턴스화하여 Button 및 MenuItem 같은 다양한 컨트롤의 Command 속성을 사용해 참조할 수 있다. 즉, Command 속성에 객체를 넣어주면 해당 컨트롤을 클릭하면 명령이 호출된다. 다음은 일반적으로 사용하기 좋은 ICommand 인터페이스를 구현한 클래스이다. class DelegateCommand : ICommand { private readonly Action<object> ex

Naver Blog

[WPF] MVVM 패턴

만약 하나의 C# 파일에 컨트롤 코드와 논리적 기능 코드가 작성되어 있다면 많은 문제점이 있다. · 거대한 파일을 만들어내고 유지 보수가 갈수록 어렵게 된다. · 테스트를 하기위해 UI를 인스턴스화해야 하므로 어렵다. · 컨트롤에 대한 참조는 다른 화면에서 코드 재사용을 어렵게 한다. 이외에도 많은 문제점이 있으므로 우리는 WPF로 애플리케이션 개발할때 MVVM 패턴을 활용하여 개발해야 한다. MVVM 구성 · Model : 비즈니스 클래스로 구성되어 UI에 제공된 데이터를 갖고 있다. Model은 쉽게 단위 테스트 가능하다. · View : 순수 XAML로 구성된 UI이다. View는 자동화된 테스트를 사용해 테스트가 어렵기 때문에 View의 코드 양을 줄여야 한다. · ViewModel : View의 DataContext 역할을 하여 둘 사이의 접착제 역할을 한다. MVVM 모델의 장점 · 설계자의 코드 리뷰를 훨씬 쉽게 만들어준다. · 깨끗하고, 재사용 가능하다 · 자동화된 단

Naver Blog

[WPF] 변형(RenderTransform, LayoutTransform)

WPF는 컨트롤을 쉽게 크기 변경, 회전 또는 기울일 수 있다. 모든 컨트롤에는 변형을 위해 사용 가능한 RenderTransform, LayoutTransform이 있다. 둘 다 적용할 변형을 묘사하는 똑같은 하위 항목을 갖는다. 변형에 필요한 XAML을 직접 작성할 수도 있지만 무의미하다. 비주얼 스튜디오에서는 직관적인 방법으로 변형이 가능하다. 컨트롤의 속성 창을 열면 당므과 같은 변형 부분이 나타난다. 둘의 차이점은 필요한 크기를 계산할 때의 계산 방법이다. RenderTransform은 컨트롤에 필요한 크기를 계산할 때 변환을 고려하지 않는 반면 LayoutTransfrom은 변환을 고려한다. 디자인 모드에서 작업하거나 Canvas를 사용할 때 차이점이 없으므로 LayoutTransform이 자주 사용되지 않는다. 아래는 RenderTransform과 LayoutTransform의 차이점을 보여주는 예시이다. 왼쪽에는 ListBox 내부의 GroupBox 컨트롤에 Rende

Naver Blog

[WPF] Style

Style은 이름에서 알 수 있듯이 컨트롤의 모양을 스타일링하는 좋은 방법이다. Style을 이해하려면 "다중 속성 설정자"로 생각해야 한다. 여러 Button 컨트롤의 Background를 멋진 그래디언트 브러시로 설정하고 Width, Height를 표준값으로해야 한다면 다음과 같이 할 수 있다. <Application.Resources> <Style x:Key="niceButton" TargetType="Button"> <Setter Property="Width" Value="50"/> <Setter Property="Height" Value="50"/> <Setter Property="Background"> <Setter.Value> <LinearGradientBrush> <GradientStop Color="Red" /> <GradientStop Color="Yellow" Offset="1"/> </LinearGradientBrush> </Setter.Value> </Sett

Naver Blog

[WPF] 리소스

일단 컨트롤에 대한 훌륭한 템플릿을 작성하면 애플리케이션 전체에 걸쳐 여러 곳에서 사용되기를 원할 것이다. 이런 경우 리소스가 빛을 발한다. 실제로 XAML에서 여러 컨트롤을 통해 일부 XAML을 공유가 필요할 때마다 리소스가 애플리케이션 전체에서 같은 화면 또는 다른 화면에 있든 상관없이 응답할 수 있다. 애플리케이션 내부의 모든 컨트롤은 문자열 키 사전인 Resources 속성을 사용해 리소스를 저장할 수 있다. 즉, 문자열 키를 제공하는 모든 리소스 객체를 추가할 수 있다. 컨트롤 자체와 모든 하위 컨트롤은 컨트롤의 리소스에 접근할 수 있으므로 리소스를 저장하는 곳은 주로 다음과 같은 두 곳이다. 화면 : 페이지, 사용자 정의 컨트롤 또는 창과 같이 단일 화면으로 범위가 지정된 리소스 애플리케이션 : App.xaml에 선언된 Application 요소와 같이 애플리케이션 전반에 걸쳐 사용되는 리소스 App.xaml 파일에 두 개의 리소스를 선언한다. <Application x:

Naver Blog

[WPF] 템플릿

거의 모든 WPF 컨트롤은 Template 속성이 있다. 컨트롤에 새로운 모양을 제공하려면 새 ControlTemplate 인스턴스를 컨트롤 속성에 할당한다. <Button Content="Prees Me"> <Button.Template> <ControlTemplate TargetType="{x:Type Button}"> <Ellipse Fill="GreenYellow" Width="100" Height="100"/> </ControlTemplate> </Button.Template> </Button> 기본모양이 원으로 바뀌었지만 Button 컨트롤의 완전한 기능을 갖추고 있으므로 사용자와 상호작용할 때 Click 이벤트나 MouseOver 이벤트가 발생한다. 이벤트를 발생하는 표면이 더 이상 직사각형이 아니기 때문에 원 외부를 클릭하면 Click 이벤트가 발생하지 않는다. 내용이 없는 영역은 컨트롤의 일부가 아니고 마우스 포인터를 가로채지도 않는다. 템플릿화를 위해 방금 작성한

Naver Blog

[WPF] INotifyPropertyChanged, INotifyCollectionChanged

INotifyPropertyChanged 컨트롤을 통해 사용자가 속성을 업데이트하면 동일한 속성에 바인딩된 다른 컨트롤도 업데이트된다. 그러나 이벤트에 대한 응답 또는 웹 서비스에서 오는 데이터와 같이 코드 자체로 인해 속성이 변경되면 해당 속성에 바인딩된 컨트롤이 업데이트 되지 않는다. 이런 종류의 시나리오가 작동하려면 속성이 변경되기 시작할 때 이벤트를 발생시켜야 한다. 속성 변경 이벤트는 INotifyPropertyChanged 인터페이스에 설명되어 있으며, 이는 데이터 객체가 사실상 INotifyPropertyChanged 인터페이스를 구현해야 한다는 의미다. 모든 데이터 객체에 속성 변경 이벤트가 필요하므로 모든 프로젝트에 다음과 같이 Notifier 클래스를 추가하고 데이터 객체에서 상속하는 것이 좋다. class Notifier : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChan

Naver Blog

[WPF] 목록 컨트롤 사용자 정의

한 번에 하나의 속성만 바인딩하는 데이터를 보았지만 종종 사용자가 데이터의 컬렉션을 확인하고 업데이트할 수 있게 해야 한다. WPF의 모든 목록 컨트롤에는 IEnumerable로 형식화된 ItemsSource 속성이 있다. 해당 속성에 컬렉션을 지정하면 목록 컨트롤에 모든 컬렉션 요소가 표시된다. Car.cs class Car { private int speed; private Color color; public int Speed { get { return speed; } set { this.speed = value; } } public Color Color { get { return color; } set { this.color = value; } } } MainWindow.xaml.cs public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); var cars = new List<C

Naver Blog

[WPF] Converter

XAML 엔진은 데이터 바인딩 시 객체 유형 및 값을 변환하는 훌륭한 작업을 수행한다. 이러한 변환 시스템은 변환기(Converters)를 사용해 확장할 수 있다. 변환기는 IValueConverter 인터페이스를 상속해 구현하는 단순한 클래스다. 구현해야 하는 메소드인 Convert는 표준 메소드고, ConvertBack은 양방향 데이터 바인딩에서만 사용된다. 자동차의 속도를 나타내는 int형 speed 값을 받아 string으로 변환해 속도를 보여주는 예시이다. Car.cs class Car { private int speed; public int Speed { get { return speed; } set { this.speed = value; } } public Car(int speed) { this.speed = speed; } } SpeedConverter.cs public class SpeedConverter : IValueConverter { // 속도 값을 받아 st

Naver Blog

[WPF] DataContext

데이터 중심 애플리케이션의 화면에서 시각적으로 그룹화된 대부분의 컨트롤은 동일한 데이터 객체의 데이터를 사용한다. 그러므로 바인딩에 대해 작성한 XAML을 단순화하기 위해 DataContext를 사용한다. 바인딩에서 ElementName, Source 속성을 사용하여 소스 데이터 객체를 지정하지 않으면 소스가 현재 DataContext로 간주된다. DataContext를 이용해 Window의 너비와 높이를 보여주는 예제이다. MainWindow.xaml.cs public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); this.DataContext = this; } } Window의 DataContext에 this로 인해 MainWindow가 설정된다. MainWindow.xaml <Window x:Class="Chapter4.MainWindow" xmlns="http://schemas.

Naver Blog

[WPF] 데이터 바인딩

데이터 바인딩 WPF에서는 UI를 데이터와 동기화한 상태로 유지하기 위해 아주 적은 양의 코드를 작성한다. 그로인해, 애플리케이션의 빠른 작성 속도 + 애플리케이션 유지 보수 시 작업이 훨씬 적다. 데이터 중심의 애플리케이션을 살펴보면 데이터를 표시하는 컨트롤이 있다. 즉, 컨트롤의 속성에 변수를 할당할 수 있다. 컨트롤 속성에 변수 할당 Text 속성은 데이터 객체(c)의 Speed 속성 값에 실제로 연결돼 Speed 속성이 TextBox 컨트롤의 Text 속성에 초기 할당되고 나면 Text 속성의 모든 변경이 데이터 객체의 Speed 속성에 할당된다. <TextBox Text="{Binding Speed, ElementName=c}" /> Binding 키워드 다음에 연결할 데이터 객체 속성의 이름을 쓰면 데이터 객체의 위치를 지정할 수 있다. ElementName 구문을 사용해 데이터 객체가 명명된 요소임을 나타낸다. <TextBox Text="{Binding Speed}" /

Naver Blog

[WPF] 목록 컨트롤

대부분의 경우 요소가 XAML을 사용해 정의되지 않고, 오히려 데이터 요소 컬렉션에 바인딩된다. 목록 컨트롤은 컨트롤 모양을 변경하는 템플릿뿐만 아니라 항목의 표시 방법을 변경하는 항목 템플릿을 제공한다. 이것은 결국 두 가지 의미가 있다. 기본 모양에서 쉽게 변경할 수 있다. 외형이 아닌 필요한 동작에 초점을 맞춰 컨트롤을 선택해야 한다. ListBox ListBox 컨트롤은 하나 또는 그 이상의 항목을 선택할 수 있으며, 한 번에 여러 항목을 표시할 수 있다. <ListBox Height="100"> <Label>Element1</Label> <Label>Element2</Label> <GroupBox Header="Element3"> With some content it's funnier </GroupBox> </ListBox> ComboBox ComboBox는 하나의 항목을 선택할 수 있으며, 두 가지 표시 모드를 갖는다. 하나는 선택한 요소가 표시되고 다른 하나는 사용 가능

Naver Blog

[WPF] Layout

지금까지 도구상자에서 디자인 화면으로 끌어다 놓기를 사용해 컨트롤을 화면에 추가했다. 비주얼 스튜디오는 끌어다 놓기 동작을 루트 컨트롤이 Canvas일 때 너비, 높이, 왼쪽 및 상단으로 하고, 루트 컨트롤이 Grid일 때 HorizontalAlignment, VerticalAlignment 컨트롤 속성으로 변환한다. 이러한 속성은 컨트롤의 위치와 크기를 지정하므로 화면에 고정된 컨트롤이 표시된다. WPF는 컨트롤의 최종 너비(높이) 를 계산하기 위해 다음 과정을 진행한다. 콘텐츠나 자식 항목에 필요한 너비 계산 부모에 의해 제한되는 너비가 있다면 재정의 Width, MinWidth, MaxWidth 속성이 존재한다면 재정의 ※ Width 속성은 실제로 원하는 너비다. 런타임 시 임시 컨트롤에 할당된 실제 너비를 알고 싶다면 컨트롤의 ActualWidth 속성을 사용하면 된다. Canvas 컨트롤 최종 크기 계산 <Canvas Width="50" Height="50" Backgrou

Naver Blog

[WPF] 이벤트

WPF 컨트롤은 이벤트를 선언하며 속성과 마찬가지로 XAML의 특성으로 사용할 수 있다. 단순히 특성에 코드 비하인드 메소드명을 제공하면 된다. 다음 코드는 코드 비하인드를 사용해 버튼의 Click 이벤트를 처리한다. MainWindow.xaml <Button Content="event Test" Click="Button_Click"/> MainWindow.xaml.cs private void Button_Click(object sender, RoutedEventArgs e) { MessageBox.Show("Button Click"); } 이벤트 추가 방법 xaml 컨트롤 구문 또는 디자인에서 컨트롤 클릭 시 속성창에 잡힌다. 이후 번개 표시를 누르게되면 각종 이벤트가 나오게된다. 여기서 빈 텍스트박스를 더블클릭하면 이벤트가 추가된다. 만약, 메소드명을 지정하고싶으면 메소드명을 입력 후 더블클릭하면 된다. 출처 WPF MVVM 일주일 만에 배우기 아르노 베유(지은이), 금재용(옮긴

Naver Blog

[WPF] XAML 이해

XAML 네임스페이스 <StackPanel xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Button x:Name="someButton">Hello</Button> </StackPanel> xmlns 특성은 C# 코드의 using 키워드와 같이 XAML 네임스페이스의 사용을 선언한다. 값은 URL이다. URL이 “http://”로 시작하지만 브라우저에 URL을 입력하면 아무것도 표시되지 않을 수 있다. XML은 여러 XML 문서에서 고유한 이름 영역을 보장하기 위해 URL을 사용한다. xmlns 특성이 요소에 추가되면 이 요소와 해당 하위 요소에 기본적으로 해당 URL이 접두어로 추가된다는 것을 의미한다. StackPanel 요소는 실제로 다음과 같다. http://schemas.microsoft.com/winf

Naver Blog

[WPF] 페이지 탐색

사용자는 애플리케이션 내에서 탐색(Navigation)하는데 익숙하다. 이전 화면으로 돌아가기 및 기록에서 되돌아가기는 애플리케이션 요구 사항의 흔한 일부 기능이다. WPF는 탐색 시스템 사용 시 화면은 페이지(Page)들이고, 페이지들은 단일 Frame 컨트롤 내부에 표시된다. Page는 XAML 파일이고 테두리나 창 관련 속성이 없다는 것을 제외하면 Window와 마찬가지로 고려할 수 있다. Frame 컨트롤은 웹 브라우저로 생각하면 된다. 애플리케이션에 필요한 화면만큼의 페이지를 생성한 다음 페이지 브라우저로 사용할 Frame 컨트롤을 추가한다. Frame 컨트롤을 배치하는 자연스러운 장소는 기본으로 생성된 MainWindow.xaml 창이다. Source 속성을 사용해 표시할 페이지를 Frame 컨트롤에 지정한다. <Frame Source="/Page2.xaml" /> 위의 코드는 Page2 페이지를 표시한다. 아래의 예제는 사용자가 한 페이지에서 다른 페이지로 이동할 수 있

Naver Blog

[WPF] 컨트롤

화면(Window, Page, 사용자 정의 컨트롤)에 컨트롤을 추가하는 두 가지 방법 도구상자에서 컨트롤을 끌어다 놓는 방법 단순 XAML 파일에 XML 요소를 추가하는 방법 예제들은 MainWindow.xaml 파일에 <Grid></Grid> 부분을 <StackPanel></StackPanel>로 변경 후 작성하였다. 기본 컨트롤 <StackPanel> <TextBlock Text="TextBlock"/> <TextBox Text="TextBox"/> <ProgressBar Value="25" Width="60" Height="20"/> <Slider Value="2" Width="60"/> <PasswordBox Password="Secret"/> </StackPanel> TextBlock 및 TextBox 컨트롤은 문자열을 Text 속성으로 표시하거나 입력할 수 있지만, ProgressBar 및 Slider 컨트롤은 Value 속성으로 double 값을 표시하거나 입력할 수 있

Naver Blog

[WPF] WPF 프로젝트 생성

기본적인 WPF 프로젝트 생성 방법에 대해 알아보겠다. 1. 비주얼 스튜디오를 시작한다. 2. 파일 → 새로만들기 → 프로젝트... 메뉴 항목을 클릭한다. 3. WPF 앱(.NET Framework) 템플릿을 선택하여 다음(N)을 누른다. 4. 프로젝트 이름 및 위치, 솔루션을 작성 후 만들기(C)를 누른다. WPF 프로젝트 구성 1. App.xaml & App.xaml.cs WPF 애플리케이션은 System.Windows.Application의 인스턴스나 상속받은 클래스의 인스턴스로 나타낸다. Application 객체를 생성한 후, Run 메소드를 호출해 애플리케이션을 시작한다. WPF 애플리케이션은 단일 스레드여야 되기 때문에 생성할 때 Main 메소드에 [STAThread] 특성을 달아야 한다. App 클래스가 Application을 상속은 받고있지만 [STAThread] 특성이나 Run 메소드 호출부분이 없다. 이것은 App.xaml의 파일 속성 중 빌드 작업 Applica

Naver Blog

[WPF] WPF

WPF(Windows Presentation Foundation)는 데스크톱 애플리케이션을 개발하는데 사용하는 UI 프레임워크다. WPF는 .NET 개발자가 Windows Form과 GDI+를 사용하려면 익혀야 했던 다양한 기술을 합했기 때문에 더 나은 솔루션이다. WPF는 외관 및 로직을 분리하기 위해 각 화면에는 두 개의 파일이 있다. 애니메이션까지 모두 포함하는 외관을 설명하는 XAML(XML Application Markup Language) 파일 화면의 기능적 로직을 설명하는 코드 비하인드라는 C# 파일 즉, MyScreen이라는 화면을 생성하면 MyScreen.xaml(외관) 및 MyScreen.xaml.cs(코드 비하인드)의 두 파일이 만들어진다. 이렇게 분리된 파일을 사용하면 디자이너와 개발자는 같은 프로젝트에서 각자 자신의 파일로 작업할 수 있다. 이 분리와는 별개로 WPF는 다음과 같은 기능을 도입했다. 컨트롤 조합 : 대부분의 컨트롤은 다른 컨트롤을 호스팅할 수

Naver Blog

[WPF_SciChart] 01.SciChartSurface 만들기

WPF에서 SciChart가 제공하는 2D차트인 SciChartSurface에 대한 기본 사용법(With. MVVM패턴)에 대해 배워보자. SciChartSurface 만들기(With. MVVM패턴) MainViewModel.cs using SciChart.Data.Model; namespace MVVMSciChartSurface { public class MainViewModel : BindableObject { private string _chartTitle = "Hello SciChart World"; private string _xAxisTitle = "XAxis"; private string _yAxisTitle = "YAxis"; public string ChartTitle { get { return _chartTitle; } set { _chartTitle = value; OnPropertyChanged(nameof(ChartTitle)); } } public stri

Naver Blog

[WPF_SciChart] 02.SciChartSurface ChartModifier 차트 동작 추가

01.SciChartSurface 만들기에서 2D 차트에 데이터 표시까지 완료하였다. 이번에는 XAML에서 ChartModifier 그룹을 정의하여 줌, 팬 등의 동작을 추가해보자. MainViewModel.cs private bool _enableZoom = true; private bool _enablePan = false; public bool EnableZoom { get { return _enableZoom; } set { if(_enableZoom != value) { _enableZoom = value; OnPropertyChanged(nameof(EnableZoom)); if (_enableZoom) EnablePan = false; } } } public bool EnablePan { get { return _enablePan; } set { if(_enablePan != value) { _enablePan = value; OnPropertyChanged(nameo

Naver Blog

[WPF_SciChart] 03.SciChartSurface 툴팁 및 범례 추가하기

02.SciChartSurface ChartModifier 차트 동작 추가를 통해 차트에 각종 동작하는 방법을 배웠다. 이번에는 차트에 툴팁 및 범례를 추가하는 방법을 배워보자. 툴팁 및 범례 추가 그러기 위해서 LegendModifier와 RolloverModifier를 다음과 같이 View에 추가해야 한다. MainWindow.xaml <s:SciChartSurface.ChartModifier> <s:ModifierGroup> ... <s:LegendModifier ShowLegend="True" Orientation="Horizontal" VerticalAlignment="Top" HorizontalAlignment="Center"/> <s:RolloverModifier ShowTooltipOn="MouseHover"/> ... </s:ModifierGroup> </s:SciChartSurface.ChartModifier> 실행결과 툴팁 템플릿 사용자 정의 MainWind

Naver Blog

[WPF_SciChart] 04.SciChartSurface 실시간 업데이트 추가하기

03.SciChartSurface 툴팁 및 범례 추가하기까지 완료하였다. 이번에는 차트에 실시간 데이터 업데이트를 추가하여보자. 실시간 업데이트 추가하기 SciChartSurface를 ViewModel에 바인딩했으므로 ViewModel에서 XyDataSeries를 조작하기만 하면 차트가 자동으로 업데이트된다. 이것을 적절하게 수행하고 값을 제공하기 위해 새 클래스를 추가할 것이다. 이 클래스는 외부 서비스 또는 데이터 공급자를 시뮬레이션하여 차트에 업데이트를 추가한다. DummyDataProvider.cs using System; using System.Collections.Generic; using System.ComponentModel; using System.Windows.Threading; namespace MVVMSciChartSurface { public struct XyValues { public IList<double> XValues; public IList<doub

Naver Blog

[WPF_SciChart] 05.SciChartSurface 주석 추가

04.SciChartSurface 실시간 업데이트 추가하기를 통해 실시간으로 데이터를 업데이트했다. 이번에는 차트 위에 WPF UIElement를 배치할 수 있는 주석 API를 배워보자. SciChart가 제공해주는 주석 추가하기 SciChart는 다양한 주석 API를 제공한다. LineAnnotation LineArrowAnnotation TextAnnotation BoxAnnotation VerticalLineAnnotation HorizontalLineAnnotation AxisMarkerAnnotation CustomAnnotation CompositeAnnotation 템플릿 주석 크기 조정 그립 주석 편집 및 상호 작용 여기서는 수직선 주석을 추가해보자. MainWindow.xaml(소스코드 추가) <s:SciChartSurface> ... <s:SciChartSurface.Annotations> <s:VerticalLineAnnotation Stroke="Red" St

Naver Blog

[대전 관평동 맛집] 치맥하기 좋은 구도로통닭 대전관평점

짝꿍과 치맥하려고 대전 관평동 맛집인 구도로통닭 대전관평점에 다녀왔어요. 구도로통닭은 본가인 진주에 아직 없어서 못 먹어봤는데 이미 전국에 체인이 있을 만큼 유명하더라고요!! 대표메뉴인 전기구이 통닭이 돌아가고 있더라고요!! 완전 신기해서 후다닥 보러 갔더니 모형이네요.. 머쓱.. 입간판에 판매 중인 메뉴를 볼 수 있는데 대표메뉴인 전기구이 통닭 외에도 바베큐, 탕류, 마른안주, 튀김류 등 되게 다양하게 있어서 회식하러 오기에도 좋겠더라고요. 구도로통닭 대전관평점 내부가 넓어 테이블이 많아요. 살짝 어두운데 중간중간 조명으로 포인트를 줬네요~! 무엇보다 살얼음맥주 숙성고가 영롱 그 자체더라고요ㅋㅋ 테이블에 있는 태블릿으로 주문하면 돼요. 구도로통닭 좋았던 점이 반 마리도 주문 가능하더라고요. 2차로 방문해도 간단하게 치맥하기 딱일 거 같아요. 태블릿에 다양한 정보들이 있어요. 구도로통닭에서 사용하는 품목 원산지도 있고 전기통닭을 더 맛있게 즐기는 꿀팁까지 있어요! 구도로통닭 대전관평

Naver Blog

노브랜드 2023년 2월 할인 행사상품(2월2일~2월15일)

요즘 물가가 어마무시해서 지갑이 얇아졌어요. 이럴때일수록 할인 행사상품 잘 챙겨가야겠죠! 노브랜드 2023년 2월 할인 행사상품 공유드려요. 기간과 조건이 상이하니 참고해서 쇼핑하세요~! 신석식품 초특가 기획은 기간이 2월 8일(수)까지네요. 고기, 쌀, 과일 다양하게 할인하니까 쟁여두기 좋겠네요! 득템찬스는 기간이 2월 15일(수)까지입니다. 라면, 피자, 냉동식품, 과자 다양하게 할인중이에요. 발렌타인데이 할인 2월 15일(수)까지 진행하네요. 다양한 초콜릿 할인하니까 참고해 주세요~ 신세계포인트 적립시 1+1 행사상품 노브랜드 쇼핑 시 신세계포인트 필수인거 아시죠!! 쟁여두기 좋은 라면, 냉동피자 할인 너무 좋네요~ 신세계포인트 적립시 할인 행사상품 계란, 쌀, 밀키트 다양하게 할인중이네요~ POS 자동에누리 1+1 행사상품 축산 행사상품 과일, 채소 행사상품 건식품 행사상품 과자 행사상품 베이커리 행사상품 커피, 음료 행사상품 냉동가공 행사상품 신세계포인트적립 외에도 기본 할

Naver Blog

진주 가좌동 밥집 스시캘리포니아 엠비씨네점 배달 후기

스시캘리포니아 엠비씨네점 배민 짝꿍이 집에서 가끔 시켜 먹는 곳으로 먹어봤어요. 진주 가좌동에 있는 스시캘리포니아 엠비씨네점!! 원래 갤백에 본점이 있다가 평거동으로 이전하고 엠비씨네점이 2호점으로 차려졌다 하더라고요. 스시캘리포니아 엠비씨네점 롤 스시 커플(2인 메뉴) 스시캘리포니아에 롤 스시 커플 메뉴를 판매하네요. 롤, 스시 비율을 다르게 할 수 있어서 좋더라고요. 초밥 안에 와사비, 장국, 반찬도 선택 가능해요. 배달을 시켰더니 이렇게 메뉴판도 주시네요. 영업시간이 10시 50분부터 21시까지이고 브레이크타임이 15시부터 16시 50분까지네요. 라스트오더 20시이니 시키실 때 참고해 주세요~ 종류가 워낙 많아서 이것저것 시켜 먹기 좋겠네요! 롤 스시 커플에서 스시로 주문했어요. 일단 음식을 놓고 보니 양이 엄청나네요! 리뷰 이벤트로 환타 서비스로 받았어요~ 짝꿍은 시킬 때마다 콘샐러드를 추가한대요! 옥수수콘, 게살, 오이가 듬뿍 들어가 있어요. 아는 맛이 무섭다고 딱 생각하시

Naver Blog

다이소 스테인레스 칼갈이 주방용품 추천템

오늘은 다이소 주방용품 추천템을 가져왔어요. 본가에서 가져온 칼이 제 기능을 못하더라고요! 다이소 스테인레스 칼갈이를 구매해서 칼을 갈았더니 새 거처럼 잘 썰리길래 추천템으로 소개해 드릴게요! 다이소 칼갈이 제품 종류가 다양하더라고요. 칼갈이 제품이 제일 많고 편해 보이는 걸로 샀어요. 제가 구매한 건 스테인레스 칼갈이 스탠드형이에요. 품명은 컬러풀 2칸 칼갈이, 품번은 62470 입니다. 다이소 칼갈이 사용방법도 되게 간단해서 좋아요. 먼저 텅스텐레일로 칼날을 견고하고 날카롭게 연마한 뒤 세라믹레일로 울퉁불퉁한 부분을 부드럽게 마무리하면 끝! ※ 칼날 연마 시엔 항상 칼을 몸 쪽으로 당겨주어야 돼요. 다이소 스테인레스 칼갈이 제품은 심플해요. 손잡이 부분과 칼갈이 하는 부분으로 되어있어요. 미끄럼 방지가 있어 칼갈이 시 미끄러지지 않아요! 한쪽 면에 레일이 표시되어 있어요. COARSE가 텅스텐레일이고 FINE이 세라믹레일이에요. 다이소 스테인레스 칼갈이 사용 전 다이소 스테인레스

Naver Blog

대전 둔산동 조개찜 맛집 수미어가

요즘같이 추운 날씨에 뜨끈한 국물이 최고잖아요. 대전 둔산동 조개찜 맛집 수미어가에 다녀왔어요! 신선한 조개도 먹고 맑고 얼큰한 국물까지 일석이조! 수미어가 영업시간이 오후 5시부터 11시까지인데 재료 소진이나 업소 사정으로 조기 마감될 수 있어요! 방문하시기 전에 042-486-1580 전화하시는 거 추천! 수미어가는 조개찜, 회, 육회, 매운탕 다양하게 판매해요. 겨울 별미로 참소라찜, 돌문어숙회, 석굴도 판매하네요!! 수미어가 내부는 넓어서 테이블 많고 깨끗했어요. 둔산동 맛집답게 회식하러 많이 오시더라고요. 수미어가 기본 찬도 너무 제 스타일이었어요! 튀김건빵, 회무침, 완두콩, 번데기, 죽이 나와요. 다 맛있어서 입맛 돋우기에 딱 좋더라고요. 뚝배기에 보글보글 나오는 계란찜도 기본 찬이라는 점. 아는 맛이 제일 무서운 법! 담백 고소한 계란찜이에요! 조개찜전골 小(2인) 55,000원 수미어가 조개찜 비주얼 대박이지 않나요?? 조개찜 보자마자 입이 떠억 벌려지더라고요!! 수

Naver Blog

진주 충무공동 이색카페, 혁신도시 테티스 베이커리 카페

요즘 이색카페를 찾아다니는 푸드코딩이에요~ 이번에는 진주 충무공동에 위치한 카페에 다녀왔어요! 테티스 베이커리 카페 진주혁신도시점이에요. 테티스는 2층 건물 통째로 쓰고 있는 카페라는 점!! 1층에서 음료, 빵을 구매해서 2층에서 먹으면 돼요. 베이커리 카페답게 빵 종류가 많아서 너무 좋았어요. 소금빵, 도넛, 쿠키, 케이크, 샌드위치 없는 게 없네요! 전일빵의 경우 50% 할인된 가격으로 판매하네요. 음료도 종류가 워낙 다양해서 좋네요~ 아메리카노 원두도 약배전, 중배전 두 가지가 있어요. 테티스만의 시그니처 메뉴도 있으니 참고해 주세요! 테티스 베이커리 카페가 이색카페인 이유는 수족관이에요. 제가 알기로는 진주에 수족관 있는 카페로 유일해요!! 종류도 워낙 다양해서 구경하는 재미가 있더라고요~ 수족관 안에 처음 보는 물고기들이 많이 있어요ㅋㅋ 저희에게 니모로 익숙한 흰동가리도 있네요~! 역시 익숙한 게 최고라고 바로 니모 쫓아가버리깅~ 테티스 베이커리 카페는 쿠폰도 있어요~! 분

Naver Blog

[진주 하대동 술집] 79대포, 파전 안주 맛집

명절 전날 3차까지 불태우고 집 앞까지 왔더니 장사하는 친구가 마감하고 이제 합류한다고.. 그리하여 다시 하대동으로 넘어와버렸어요ㅋㅋ 시간이 12시 넘어서 좀 오래 하는 술집으로 써치! 79대포 진주하대점 경상남도 진주시 도동로231번길 4 1층 79대포 빠삭파전 맛집 ️ 매일 17:00 - 03:00 골목 주차 요즘 하대동이 핫하다더니 사람도 많고 올 때마다 새로 생긴 술집들이 있네요ㅋㅋ 79대포 처음 봤지만 전국에 체인점이 있더라고요? (먼가 예전에 시내 79포차가 생각나는 상호명!!) 79대포 뜻이 "친구야 대포한잔하자"인가봐요. 한 마디로 큰 술잔에 거하게 마시자는 건가!? (나는 이미 거하게 마시고 와버렸는데..;;) 내부는 79년도 시절의 포스팅으로 꾸며서 살짝 예스러운 분위기를 연출했나봐요ㅋㅋ (먼가 제가 대학생 때 유행했던 느낌인데!?) 내부는 꽤 넓고 쾌적해서 괜찮았어요~! 눈을 사로잡는 빠삭파전 특허등록이라니!?? 빠삭하게 굽는 방법을 특허 내신 건가 독특하네요!

Naver Blog

대전 문지동 영칼로리카페, 대전 포케 샐러드, 샌드위치 맛집

올해의 목표인 제 자신을 가꾸기 위해 다이어트를 하는데 3주간의 노력이 단 4일의 명절로 인해 물거품이 되었어요. 제가 만드는 샐러드는 또 맛이 없어서 지속하기 힘들더라고요. 먹는 거에서 행복을 많이 느끼는 저한테 식단이 제일 힘든 부분. 그래서 집 근처인 문지동에 대전 포케 맛집이 있어서 다녀왔어요! 제가 방문한 곳은 영칼로리카페 대전문지점이에요. 빌라 1층에 위치해있어 주차는 근처 골목에 하시면 돼요. 대전 포케 맛집답게 배민 리뷰 수가 1000개 넘더라고요!! 입구 앞에 판매 중인 메뉴를 볼 수 있어서 좋네요. 영칼로리카페 포케 샐러드가 왜 맛있는가 했더니 트레이너, 영양사가 재해석하여 개발한 메뉴네요! 영칼로리카페 대전문지점 내부는 넓고 깔끔했어요. 아기용 의자, 우산꽂이, 담요도 준비되어 있어요. 독특한 게 테이블과 의자가 되게 다양하게 있어요. 특히 녹색의자가 완전 시선강탈하더라고요ㅋㅋ 영칼로리카페는 키오스크로 주문하는 시스템이에요. 포케 샐러드, 도시락, 샌드위치, 요거

Naver Blog

[WPF_DevExpress] PropertyGrid 시작하기 02. 컬렉션 정의

컬렉션 정의는 바인딩된 객체의 컬렉션 속성을 나타내고 속성그리드(PropertyGrid) 내에서 해당 모양을 지정한다. 각 컬렉션 정의는 바인딩된 객체의 하나 이상의 컬렉션 속성에 연결되며, PropertyGridControl.PropertyDefinitions 컬렉션 내에 저장된 CollectionDefinition 객체로 표시된다. PropertyGridControl 내 컬렉션 표시 PropertyGridControl.ShowProperties 속성이 WithPropertyDefinitions로 설정된 경우 컬렉션 항목의 속성을 수동으로 초기화해야 한다. MainWindowVM.cs using System.Collections.Generic; namespace CollectionDefintionStudy { public class MainWindowVM { public Product Product { get; set; } public MainWindowVM() { Product

Naver Blog

[WPF_DevExpress] PropertyGrid 시작하기 01.속성 정의

PropertyGridControl은 최종 사용자가 객체의 속성을 표시하고 편집할 수 있도록 하는 데이터 바인딩된 컨트롤이다. 내장된 검색 컨트롤, 다양한 셀 편집기, 런타임에 객체를 전환하는 기능, 유연한 속성 정의 등과 같은 여러 기능을 제공한다. 속성 정의 만들기 PropertyGridControl은 속성 정의를 사용하여 표시되는 속성과 방법을 정의한다. PropertyGridControl을 데이터에 바인딩하고 속성 정의를 만드는 방법을 배워보자. 1단계 - 속성 그리드 생성 PropertyGridControl 구성 요소를 프로젝트에 추가한다. 만약, Window 전체를 채우려면 속성 그리드를 마우스 우클릭하여 레이아웃 | 모두 다시 설정을 클릭한다. MainWindow.xaml <Window x:Class="PropertyGridControlStudy.MainWindow" Title="MainWindow" Height="350" Width="525" xmlns="http:/

Naver Blog

[WPF_DevExpress] DataGrid 그룹화

해당 글은 DevExpress 18.2 버전을 기준으로 작성되었습니다. GridControl을 사용하면 데이터를 열 수에 제한 없이 그룹화할 수 있다. 간격 그룹화 그룹화 열에 다른 데이터 유형이 포함된 경우 기본 그룹화 논리가 사용된다. 이 경우 행은 그룹화 열에 일치하는 값이 있는 경우 단일 그룹으로 결합된다. 간격 그룹화 기능을 사용하면 기본 논리를 변경할 수 있다. 열의 GridColumn.GroupInterval 속성을 사용하여 필요한 그룹화 모드를 지정한다. 대표적인 GroupInterval 속성 값 값 설명 Default 날짜/시간 값을 저장하는 열의 경우 ColumnGroupInterval.Date와 동일하게 작동하고 이외의 열은 ColumnGroupInterval.Value와 동일하게 작동한다. Value 행은 그룹화 열의 값으로 그룹화된다. 그룹 수는 그룹화 열 내의 고유 값 수와 일치한다. Date 이 옵션은 날짜/시간 값을 저장하는 열에만 적용된다. 행은 해당

Naver Blog

[WPF_DevExpress] DataGrid 시작하기 04. 그리드 요약(최댓값, 최솟값, 합계 등)

이전 글에서는 GridControl 데이터 관리(정렬, 필터링, 그룹화)에 대해 배웠다. 이번에는 GridControl의 행 및 그룹에 대한 간결한 정보(레코드 수, 최댓값, 최솟값)를 표시하는 그리드 요약을 배워보자. 요약은 모든 데이터 행(total summaries)과 그룹의 데이터 행(group summaries)에 대해 계산할 수 있다. 요약 패널(Total Summary) 또는 고정 요약 패널(Fixed Total Summary)은DataViewBase.ShowTotalSummary 또는 DataViewBase.ShowFixedTotalSummary 옵션이 활성화 되어야 표시된다. 고정 요약 패널에 표시되는 요약은 수평으로 스크롤되지 않으며 해당 열의 위치 및 가시성에 관계없이 항상 화면에 표시된다. <dxg:GridControl.View> <dxg:TableView ShowTotalSummary="True" ShowFixedTotalSummary="True"/> </dx

Naver Blog

[WPF_DevExpress] DataGrid 시작하기 03. 데이터 관리(정렬, 필터링, 그룹화)

이전 글에서는 GridControl 데이터 편집 및 표시에 대해 배웠다. 이번에는 GridControl 데이터 관리 기능의 기본 사항인 정렬, 필터링, 그룹화에 대해 배워보자. 정렬 그리드의 데이터는 열수에 제한 없이 정렬할 수 있다. 열에 대해 데이터를 정렬하거나 열의 정렬 순서를 변경하기 위해 사용자는 해당 열의 헤더를 클릭할 수 있다. 열의 현재 정렬 순서는 정렬 문양(, )으로 표시된다. 열에서 정렬을 지우려면 CTRL 키를 누른 상태에서 열의 헤더를 클릭하면 된다. 만약, 한 번에 여러 열을 기준으로 정렬하려면 Shift 키를 누른 상태에서 열의 헤더를 클릭하면 된다. 필터링 및 검색 필터링을 사용하면 원하는 기준을 충족하는 데이터 원본의 레코드 하위 집합을 표시할 수 있다. 단일 열 또는 여러 열에 대해 데이터를 필터링할 수 있다. 사용자는 자동 필터 행, 열의 필터 드롭다운 및 필터 편집기 대화상자를 사용하여 간단한 필터 기준을 만들고 적용할 수 있다. 또한 기본 제공

Naver Blog

[WPF_DevExpress] DataGrid 시작하기 02. 데이터 편집 및 표시

이전 글에서 프로젝트에 GridControl 추가 및 데이터 바인딩에 대해 배웠다. 이번에는 GridControl 내의 데이터 편집 및 표시에 대해 알아보자. 열 집합 조작 GirdControl은 바인딩 된 모든 데이터 소스 필드에 대한 열을 자동으로 생성했다. 열은 데이터 원본 필드가 정의된 것과 동일한 순서로 그리드 내부에 배치되었다. 그리드 내에 표시되어야 하는 데이터 소스 필드 및 순서를 수동으로 정의할 수 있다. 그러기 위해 GridControl의 스마트 태그를 호출하고 "Generate Columns"를 선택한다. 결과적으로 GridControl의 XAML은 다음과 같이 표시된다. 이제 개별 열(dxg:GridColumn)에 대한 설정을 정의할 수 있다. 순서나 FieldName 값을 변경해 보면 금방 알 수 있다. 열 편집 기능 확장 생성될 때 GridControl 열은 내용에 따라 내부 편집기를 가져온다. 기본적으로 CheckEdit는 Boolean 열을 편집하는 데

Naver Blog

[WPF_DevExpress] DataGrid 시작하기 01. GridControl 추가 및 데이터 바인딩

GridControl은 사용자가 많은 양의 데이터를 표시하고 관리할 수 있는 편집 및 데이터 형성 구성 요소이다. 특징 - 사용자 인터페이스가 항상 응답하도록 유지하면서 대량의 데이터와 함께 작동하도록 설계된 특정 데이터 바인딩 모드를 제공한다. - Tree List View와 Card View를 비롯한 다양한 View로 유연한 UI를 사용할 수 있다. - 정렬, 그룹화 및 요약 게산을 비롯한 매우 직관적인 데이터 형성 기능과 필터 패널 및 자동 필터 행과 같은 다양한 필터링 옵션을 제공한다. 프로젝트에 그리드 컨트롤 추가 및 데이터 바인딩 데이터 모델 추가 GridControl은 데이터 소스 없이 작동할 수 없으므로 ItemsSource 속성에 System.Collections.IEnumerable 인터페이스를 구현하는 모든 객체 또는 해당 하위 항목(예 : IList, ICollection)을 바인딩하면 된다. 데이터베이스의 데이터, XML 파일의 데이터, 런타임에 생성된 모든

Naver Blog

[WPF_DevExpress] Behavior 10.CompositeCommandBehavior

여러 명령을 순서대로 그룹화하고 실행하는 것은 WPF MVVM 응용 프로그램을 만들 때 일반적인 작업이다. 그러나 표준 WPF 메커니즘은 이러한 작업을 수행하는 편리한 방법을 제공하지 않는다. DevExpress의 경우 CompositeCommandBehavior를 사용하여 여러 명령을 집계하고 실행할 수 있다. CommpositeCommandBehavior를 사용하려면 아래 단계를 따른다. 1. 대상 컨트롤의 동작을 정의한다. <dxb:BarButtonItem Content="저장 및 닫기"> <dxmvvm:Interaction.Behaviors> <dxmvvm:CompositeCommandBehavior> </dxmvvm:CompositeCommandBehavior> </dxmvvm:Interaction.Behaviors> </dxb:BarButtonItem> 2. 명령(CommandItem 객체)을 만들고 동작에 추가한다. <dxb:BarButtonItem Content="저장

Naver Blog

[WPF_DevExpress] WPF 버튼에 DevExpress 이미지 사용하는 방법

우리는 WPF 버튼에 이미지를 사용하기 위해 다음과 같은 과정을 거쳐야 한다. 1. 사용할 이미지 찾기 2. 이미지 리소스로 추가하기 3. 리소스 빌드 작업 Resource로 변경하기 4. Image 사용 <Button Command="{Binding BtnClickCommand}" HorizontalAlignment="Center" VerticalAlignment="Center"> <Button.Template> <ControlTemplate> <Border HorizontalAlignment="Center" VerticalAlignment="Center"> <Image Source="Resources\Add_16x16.png" Width="16" Height="16" /> </Border> </ControlTemplate> </Button.Template> </Button> DevExpress에는 다양한 이미지 파일을 지원해 준다. 그래서 이 이미지를 WPF 버튼에 활용하기로 했

Naver Blog

[WPF_DevExpress] Behavior 09.EnumItemsSourceBehavior

EnumItemsSourceBehavior를 사용하면 열거형을 모든 컨트롤의 ItemsSource 속성에 바인딩할 수 있다. 아래는 UserRole 열거형을 ComboBoxEdit 컨트롤에 바인딩하는 예이다. public enum UserRole { [Image("pack://application:,,,/Resources/Admin.png"), Display(Name = "Admin", Description = "High level of access", Order = 5)] Administrator, [Image("pack://application:,,,/Resources/Moderator.png"), Display(Name = "Moderator", Description = "Average level of access", Order = 2)] Moderator, [Image("pack://application:,,,/Resources/User.png"), Display(Name =

Naver Blog

[WPF_DevExpress] Behavior 08.DependencyPropertyBehavior

UI 컨트롤의 일부 속성은 종속성 속성(DependencyProperty)이 아니다. 이는 WPF 바인딩 시스템이 이 속성을 대상으로 지정할 수 없다. 예를 들어 TextBox.SelectedText 속성이 종속성 속성이 아니므로 아래 코드가 허용되지 않음을 의미한다. <TextBox Text="Select some text in this box" SelectedText="{Binding SelectedText, Mode=TwoWay}"/> DependencyPropertyBehavior를 사용하여 이러한 문제를 해결할 수 있다. <TextBox Text="Select some text in this box"> <dxmvvm:Interaction.Behaviors> <dxmvvm:DependencyPropertyBehavior PropertyName="SelectedText" EventName="SelectionChanged" Binding="{Binding SelectedText,

Naver Blog

[WPF_DevExpress] Behavior 07.ConfirmationBehavior

작업을 수행하기 전에 확인메시지를 표시해야 하는 경우가 많다. 이때 ConfirmationBehavior를 사용하면 이 프로세스를 자동화할 수 있다. 예를 들어 최종 사용자가 저장되지 않은 문서를 닫을 때 "저장되지 않은 문서를 닫으시겠습니까?"라는 메시지를 표시하는 방법을 알아보자. <Button Content="Close"> <dxmvvm:Interaction.Behaviors> <dxmvvm:ConfirmationBehavior EnableConfirmationMessage="{Binding IsSaved, Converter={StaticResource BooleanNegationConverter}}" Command="{Binding CloseCommand}" MessageText="저장되지 않은 문서를 닫으시겠습니까?"/> </dxmvvm:Interaction.Behaviors> </Button> ConfirmationBehavior는 연결된 컨트롤의 명령 속성을 자동으로 설

Naver Blog

[WPF_DevExpress] Behavior 06.ValidationErrorsHostBehavior

ValidationErrorsHostBehavior를 사용하면 UI 컨테이너 내에서 유효성 검사 오류를 추적할 수 있다. 유효성을 검사할 컨트롤에 대해 Binding.NotifyOnValidationError 및 Binding.ValidatesOnDataErrors 속성을 true로 설정해야 한다. ValidationErrosHostBehavior.HasErrors 속성을 통해 바인딩된 UI 컨테이너에 유효성 검사 오류가 포함되어 있는지 확인할 수 있다. 뷰모델에서는 IDataErrorInfo 인터페이스를 구현해야 한다. POCO 뷰모델의 경우 DataAnnotation 속성을 기반으로 자동 생성할 수 있다. [POCOViewModel(ImplementIDataErrorInfo = true)] public class MainWindowVM { ... } 예시로 두 개의 필드(FirstName 및 LastName)에 유효성 검사를 하여 오류가 없는 경우에만 버튼이 활성화 된다고 해보자

Naver Blog

[WPF_DevExpress] Tile Layout 01.LayoutControl

LayoutControl은 단일 행 또는 열로 정렬하는 컨테이너이다. LayoutControl 기능 자식 컨트롤의 일관된 레이아웃을 자동으로 유지 관리한다는 것이다. 창의 크기를 조정하거나, 컨트롤을 추가 및 제거, 글꼴 설정을 변경하더라도 컨트롤이 겹치지 않는다. LayoutItem을 사용하면 LayoutControl에 포함된 컨트롤에 자동 정렬된다. 내장된 크기 조정기를 통해 하위 항목 및 그룹 크기 조정이 가능하다. 항목을 부모 컨트롤의 가장자리에 정렬하거나 가운데에 맞추거나 늘릴 수 있다. 부모의 크기가 변경되면 항목이 그에 따라 위치를 조정한다. 레이아웃 사용자 정의 모드에서 사용자는 끌어서 놓기를 통해 항목의 레이아웃을 수정하고 그룹 내 컨트롤의 정렬을 변경할 수 있다. 그룹은 Tabs 또는 GroupBox로 렌더링될 수 있다. LayoutControl 요소 LayoutControl은 모든 유형의 항목을 허용하지만 일반적으로 LayoutGroup, LayoutItem

Naver Blog

[WPF_DevExpress] Behavior 05.FocusBehavior

FocusBehavior를 사용하면 코드 비하인드를 사용하지 않고 UI 컨트롤에 포커스를 설정할 수 있다. Startup 될 때 포커스 연결된 컨트롤이 로드될 때 포커스를 설정하려면 컨트롤에 FocusBehavior를 다음과 같이 정의하면 된다. <TextBox Text="Startup 될 때 Foucs "> <dxmvvm:Interaction.Behaviors> <dxmvvm:FocusBehavior/> </dxmvvm:Interaction.Behaviors> </TextBox> 이벤트 또는 속성 변경될 때 포커스 이벤트가 발생할 때 컨트롤에 포커스를 설정하려면 EventName 속성을 지정하면 된다. 다음은 버튼 클릭 시 TextBox에 포커스를 설정하는 예다. <TextBox Text="버튼 클릭 시 Foucs "> <dxmvvm:Interaction.Behaviors> <dxmvvm:FocusBehavior SourceName="button" EventName="Click"/

Naver Blog

[WPF_DevExpress] Ribbon Quick Access Toolbar(리본 빠른 실행 툴바)

리본 빠른 실행 툴바는 사용자가 클릭 한 번으로 가장 중요하고 많이 사용하는 기능에 액세스할 수 있도록 설계된 사용자 정의 가능한 요소이다. 기본적으로 이 툴바는 RibbonControl위에 표시된다. 위치와 가시성은 RibbonControl.ToolbarShowMode 및 RibbonControl.RibbonTitleBarVisibility 속성을 사용하여 변경할 수 있다. RibbonPageGroup과 마찬가지로 빠른 실행 툴바에는 특정 BarItem 또는 BarItemLink로 표시되는 요소(버튼, 편집기 등)가 표시된다. 빠른 실행 툴바에 요소를 추가하려면 RibbonControl.ToolbarItems 컬렉션에 추가하면 된다. 위의 이미지처럼 Past, Cut, Copy 요소를 빠른 실행 툴바에 추가하는 코드는 다음과 같다. <dxr:RibbonControl DockPanel.Dock="Top" RibbonStyle="Office2010"> <dxr:RibbonControl

Naver Blog

[WPF_DevExpress] RibbonPageGroup

리본 페이지 그룹은 리본 페이지 내의 BarItem(일반 및 체크 버튼, 하위 메뉴, 편집기 등) 그룹이다. 그룹은 공통된 특정 기능을 가진 명령을 결합하는 데 사용된다. 리본 페이지 그룹은 RibbonPageGroup으로 표시된다. 페이지에 페이지 그룹을 추가하려면 RibbonPage.Groups 컬렉션에 RibbonPageGroup 객체를 추가하면 된다. XAML에서는 RibbonPage 시작 태그와 끝 태그 사이에 직접 그룹을 정의할 수 있다. 위 이미지는 Home 리본 페이지에 Clipboard, Font, Paragraph, Editing 4개의 리본 페이지 그룹을 가지고 있다. XAML에는 다음과 같이 작성되어 있을 것이다. <dxr:RibbonPage Caption="Home"> <dxr:RibbonPageGroup Caption="Clipboard"> <!--...--> </dxr:RibbonPageGroup> <dxr:RibbonPageGroup Caption="Fo

Naver Blog

[WPF_DevExpress] RibbonPage

리본 페이지는 탭으로 표시되며 다양한 명령, 정적 항목, 편집기 및 갤러리를 표시하는 그룹으로 구조적 및 시각적으로 분할된다. 리본 페이지는 기본 또는 사용자 정의 페이지 카테고리에 속한다. 기본 페이지 카테고리에 속하는 리본 페이지는 RibbonControl의 왼쪽 가장자리에 표시된다. 리본 페이지 설정 리본 페이지는 RibbonPage 클래스 객체로 표시된다. 각 페이지에 대해 해당 탭에 표시될 캡션은 RibbonPage.Caption 속성으로 지정한다. 리본 페이지 카테고리에 리본 페이지를 추가하기 위해서는 RibbonPageCategoryBase.Pages 컬렉션에 추가하면 된다. XAML에서는 RibbonDefaultPageCategory 또는 RibbonPageCategory의 시작 태그와 끝 태그 사이에 직접 추가할 수 있다. 위의 이미지처럼 RibbonDefaultPageCategory에 Home, Settings 페이지를 추가하여 보자. <dxr:RibbonDefau

Naver Blog

[WPF_DevExpress] RibbonPageCategory 및 Contextual Page

리본 컨트롤은 리본 페이지를 소유하는 페이지 카테고리(Default 또는 Custom 카테고리)로 구성된다. 기본 카테고리에 속하는 페이지는 리본 응용 프로그램의 기본 페이지로 간주되는 반면 사용자 정의 카테고리에 속하는 페이지는 컨텍스트 세부 정보를 제공해야 한다. Microsoft Office UI에서와 같이 사용자 정의 카테고리를 사용하여 상황별 페이지(Contextual Page)를 구현한다. 기본 페이지 범주 RibbonControl에는 항상 RibbonDefaultPageCategory 클래스로 표시되는 단일 카테고리가 포함되어야 한다. 사용자 정의 카테고리와 달리 기본 카테고리의 캡션은 화면에 표시되지 않는다. 기본 카테고리에 속하는 페이지는 컨텍스트에 독립적인 기본 탭으로 생각할 수 있다. 필요할 때 기본 페이지를 일시적으로 숨길 수 있지만 대부분의 경우 응용 프로그램이 실행되는 동안 영구적으로 표시되도록 설계되었다. 기본 카테고리를 정의하려면 RibbonDefault

Naver Blog

[WPF_DevExpress] RibbonControl

RibbonControl은 기존 툴바와 메뉴를 탭 페이지로 대체하기 위해 설계된 리본 UI의 주요 부분이다. 각 페이지에는 하나 또는 여러 그룹으로 결합된 다양한 요소(버튼, 하위 메뉴, 내부 편집기, 갤러리 등)가 포함되어 있다. RibbonControl 통합을 위한 ThemedWindow 일반적으로 창 상단에 RibbonControl을 배치한다. 일반 Window 클래스 대신 RibbonControl과 통합을 지원하는 ThemedWindow를 사용하는 것이 좋다. WindowKind 속성에 "Ribbon"으로 지정하여 RibbonControl과 통합한다. <dx:ThemedWindow x:Class="Example.MainWindow" ... xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core" WindowKind="Ribbon"> RibbonControl 요소 시각적으로 리본 컨트롤은 다음 영역으로 구성된다. 명령 영역

Naver Blog

[WPF_DevExpress] Ribbon 시작하기

디자인 타임에 RibbonControl을 커스터마이징하는 방법을 배워보자. ThemedWindow에 RibbonControl 추가 Visual Studio 도구 상자에서 DX.18.2: Navigation & Layout 탭에 있는 RibbonControl을 ThemedWindow에 추가한다. <dx:ThemedWindow xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core" xmlns:dxr="http://schemas.devexpress.com/winfx/2008/xaml/ribbon" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="RibbonStudy.MainWindow" Title="MainWindow" Height="350" Width

Naver Blog

[WPF_DevExpress] Ribbon, Bar, Menu 공통 개념 03. MVVM 지원

View 수준에서 UI 정의 UI가 VIew 수준에서 정의되는 가장 간단한 접근 방식이다. UI 요소 동작은 ViewModel에 정의된 명령으로 구현된다. 아래의 예제는 버튼이 있는 MainMenuControl로 구성된 간단한 UI이다. 버튼을 클릭하면 바인딩된 POCO ViewModel에 정의된 ShowTextCommand가 호출된다. MainWindow.xaml <dx:ThemedWindow x:Class="RibbonBarMenuMVVMStudy.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:dxb="http://schemas.devexpress.com/winfx/2008/xaml/bars" xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core" xmlns:dxe="http://schemas.devexpress.com/w

Naver Blog

[WPF_DevExpress] Ribbon, Bar, Menu 공통 개념 02. Glyph(아이콘)

글리프 지정하기 막대 항목(Bar Item)에 글리프를 지정하려면 BarItem.Glyph 및 BarItem.LargeGlyph 속성을 사용한다. 글리프 지정 결과는 사용 가능한 공간에 따라 다르다. xmlns:dxb="http://schemas.devexpress.com/winfx/2008/xaml/bars" xmlns:dxc="http://schemas.devexpress.com/winfx/2008/xaml/core" <dxb:ToolBarControl> <dxb:BarButtonItem Name="itemCut" Content="Cut" Glyph="{dxc:DXImage Image=Cut_16x16.png}" LargeGlyph="{dxc:DXImage Image=Cut_32x32.png}"/> <dxb:BarButtonItem Name="itemCopy" Content="Copy" Glyph="{dxc:DXImage Image=Copy_16x16.png}" LargeGlyp

Naver Blog

[WPF_DevExpress] Ribbon, Bar, Menu 공통 개념 01. 항목 및 링크

막대 항목(BarItems)과 막대 항목 링크(BarItemLinks)는 Ribbon, Bar, Menu의 내용을 나타내는 객체이다. 툴바를 구성하는 다양한 BarItem 막대 항목은 BarItem 클래스의 하위 항목으로 버튼, 편집기, 정적 텍스트, 리본 갤러리, 항목 컨테이너를 나타낼 수 있다. 막대 항목 링크는 다른 위치에 정의된 막대 항목을 나타낸다. 아래의 예제에서는 툴바에 정의된 Paste BarButtonItem을 보여주고, Edit 메뉴에는 툴바의 Paste 버튼을 참조하는 BarButtonItemLink를 보여준다. <DockPanel> <dxb:MainMenuControl Caption="Main Menu" DockPanel.Dock="Top"> <!-- "Edit" 메뉴 --> <dxb:BarSubItem Name="bsEdit" Content="Edit"> <!-- BarButtonItemLink는 툴바 아이템(bPaste)를 참조한다 --> <dxb:BarBu

Naver Blog

[WPF_DevExpress] Ribbon, Bar, Menu

DevExpress 구성 요소 중 리본, 툴바, 메뉴에 대해 알아보자. 이러한 구성 요소는 도구 상자의 DX.18.2:Navigation & Layout 탭에서 사용할 수 있다. 리본, 툴바, 메뉴 탭 툴바 DevExpress Bars는 응용 프로그램 명령 영역을 구성하는 전통적인 방법인 기존 도구 모음을 구현한다. 응용 프로그램 개발의 역사 동안 사용된 도구 모음은 사용자에게 가장 직관적인 응용 프로그램 메뉴 유형으로 남아있다. WPF용 DevExpress Bars는 다음과 같은 기능을 제공한다. 단일 양식 내에서 함께 사용할 수 있는 세 가지 표시줄 유형 : 기본 메뉴 표시줄, 일반 도구 모음 및 상태 표시줄, 각 유형에 대해 해당 독립형 막대 컨트롤 전체 도구 모음 시스템에 대한 중앙 집중식 액세스를 제공하는 Bar Manager 구성 요소 사용자가 필요에 따라 런타임에 도구 모음과 메뉴를 사용자 정의할 수 있는 런타임 사용자 정의 다중 문서 인터페이스(MDI)에서 하위 문서에

Naver Blog

[WPF_DevExpress] Behavior 04.KeyToCommand

KeyToCommand 클래스는 KeyGesture를 명령에 바인딩 할 수 있는 Behavior이다 컨트롤의 키 제스처를 처리해야 하는 요구사항이 있다고 가정하자. 예를 들어 포커스가 TextBox에 있는 동안 사용자가 Enter 키를 누르면 ViewModel의 CommitCommand를 호출해야 한다고 했을 때 KeyToCommand를 사용하여 처리할 수 있다. KeyToCommand 동작을 TextBox의 dxmvvm:Interaction.Behaviors 컬렉션에 추가한다. KeyToCommand.KeyGesture 속성에 처리해야 하는 키 제스처를 지정하고, EventToCommandBase.Command 속성에 명령을 바인딩 한다. MainWindow.xaml <dx:ThemedWindow xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:dx="http://schemas.devexpress.co

1 2 3 4 5