블로그 이미지
Every unexpected event is a path to learning for you.

카테고리

분류 전체보기 (2737)
Unity3D (817)
Programming (474)
Python (8)
TinyXML (5)
STL (13)
D3D (3)
MFC (1)
C/C++ (54)
C++/CLI (45)
C# (250)
WinForm (6)
WPF (5)
Math (10)
A.I. (1)
Win32API (11)
Algorithm (3)
Design Pattern (7)
UML (1)
MaxScript (1)
FMOD (4)
FX Studio (1)
Lua (2)
Terrain (1)
Shader (3)
boost (2)
Xml (2)
JSON (4)
Etc (11)
Monad (1)
Html5 (4)
Qt (1)
Houdini (0)
Regex (10)
Server (33)
Unreal (4)
Gamebryo (56)
Tip & Tech (228)
협업 (58)
3DS Max (3)
Game (12)
Utility (136)
Etc (96)
Link (32)
Portfolio (19)
Subject (90)
iOS,OSX (53)
Android (14)
Linux (5)
잉여 프로젝트 (2)
게임이야기 (3)
Memories (20)
Interest (38)
Thinking (38)
한글 (30)
PaperCraft (5)
Animation (408)
Wallpaper (2)
재테크 (18)
Exercise (3)
나만의 맛집 (3)
냥이 (10)
육아 (16)
Total
Today
Yesterday
04-20 00:00

문자열이 지정한 숫자 형식의 유효한 표현인지 확인하려면 모든 기본 숫자 형식에서 구현되며 DateTime 및 IPAddress 같은 형식에서도 구현되는 정적 TryParse 메서드를 사용합니다. 다음 예제에서는 "108"이 유효한 int인지 확인하는 방법을 보여 줍니다.

  int i = 0; 
  string s = "108";
  bool result = int.TryParse(s, out i); //i now = 108

문자열에 비숫자 문자가 포함되어 있는 경우 또는 숫자 값이 지정한 특정 형식에 비해 너무 크거나 너무 작은 경우 TryParse는 false를 반환하고 out 매개 변수를 0으로 설정합니다. 그렇지 않으면 true를 반환하고 out 매개 변수를 문자열의 숫자 값으로 설정합니다.

참고참고

문자열은 숫자만 포함할 수 있으며 사용할 TryParse 메서드 형식에 아직 유효하지 않을 수 있습니다. 예를 들어 "256"은 byte에 대해서는 유효한 값이 아니지만int에 대해서는 유효한 값입니다. 이때 98.6"은 int에 대해 유효한 값이 아니지만 decimal에 대해서는 유효한 값입니다.

다음 예제에서는 longbyte 및 decimal 값의 문자열 표현을 사용하여 TryParse를 사용하는 방법을 보여 줍니다.

string numString = "1287543"; //"1287543.0" will return false for a long
long number1 = 0;
bool canConvert = long.TryParse(numString, out number1);
if (canConvert == true)
  Console.WriteLine("number1 now = {0}", number1);
else
  Console.WriteLine("numString is not a valid long");

byte number2 = 0;
numString = "255"; // A value of 256 will return false
canConvert = byte.TryParse(numString, out number2);
if (canConvert == true)
  Console.WriteLine("number2 now = {0}", number2);
else
  Console.WriteLine("numString is not a valid byte");

decimal number3 = 0;
numString = "27.3"; //"27" is also a valid decimal
canConvert = decimal.TryParse(numString, out number3);
if (canConvert == true)
  Console.WriteLine("number3 now = {0}", number3);
else
  Console.WriteLine("number3 is not a valid decimal");            


또한 기본 숫자 형식에서는 문자열이 유효한 숫자가 아닌 경우 예외를 throw하는 정적 메서드 Parse를 구현합니다. 숫자가 유효하지 않은 경우 false를 반환하기 때문에 일반적으로 TryParse를 사용하는 것이 더 효과적입니다.

TryParse 또는 Parse를 사용하여 텍스트 상자와 콤보 상자 등의 컨트롤로부터 항상 사용자 입력의 유효성을 검사합니다.



출처 :  http://msdn.microsoft.com/ko-kr/library/bb384043.aspx
반응형

'Programming > C#' 카테고리의 다른 글

MeasureString(문자열 길이 체크)  (0) 2012.01.17
Convert String To Enum Instance  (0) 2011.12.16
Operator Overloading in C#  (2) 2011.12.05
Force property update in propertygrid  (0) 2011.11.29
is 비교 연산자, as 연산자  (0) 2011.11.29
Posted by blueasa
, |

Description

The Source code below shows how to use OperatorOverloading in C#. Operator Overloading is pretty useful concept derived from C++ by C#.For eg.

We can have class Matrix which hold 2D array of elements.C# add doest not Allows us to do Addition, Subtraction of matrices using the +,- operator rather We use to write Methods AddMatrix(),SubMatrix() with the use of Operator.

Overloading we make the user to code it: 

M3=M1+M2 where M1 and M2 are matrix objects. 

Some Tips while using Operator overloading: 

  1. While OverLoading a Operator always give public static access specifiers. 

  2. Operator Overloading should return a CLS type and not void. 

  3. Atleast one operand to the operator must be of type UDC [User Defined Class] because we cannot overload a operator with two int operands and perform subtraction for + operator which C# does not allow. 

  4. Relational Operators are overloaded in Pairs only.ie if == is overloaded then So !=. 

  5. Same Operator can be overloaded with different function signature for eg. 
    public static Matrix operator +(Matrix m1,int[,] m2) 



    we can also one more method like this: 
    public static Matrix operator + (Matrix m1,Matrix m2)



    Please find to the code which uses overloading of almost all operators. 

Source Code: 

// Source Code starts
using System; 
class Square
{
private double Side;
//public Constructor if int is passed convert to double and assign to Side
public Square(int s)
{
Console.WriteLine(".ctor with int argument");
Side=(
double)s;

//OverLoaded constructor with double argument
public Square(double s)
{
Console.WriteLine(".ctor with double argument");
Side=s;

//override ToString() method of object class.
public override string ToString()
{
Console.WriteLine("Override object class's string");
return this.Side.ToString();

//Overloading + operator to add 2 square objects and return new square object
public static Square operator + (Square x,Square y)
{
Console.WriteLine("Overloading + with Square,Square");
return new Square(x.Side+y.Side);

//Overloading + operator to add square objects with double side and return new square object
public static Square operator + (Square x,double y)
{
Console.WriteLine("Overloading + with Square,double");
return new Square(x.Side+y);

//Overloading + operator to add square objects with int side and return new square object
//This is not necessary since C# automatically calls +(Square,double)
public static Square operator + (Square x,int y)
{
Console.WriteLine("Overloading + with Square,int");
return x +(double)y;

public static implicit operator Square(double s)
{
Console.WriteLine("Overloading = for Square s5=1.5 assignment");
return new Square(s);

public static implicit operator Square(int s)
{
Console.WriteLine("Overloading = for Square s5=10 assignment");
return new Square((double)s);

//OverLoading == operator
public static bool operator ==(Square x,Square y)
{
Console.WriteLine("Overloading == with Square,Square");
return x.Side==y.Side;
}
//OverLoading != operator
public static bool operator !=(Square x,Square y)
{
Console.WriteLine("Overloading != with Square,Square");
return !(x==y); //This will call to operator == simple way to implement !=

//Always override GetHashCode(),Equals when overloading ==
public override bool Equals(object o)
{
return this==(Square)o;

public override int GetHashCode()
{
return (int)Side;

//OverLoading > operator
public static bool operator >(Square x,Square y)
{
Console.WriteLine("Overloading > with Square,Square");
return x.Side>y.Side;

//OverLoading < operator
public static bool operator <(Square x,Square y)
{
Console.WriteLine("Overloading < with Square,Square");
return x.Side<y.Side;

//OverLoading <= operator
public static bool operator <=(Square x,Square y)
{
Console.WriteLine("Overloading <= with Square,Square");
return (x<y) || (x==y); //Calls to operator == and <

//OverLoading >= operator
public static bool operator >=(Square x,Square y)
{
Console.WriteLine("Overloading >= with Square,Square");
return (x>y) || (x==y); //Calls to operator == and >

//Readonly Property
public double Area
{
get
{
return 2*Side;
}

public static void Main()
{
Square s1=
new Square(10);
Square s2=
new Square(20);
Square s3=s1+s2; 
// This will call operator + (Square,Square)
Console.WriteLine(s3);
Console.WriteLine(s3+15); 
// This will call operator + (Square,int) and then ToString()
Console.WriteLine(s3+1.5);// This will call operator + (Square,double) and then ToString()
s3=10; // This will call operator Square(int)
Console.WriteLine(s3);
Square s4=10;
Console.WriteLine(s1==s4); 
//Calls == operator
Console.WriteLine(s1!=s4); //Calls != operator
Console.WriteLine(s1>s2); //Calls > operator
Console.WriteLine(s1<=s4); //Calls <= operator
}
}
// Source Code End


출처 : http://www.c-sharpcorner.com/UploadFile/prasadh/OperatorOverloading11142005003229AM/OperatorOverloading.aspx
반응형

'Programming > C#' 카테고리의 다른 글

Convert String To Enum Instance  (0) 2011.12.16
문자열이 숫자 값을 나타내는지 확인  (0) 2011.12.16
Force property update in propertygrid  (0) 2011.11.29
is 비교 연산자, as 연산자  (0) 2011.11.29
effective c# - 1  (0) 2011.11.29
Posted by blueasa
, |
특정 이벤트에서 변경 이벤트가 발생할 때,
propertyGrid1.Refresh();
실행

테스트를 해 본 바로는 PropertyValueChanged Event가 적당함.

출처 : Mine 



I know this is an OLD thread, but for the next person looking for a response this works quite well for me:

Expand|Select|Wrap|Line Numbers
  1. object Temp = propertyGrid1.SelectedObject;
  2.                 propertyGrid1.SelectedObject = null;
  3.                 propertyGrid1.SelectedObject = Temp;
Feb 26 '10 #4


출처 : http://bytes.com/topic/c-sharp/answers/436382-force-property-update-propertygrid
반응형

'Programming > C#' 카테고리의 다른 글

문자열이 숫자 값을 나타내는지 확인  (0) 2011.12.16
Operator Overloading in C#  (2) 2011.12.05
is 비교 연산자, as 연산자  (0) 2011.11.29
effective c# - 1  (0) 2011.11.29
TreeNode Visual C# 도구 설명을 추가하는 방법  (0) 2011.11.21
Posted by blueasa
, |

 is 연산자 : 두 객체가 동일한지 비교하는데 사용, is 연산자는 해당 객체가 is 오른쪽 형식과 호환되는지 확인만 한다. 객체 형식을 변경할 수 는 없다.

  1. char data = 'a';
  2. if(data is char)
  3. System.Console.WriteLine("문자 데이터 입니다.");
  4. else
  5. System.Console.WriteLine("문자 데이터가 아닙니다.");

 

 

as 연산자 : 객체가 호환되지 않으면 null 값을 할당, 호환되면 형식(casting)을 시켜준다. as 연산자는 강제 형변환과 비슷하며 변환시 예외가 발생하면 null을 채운다.

[표현식] as [데이터타입]

 

  1. string obj = data as string;
    if(obj != null)
    {
     ....
    }

 

아래의 형태는 as 연산자가 하는 기능이다.

[표현식] is [데이터타입] ? (데이터타입)[표현식] : (데이터타입) null

 

출처 : http://ocplay.springnote.com/pages/2731066 

반응형

'Programming > C#' 카테고리의 다른 글

Operator Overloading in C#  (2) 2011.12.05
Force property update in propertygrid  (0) 2011.11.29
effective c# - 1  (0) 2011.11.29
TreeNode Visual C# 도구 설명을 추가하는 방법  (0) 2011.11.21
TreeView에서 Find 함수 사용 방법  (0) 2011.11.20
Posted by blueasa
, |

effective c# - 1

Programming/C# / 2011. 11. 29. 10:56

C# 코드를 짤 때 좀 더 효율적인 코드를 짜기 위한 방법들을 정리한 포스트이다.
먼저 Code Project의 아래 포스트를 번역한 후 다른 글들도 한번 찾아 봐야겠다.

원본 : http://www.codeproject.com/KB/cs/effectivecspart1.aspx#item1

포스팅한 날짜가 2005년꺼라 꽤 오래된 자료라 현재 버전에서는 어느정도 차이가 있을듯하다.




Item 1 - String의 사이즈를 체크할때는 Length Property를 사용하라.[Performance]

String 비교는 불필요한 overhead를 포함하고 있다. 스트링이 비어 있는지를 체크하는 것이라면

Length properthy를 사용하도록 한다.

 
//NO

if ( str != "")//comparison of two strings {...}

//YES

if ( str.Length > 0) {...}

 

Item 2 - String을 연속적으로 붙일 때에는 StringBuilder 객체를 사용하라.[Performance]

C# string은 변경되지 않는다. string 값이 변경할 때, 아래와 같은 문제들이 야기된다.

  • 필요한양보다 메모리를 추가적으로 더 사용하게 된다.
  • garbage collector가 작업해야 될 일들이 더 생긴다.
  • 실행시 느려지는 코드를 만들게 된다.
 
//NO

String strConcat;
ArrayList arrayOfStrings = new ArrayList();
arrayOfStrings.Add("a"); 
arrayOfStrings.Add("b");
foreach (string s in stringContainer) {
  strConcat += s; 
}

//YES

StringBuilder sbConcat = new StringBuilder ();
foreach (string s in arrayOfStrings ) { 
  sbConcat.append(s);
}

 

Item 3 - 되도록이면 Boxing과 UnBoxing을 피하라[Performance]

BBoxing은 garbage-collected 힙 영역에 value types들을 저장하는데 이용된다.

value type이 box되면 새로운 ojbect가 메모리에 잡히고 생성되어야 한다.

즉, 아래의 두가지 작업이 일어난다.

  - Object 인스턴스를 할당한다.

  - 위 인스턴스에 value type 값을 복사해서 넣는다.

위의 이유로 되도록이면 Boxing을 피하는것이 좋다. ArrayList를 예로 들어보면 struct 키워드를

통해서 ArrayList의 값을 넣을 때 위와 같은 Boxing과 UnBoxing이 일어나게 된다.

 
//NO

struct st { public Int i; }
Arraylist arr = new ArrayList();
for (int i=0 ; i< count; i++) { 
  st s;
  s.i = 4; 
  arr.item.add(st) ; //<- Boxing (Allocating an object instance

                     // + copying the value-type value into that instance)

}
st obj = (st ) arr[0]; //<- Unboxing (casting and copy)


//YES

//Decalre the data type as class.

Class st { public Int i; }

 

Item4 - == 대신 Equal 함수를 사용하라 [Performance]

== 보다 equal 함수를 사용하는것이 좀 더 빠르다.

 

 
string s1= "code";
string s2 = "code1";
//No:

if(s1 == s2){...}
//Yes:

if(s1.Equals(s2)){...}


Item5 - 'foreach' 말고 'for' 를 사용해야 하는 케이스  . [Performance]

'foreach' 랑 'for'  키워드는 일부 비슷한 기능을 한다. - 블록 안에서 루프를 돌면서 기능을 수행

foreach와 for를 사용할때 가장 중요한 차이쯤은 루프문의 증가와 끝에 대해서 따로 작업이 필요 없다는것이다.  또한 foreach는 모든 collection을 사용할 수 있게 만들어졌다. foreach는for의 private한 case에 사용한다고 하기도 한다.

아래 코드를 통해서,  두 루프문이 동일한 결과를 낸다는것을 알 수 있다. 다만 foreach를 사용했을 경우퍼포먼스가 조금 떨어졌다. 좀더 무거운 변수와 큰 array를 사용하면 그 차이가 더 크게 날것이다.

foreach는 for에 비해서 좀더  사용하기 쉽지만 만약 큰 collection을 도는 경우는에는 'for' 를 사용하는것이 퍼포먼스에 좋을 것이다.


Code snippets:

 Collapse
//foreach

int[] arrayOfInts= new int[5];
int sum= 0; 
foreach(int i arrayOfInts) {
  sum+= i; 
}

//for

int[] arrayOfInts= new int[1]; 
int sum= 0;
for(int i = 0; i < arrayOfInts.Length; i++) {
  sum+= arrayOfInts[i]; 
}

Item7 - Prefer the �as� operator instead of direct type casting. [Usage]

The 'as' operator does not throw an exception. In case of bad cast, the return value is null.

Code snippets:

 Collapse
//NO

object o = 1.3; 
try
{
  string str = (string)o; 
} 
catch(InvalidCastException ex){...}

//YES

string str = o as string;
if(null != str){...}

Item8 - Use the 'checked' keyword to avoid overflow. [Usage]

Code snippets:

 Collapse
//NO

short shortNum;
int i = 32768;
shortNum = (short) i; 
// problem after statment excution

// the shortNum variable has an uninitialized value,


//YES

try {
  shortNum = checked((short)i); // solution 

}
catch(OverflowException efx) {}

Item9 - Use the 'is' operator instead of casting. [Usage]

Code snippets:

 Collapse
public class Preson{int nAge;}

//No:

static void main(object o){
  try {
    (Person)o.nAge = 45;
  }
  catch(InvalidCastException ex){...}
}

//Yes:

static void func(object o)
{
  if ( true == (o is Person) )
  {
    (Person)o.nAge = 45;
  }
}

Item10 - Use Explicit interface to 'hide' the implementation of an interface [Usage]

Implementing an interface explicitly 'hides' the interface methods. Visual Studio does not display the interface methods in the intellisense.

Code snippets:

 Collapse
//interface definition

Public interface IChild{
  bool IsHuman();
  void lie();
}

//class definition

Pubic Pinocchio: IChild {
  IChild.IsHuman() //explicit interface implementation

  {
  }
  public void Lie(); //regular interface implementation

}

//using the object

static void main()
{
  // Visual studio will not display

  // the isHuman mwthod in the intellisence.

  Pinocchio o = new Pinocchio();
  ((IChild) o).IsHuman(); // using the IsHuman method explicitly.

  o.Lie();
}

Item11 - Use @ to ease the work with literal paths. [Usage]

Code snippets:

 Collapse
//Old way

String sFilePath = �c:\\a\\b\\c.txt�;

//The C# way

String sFilePath = @�c:\a\b\c.txt�;

Item12 - Make your API assembly CLS Compliant. [Usage]

The CLS-Compliant attribute cause the compiler to check whether your public exposed types in the assembly are CLS-Compliant.

Prefer to define the attribute for the entire assembly, especially for API. The incentive to create a CLS compliant assembly is that any assembly written in one of the .NET aware languages can use your assembly more efficiently because there is no data types interoperability.

Code snippets:

 Collapse
using System; 
[assembly:CLSCompliant(true)]

Item13 - Define destructor and implement IDisposable interface for classes that use native resource directly. [Garbage Collection]

You should define a destructor whenever you use native code in your assembly, i.e., use types that are not managed by the garbage collector. The compiler changes the destructor method to Finalize method (can be seen in the MSIL using the ILDasm.exe).

The Garbage collector marks a class with destructor as Finalized and calls the Finalize method while destructing the object. This behavior guarantees that your release of resources in the destructor will occur.

But, what if you want to release the resources immediately? For this purpose, you should implement the IDisposable interface and call theDispose method when you want to release the object.

Note 1: Do not use destructor if your class does not use native / unmanaged resources. If you do so, you create unnecessary work for the garbage collector.

Note 2: If you implement the IDisposable and a destructor, you should call the Dispose method from the destructor to force the object to release resources immediately.

Code snippets:

 Collapse
~my class {
  if ( true == b) { 
  }
} 

//The MSIL code:

protected override void Finalize() {
  try { 
    if ( true == b) { 
    }
  }finally { base.Finalize();} 
}

Item14 - Avoid the use of GC.Collect. [Garbage Collection]

The GC.Collect method forces garbage collection of all generations.

The performance is hurt during the call to GC.Collect, the application execution is paused. Moreover, the method might cause the promotion of short lived objects to a higher generation, i.e., those object live longer than it should in the first place.

If you must use it in order to reclaim the maximum amount of available memory, use the method only on generation 0.

Code snippets:

 Collapse
//No:

GO.Collect();
//Yes:

GC.Collect(0);

Item15 - Use StructLayout attribute for classes and structs when using COM Interop. [COM Interop]

The attributes cause the compiler to pack the structure in sequential memory so that it can be sent to unmanaged code correctly (unmanaged code that expects a specific layout).

Code snippets:

 Collapse
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)] 
public struct st{
  int i;
  float f;
}

What next?

The part II article, will deal with COM Interop in general, and events between managed and unmanaged code in particular.


출처 : http://www.cyworld.com/mengwi/7680825 

반응형
Posted by blueasa
, |
이 문서에서는 TreeView 컨트롤 노드의 설명을 추가하는 방법에 대해 설명합니다. 도구 설명 위에 마우스 포인터를 일시 TreeNode에 대한 정보를 표시합니다. TreeView 컨트롤의 ToolTip 속성이 없지만 도구 설명 컨트롤의 도구 설명 기능을 제공할 수 있습니다.

이 문서에 설명되어 있는 예제를 사용하여 요일을 표시하는 TreeView 컨트롤을 사용하여 보여 줍니다. 마우스 포인터가 있는 TreeNodes 중 하나 위에 멈추면 주의 요일을 나타내는 도구 설명이 나타납니다.

요구 사항

다음은 권장되는 하드웨어, 소프트웨어, 네트워크 인프라 및 필요한 서비스 팩의 목록입니다.
  • Microsoft Visual Studio .NET 또는 Microsoft Visual Studio 2005
이 문서에서는 사용자가 다음 항목을 잘 알고 있다고 가정합니다.
  • Visual C# 구문
  • Windows 폼

만들기 및 예제 양식 채우기

  1. Visual C# 에서 새 Windows 프로그램을 만듭니다.
  2. TreeView 컨트롤을 Form1에 추가하십시오.
  3. ToolTip 컨트롤을 Form1에 추가하십시오.

도구 설명을 위해 TreeNodes 추가

  1. Form1 로드 이벤트에 다음 코드를 붙여 넣습니다.
    // Create a root node.
    TreeNode rootNode = treeView1.Nodes.Add("Day of Week");
    
    // Create a series of child nodes and then set the Tag property for each.
    for (int count = 0; count <= 6; count++)
    {
       DayOfWeek day = (DayOfWeek)count;
       TreeNode childNode = rootNode.Nodes.Add(day.ToString());
       childNode.Tag = "This day is " + day.ToString() + ".";
    }
    
    // Expand all of the TreeView nodes.
    rootNode.ExpandAll();
    					
  2. TreeView MouseMove 이벤트에 다음 코드를 붙여 넣습니다.
    // Get the node at the current mouse pointer location.
    TreeNode theNode =  this.treeView1.GetNodeAt(e.X, e.Y);
    
    // Set a ToolTip only if the mouse pointer is actually paused on a node.
    if ((theNode != null))
    {
       // Verify that the tag property is not "null".
       if (theNode.Tag != null)
       {
          // Change the ToolTip only if the pointer moved to a new node.
          if (theNode.Tag.ToString()!=this.toolTip1.GetToolTip(this.treeView1))
          {
             this.toolTip1.SetToolTip(this.treeView1, theNode.Tag.ToString());
          }
       }     
       else
       {
          this.toolTip1.SetToolTip(this.treeView1, "");
       }
    }
    else     // Pointer is not over a node so clear the ToolTip.
    {
       this.toolTip1.SetToolTip(this.treeView1, "");
    }
    					
    노트 해당 코드는 Visual Studio 2005에서 변경해야 합니다. Windows Forms 프로젝트를 만들 때 Visual C# 한 폼을 프로젝트에 기본적으로 추가됩니다. 이 폼은 Form1을 이라고 합니다. 폼을 나타내는 두 파일의 Form1.cs 및 Form1.designer.cs가 지정됩니다. Form1.cs 있는 코드를 작성할 수 있습니다. Windows Forms 디자이너 도구 상자에서 컨트롤을 끌어서 의해 수행된 모든 작업을 구현하는 코드를 기록하는 위치 designer.cs 파일이 없습니다. Windows Forms 디자이너를 Visual C# 2005에 [NULL]에 대한 자세한 내용은 다음 Microsoft 웹 사이트를 방문하십시오.
  3. 저장하고 프로그램을 실행하십시오. 노드 중 하나에서 마우스 포인터를 잠시 두면 도구 설명이 나타납니다.


    출처 : http://support.microsoft.com/kb/322634/ko 
반응형

'Programming > C#' 카테고리의 다른 글

is 비교 연산자, as 연산자  (0) 2011.11.29
effective c# - 1  (0) 2011.11.29
TreeView에서 Find 함수 사용 방법  (0) 2011.11.20
C# C++ COM Interop  (0) 2011.11.15
C#에서 포인터  (0) 2011.11.15
Posted by blueasa
, |

[참조]


위에 보면 Find 함수를 쓴다.
[예: treeNode.Nodes.Find(string key, bool searchAllChildren)]

그런데 직접 만들고 써보니 찾지를 못한다..
[처음 삽질한 방법]
TreeNode.Nodes.Add("AAA");
TreeNode[] arrayTN = TreeNode.Nodes.Find("AAA", false);

뭘까..하고 이리저리 찾아보다보니..

TreeNode.Nodes.Add() 함수는 몇가지 오버로딩 함수를 가지는 데,

그 중,
1) TreeNode.Nodes.Add(string text);
2) TreeNode.Nodes.Add(string key, string text); 
두가지 함수의 차이에 대해 알아야 될 것 같다.

첫 삽질에서 사용 한 함수는 1) 함수이다.

그런데 Find 함수의 첫 인자인 key는 Node의 Name이라고 위 참조글에 적혀 있다.
TreeNode.Nodes.Add("AAA"); 는 1) 함수에 보면 key(Name)가 아니라 text이다.
 그래서 Name엔 기본값인 빈 문장("")이 들어가 있다.
결과적으로 Find로 찾는 Name값은 빈문장이기 때문에 "AAA"를 찾을 수 없다.

Find를 쓰려면 Node를 Add할 때 2) 함수로 추가를 해줘야 한다.
어차피 Text와 Name이 다를 필요가 없을 것 같아서 같게 해줬다.

[해결방법]
TreeNode.Nodes.Add("AAA", "AAA");
TreeNode.Nodes.Find("AAA", false);

P.s. Find 후 TreeNode[] 변수가  반환 되는데, 찾은 노드의 개수 판단은 Count가 아니라 Length 프로퍼티이다.
      (
Length가 0이면 찾는 항목이 없음.)

P.s.2 bool 
searchAllChildren 은 하위레벨 노드를 검색할 지 판단 변수이다. false로 하면 같은 레벨 노드에서만 검색을 한다.
        나는 같은 레벨에서 검색이 필요하기 때문에 false를 했다.

반응형

'Programming > C#' 카테고리의 다른 글

effective c# - 1  (0) 2011.11.29
TreeNode Visual C# 도구 설명을 추가하는 방법  (0) 2011.11.21
C# C++ COM Interop  (0) 2011.11.15
C#에서 포인터  (0) 2011.11.15
TreeView 이용하기(추가/선택삭제/체크삭제)  (0) 2011.11.14
Posted by blueasa
, |

C# C++ COM Interop

Programming/C# / 2011. 11. 15. 14:38

관리되는 코드(C# or C++/CLI) 와 비관리되는 코드(C or C++)이 프로젝트에서 함께 사용되는 경우가 발생한다.
이때 사용되는 기술이 Interop 기술이다.

MSDN : 비관리 코드와의 상호운용

다음 두가지 경우를 생각해보자.

1. C++에서 C# 함수 호출


내용 보기


//-- C# Com Server ---------------------------------------------------------------------//

[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface ICOMClass
{
    void HelloWorld();
}

[ClassInterface(ClassInterfaceType.AutoDual)]
public class COMClass : ICOMClass
{
    ...

    public void HelloWorld()
    {
        MessageBox.Show("Hello");
    }
}

--> 이런 클래스가 있다면 클래스 라이브러리로 컴파일을 하고 C++에서 사용할수 있는 형식라이브러리 생성 및 등록       
      
     regasm COMClass.dll /regfile COMClass.reg
     regasm COMClass.dll /tlb:COMClass.tlb
     참고 : http://msdn.microsoft.com/ko-kr/library/tzat5yw6.aspx

//-- C++ Client -------------------------------------------------------------------------//

[[ Heaer ]]
/** #import attribute
 *        no_namespace : Specifies that the namespace name is not generated by the compiler.
 *        raw_interfaces_only : Suppresses the generation of error-handling wrapper functions and property (C++) declarations that use those wrapper functions
 *        named_guids : Tells the compiler to define and initialize GUID variables in old style, of the form LIBID_MyLibCLSID_MyCoClassIID_MyInterface, andDIID_MyDispInterface.
 **/
#import "COMClass.tlb" no_namespace raw_interfaces_only named_guids

[[ CPP ]]

HRESULT hr;
_COMClassPtr pClass;
hr = pClass->CoCreateInstance(CLSID_COMClass,NULL,CLSCTX_ALL,IID__COMClass,(void**)&pClass);
if(hr != S_OK) return;

ICOMClassPtr pIClass;
pClass->QueryInterface(IID_ICOMClass,(void**)&pIClass);
if(SUCCEEDED(hr))
    pClass->HelloWorld();

잘되었다면.. Hello 메시지 박스를 볼수 있을 것이다. 



2. C# 이벤트를 C++에서 받기

내용 보기


C#의 컨트롤에서 발생하는 이벤트를 C++에서 처리할 경우가 있다.
IDispEventSimpleImpl 를 이용하여 이벤트를 등록하는 방식을 알아보자.

[[ C# ]]
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    public interface _EventInterface
    {
        [DispId(1)]
        void ClickedEvent(int ID, bool selected);       
    }
    [ComSourceInterfaces(typeof(_EventInterface))]
    [ClassInterface(ClassInterfaceType.AutoDual)]
    public class VCGraphControl
    {
        [ComVisible(false)]
        public delegate void ClickedEvent(int ID, bool selected);
        public event ClickedEvent ClickEvent;

        // 이벤트발생시
        public function()
        { 
            if(ClickEvent!= null) ClickEvent();
        }
    }

[[ C++ - Header ]]
extern _ATL_FUNC_INFO OnClickEventInfo;
class CEventSink : public IDispEventSimpleImpl<1, CVCMapEventSink, &DIID__EventInterface>
{
    BEGIN_SINK_MAP(CEventSink )
        SINK_ENTRY_INFO(1,DIID__EventInterface, 1, OnClickEvent, &OnClickEventInfo)
    END_SINK_MAP()

    ...

public:
    void Start()
    {
        DispEventAdvise((IUnkown*) pClass);
    }
    void Stop();
    {
        DispEventUnadvise((IUnknown*) pClass);
    }

    void __stdcall OnClickEvent(int ID, bool selected);

private:
    _COMClassPtr pClass;
    CWnd* m_pTargetWnd;
}

[[ C++ - Cpp ]] 
_ATL_FUNC_INFO OnClickEventInfo= {CC_STDCALL, VT_EMPTY, 2, {VT_INT,VT_BOOL}};

void CEventSink::OnSelectedTeacher(int ID, bool selected)
{
    ...
}

/// main
void main()
{
    ...

    CEventSink  sink = new CEventSink(this);
    sink->Start();
    
    ...

    /// release
    sink->Stop();
    delete sink;    
    ...
}

이런식으로 구현하면 될것이다. 
참고 : http://msdn.microsoft.com/ko-kr/library/b91kf2t0(VS.80).aspx



ps. 여기까지 C#의 컨트롤을 가져와 C++에서 운용하는 VS2003으로 되어있는 프로젝트를 VS2008로 업그레이드 하면서 Interop에 대하여 정리하였다. 

    닷넷1.1에서 동작하던 함수들이 닷넷2.0으로 넘어오면서 발생된 문제.. 
    http://www.codeforum.net/blog/pitoosung/entry/Net-Framework-11-에서-Net-Framework-20-으로의-Migration-CollectionBase-문제#comment1328

    Custom Object를 닷넷2.0에서 직접 가져와 사용하는 부분이 닷넷2.0에서는 불가능해진것 같다.(확실하진 않음)
    Object를 가져오는 인터페이스와 Collection Enumerator를 사용하면서 가져오는 부분은 에러를 리턴한다. 
    그래서 C++은 C#의 인터페이스 함수만 참조하게 단순화 시켰다. 

    그리고 예제 코드는 클래스 이름과 인터페이스이름을 바꾸면서 적은 코드로 동작안할 가능성이 있음.. 참조만 하시길..^^;
    관련 예제 - http://msdn.microsoft.com/ko-kr/library/65t81w8a.aspx



출처 : http://icarosss.egloos.com/1999092#none
반응형
Posted by blueasa
, |

C#에서 포인터

Programming/C# / 2011. 11. 15. 14:18

Marshal.PtrToStructure 메서드 (IntPtr, Type)

.NET Framework 4

관리되지 않는 메모리 블록의 데이터를 지정된 형식의 새로 할당된 관리되는 개체로 마샬링합니다.

네임스페이스:  System.Runtime.InteropServices
어셈블리:  mscorlib(mscorlib.dll)
[ComVisibleAttribute(true)]
public static Object PtrToStructure(
	IntPtr ptr,
	Type structureType
)

매개 변수

ptr
형식: System.IntPtr
관리되지 않는 메모리 블록에 대한 포인터입니다.
structureType
형식: System.Type
만들 개체의 형식입니다. 이 개체는 서식이 지정된 클래스나 구조체를 나타내야 합니다. 

반환 값

형식: System.Object
ptr 매개 변수가 가리키는 데이터가 있는 관리되는 개체입니다.
예외상황
ArgumentException

structureType 매개 변수 레이아웃이 Sequential 또는 Explicit이 아닌 경우

또는

structureType 매개 변수가 제네릭 형식인 경우

ArgumentNullException

structureType는 Nothing입니다.

PtrToStructure는 주로 구조체 매개 변수를 System.IntPtr 값으로 나타낼 때 COM interop 및 플랫폼 호출에 필요합니다. 값 형식을 이 오버로드 메서드에 전달할 수 있습니다. 이 경우 반환된 개체는 boxing된 인스턴스입니다.

다음 예제에서는 관리되는 구조체를 만들고 이를 관리되지 않는 메모리로 전달한 다음 PtrToStructure 메서드를 사용하여 다시 관리되는 메모리로 전달합니다.

using System;
using System.Runtime.InteropServices;

public struct Point
{
    public int x;
    public int y;
}

class Example
{

    static void Main()
    {

        // Create a point struct.
        Point p;
        p.x = 1;
        p.y = 1;

        Console.WriteLine("The value of first point is " + p.x + " and " + p.y + ".");

        // Initialize unmanged memory to hold the struct.
        IntPtr pnt = Marshal.AllocHGlobal(Marshal.SizeOf(p));

        try
        {

            // Copy the struct to unmanaged memory.
            Marshal.StructureToPtr(p, pnt, false);

            // Create another point.
            Point anotherP;

            // Set this Point to the value of the 
            // Point in unmanaged memory. 
            anotherP = (Point)Marshal.PtrToStructure(pnt, typeof(Point));

            Console.WriteLine("The value of new point is " + anotherP.x + " and " + anotherP.y + ".");

        }
        finally
        {
            // Free the unmanaged memory.
            Marshal.FreeHGlobal(pnt);
        }



    }

}


다음 예제에서는 PtrToStructure 메서드를 사용하여 관리되지 않는 메모리 블록을 관리되는 구조체로 마샬링하는 방법을 보여 줍니다.

		[StructLayout(LayoutKind.Sequential)]

		public class  INNER

		{

			[MarshalAs(UnmanagedType.ByValTStr, SizeConst =  10)]

			public string field1 = "Test";

	 

		}	

		[StructLayout(LayoutKind.Sequential)]

		public struct OUTER

		{

			[MarshalAs(UnmanagedType.ByValTStr, SizeConst =  10)]

			public string field1;

			[MarshalAs(UnmanagedType.ByValArray, SizeConst =  100)]

			public byte[] inner;

		}





		[DllImport(@"SomeTestDLL.dll")]

		public static extern void CallTest( ref OUTER po);



		static void Main(string[] args)

		{

			OUTER ed = new OUTER();

			INNER[] inn=new INNER[10];

			INNER test = new INNER();

			int iStructSize = Marshal.SizeOf(test);



			int sz =inn.Length * iStructSize;

			ed.inner = new byte[sz];



			try

			{

				CallTest( ref ed);

			}

			catch(Exception e)

			{

				Console.WriteLine(e.Message);

			}

			IntPtr buffer = Marshal.AllocCoTaskMem(iStructSize*10);

			Marshal.Copy(ed.inner,0,buffer,iStructSize*10);

			

			int iCurOffset = 0;

			for(int i=0;i<10;i++)

			{

				

				inn[i] = (INNER)Marshal.PtrToStructure(new
IntPtr(buffer.ToInt32()+iCurOffset),typeof(INNER) );

				iCurOffset += iStructSize;

			}

			Console.WriteLine(ed.field1);

			Marshal.FreeCoTaskMem(buffer);

		}


.NET Framework

4, 3.5, 3.0, 2.0, 1.1, 1.0에서 지원

.NET Framework Client Profile

4, 3.5 SP1에서 지원
  • SecurityCriticalAttribute  

    직접 실행 호출자에 대한 완전 신뢰가 필요합니다. 이 멤버는 부분적으로 신뢰할 수 있거나 투명한 코드에서 사용할 수 없습니다.

Windows 7, Windows Vista SP1 이상, Windows XP SP3, Windows XP SP2 x64 버전, Windows Server 2008(Server Core는 지원되지 않음), Windows Server 2008 R2(Server Core는 SP1 이상에서 지원됨), Windows Server 2003 SP2

.NET Framework에서 모든 플랫폼의 전체 버전을 지원하지는 않습니다. 지원되는 버전의 목록을 보려면 .NET Framework 시스템 요구 사항을 참조하십시오.



반응형
Posted by blueasa
, |

전체 소스
     


특별히 설명이 필요 없을거 같습니다.





using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

 

namespace WATTreeView

{

    public partial class Form1 : Form

    {

        Random m_random = new Random(); // 랜덤인스턴스생성

        public Form1()

        {

            InitializeComponent();

        }

 

        private void Form1_Load(object senderEventArgs e)

        {

            treeView1.Nodes.Clear();

        }

 

        // 선택된노드에노드추가하기

        private void button1_Click(object senderEventArgs e)

        {

            TreeNode node = treeView1.SelectedNode;

            if (null == node)

                treeView1.Nodes.Add(m_random.Next(0, 100).ToString());

            else

            {

                node.Nodes.Add(m_random.Next(0, 100).ToString());

                node.Expand();

            }

        }

 

        // 선택노드삭제

        private void button2_Click(object senderEventArgs e)

        {

            TreeNode node = treeView1.SelectedNode;

            if (null != node)

            {

                node.Remove();

            }

        }

 

        // 체크된노드삭제

        private void btnDelCheck_Click(object senderEventArgs e)

        {

            foreach (TreeNode n in treeView1.Nodes)

            {

                if (n.Checkedn.Remove();

            }

        }

    }

}


출처 : 
http://pcsak3.com/48 

반응형

'Programming > C#' 카테고리의 다른 글

C# C++ COM Interop  (0) 2011.11.15
C#에서 포인터  (0) 2011.11.15
TreeView에서 Node 검색 및 카테고리 구현  (0) 2011.11.14
PropertyGrid 속성 값 가져오기(사용하기)  (0) 2011.11.02
PropertyGrid and Drop Down properties  (0) 2011.11.02
Posted by blueasa
, |