달력

42024  이전 다음

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

Configuring Context-Sensitive Custom Tabs MOC2007

How to configure custom content sensitive tabs in Microsoft Office Communicator MOC2007?

Well its very simple to do. For more indepth information see Communicator_2007_Deployment_Guide from pagr 14.

Setting up a custom tab requires:

  • A network-accessible custom tab definition file in XML format that gives the location of each tab’s main page and controls the information Communicator passes to this page.
  • A registry entry in the \Software\Policies\Microsoft\Communicator registry hive that gives the location of the tab definition file.

· A graphic in Portable Network Graphics (PNG) format for the tab. The graphic can be:

  • Up to 16 pixels high by 16 pixels wide, or
  • Exactly 32 pixels high by 32 pixels wide.

One or more Web pages for display in the Office Communicator window.

Step 1. Create a custom XML file to prepare your MOC2007 configuration:

Example:

<?xml version="1.0" ?> 
<tabdata>
<tab>
   <image>/.png">http://<COMPUTERNAME>/<IMAGE>.png</image>
   <name>Smoelenboek</name>
   <tooltip>Tooltip text</tooltip> 
   <contenturl> /">http://<WEBURL>/</contenturl>  
   <userid>true</userid>
   <contactid>true</contactid>
   <accessibility>inside</accessibility>
</tab>
</tabdata>

Step 2. Customize the registry in:

HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Communicator

The TabURL setting can be added to either section of the registry. However, settings in the hkey_local_machine\software section take precedence.

image

The HTML file containing the tab content must be in a trusted location on the network. The XML and PNG files can be stored in the same location as the HTML file, or on a network server or local machine. For example:

· file:///\\contonso-it\oc\tabs.xml

· file:///c:/myTab/tabs.xml

Example:

file:///c:/temp/customtab.xml

Step 3. Restart your MOC2007 client and there you go ;-)

image

Posted by tornado
|
http://www.velocityreviews.com/forums/t81512-htmltable-control-css-class.html


Default Re: HtmlTable control css class

Thanks Jeffrey, this works just fine. It is perhaps worth noting that
Attributes["class"] = "myCSSClass" uses C# syntax. VB is
Attributes("class") = "myCSSClass". This trips me up regularly - I much
prefer C# syntax, but am sometimes forced to use VB.

> Alfred,
> Any time you want to add any attribute that may not be included in the
> code, just use HtmlTable.Attributes["class"] = "myCSSClass";
> This will work for any attribute.
>
> Best regards,
> Jeffrey Palermo
>
> "Alfred Salton" <> wrote in message
> news:2004062721504216807%alfredsalton@hotmailcom.. .
>> Can anyone show me how to set the css class of an HtmlTable control in
>> code on the server?
>>
>> I can't find any indication that the css class is a property of the
>> HtmlTable, HtmlTableRow and HtmlTableCell classes. I'm getting the
>> uncomfortable feeling that this can't be done, even though it seems
>> incredible to me!

Posted by tornado
|
[펌] SQL Server Explorer 만들기;
[원글] http://blog.vuscode.com/malovicn/archive/2007/11/12/how-to-build-your-own-sql-server-explorer.aspx



.NET exploration, articles, cool links, surf logs, book reviews, .net, c#, smart clients, software factories, patterns & practices, web casts and much more

How to build your own SQL Server Explorer

Recently, I've started making in my free time my own little ORM tool, mainly as an fun way into exploration of the ADO .NET 2.0

Every  dissent ORM tool has to be based on DB object enumeration activities and I've noticed there are not a lot straight "how to" articles on net how to do various things (at least I had a hard time finding them), so I decided to make a simple blog post describing exactly those How-To's

How to enumerate visible SQL server instances

Enumerating visible instances of MS SQL Server can be performed by executing the GetDataSource() of the SqlDataSourceEnumerator type singleton instance.

GetDataSource returns four column data table with next columns:

  1. ServerName - Name of the server.
  2. InstanceName - Name of the server instance. Blank if the server is running as the default instance.
  3. IsClustered - Indicates whether the server is part of a cluster.
  4. Version - Version of the server (8.00.x for SQL Server 2000, and 9.00.x for SQL Server 2005).

Code example:

   1: public static IList<string> GetActiveServers()
   2: {
   3:     Collection<string> result = new Collection<string>();
   4:     SqlDataSourceEnumerator instanceEnumerator = SqlDataSourceEnumerator.Instance;
   5:     DataTable instancesTable = instanceEnumerator.GetDataSources();
   6:     foreach (DataRow row in instancesTable.Rows)
   7:     {
   8:         if (!string.IsNullOrEmpty(row["InstanceName"].ToString()))
   9:             result.Add(string.Format(@"{0}\{1}", row["ServerName"], row["InstanceName"]));
  10:         else
  11:             result.Add(row["ServerName"].ToString());
  12:     }
  13:     return result;
  14: }

How to enumerate databases of the given SQL server instance

Enumerating the databases of the given server can be performed by executing the GetSchema method of the SqlConnection instance with a SqlClientMetaDataCollectionNames.Databases string enumeration value passed to method.

Passing that enumeration or it's string equivalent ("Databases") is totally the same, except enumeration looks cooler :)

Code example:

   1: public static IList<string> GetDatabases(string serverName, string userId, string password,
   2:                                               bool windowsAuthentication)
   3:      {
   4:          Collection<string> result = new Collection<string>();
   5:          using (
   6:              SqlConnection connection =
   7:                  GetActiveConnection(serverName, string.Empty, userId, password, windowsAuthentication))
   8:          {
   9:              connection.Open();
  10:              DataTable dt = connection.GetSchema(SqlClientMetaDataCollectionNames.Databases);
  11:              foreach (DataRow row in dt.Rows)
  12:              {
  13:                  result.Add(string.Format("{0}", row[0]));
  14:              }
  15:          }
  16:          return result;
  17:      }

In line 6, we are using an instance of SqlConnection type created by GetActiveConnection method.

In line 10, we are calling GetSchema connection instance method which returns a data table with a single column which contains the name of the database

in ADO NET, methods used for retrieving schema information always are overloaded with a version accepting additional string array parameter which is used for passing the restrictions (you can think of it as a filter criteria) which ADO.NET should apply while retrieving resulting set.
Retrieving database schema in our example has only one restriction and that is database name so if we would write something like

   DataTable dt = connection.GetSchema("Databases", new string[] {"Northwind" });

Please notice in that that line that I used "Databases" and not enumeration and that I have passed single string array with "Nortwind" content.
Result of passing that restriction would be that ADO NET would retrieve only databases fulfilling the restriction requirement, which means only Nortwind database data would be returned

GetActiveConnection method creates a new SqlConnection instance using SqlConnectionStringBuilder class which is used to build connection string for given parameters.

Something like this

   1: private static SqlConnection GetActiveConnection(string serverName, string databaseName, string userName,
   2:                                                  string password, bool useIntegratedSecurity)
   3: {
   4:     SqlConnectionStringBuilder connBuilder = new SqlConnectionStringBuilder();
   5:     connBuilder.DataSource = serverName;
   6:     connBuilder.InitialCatalog = databaseName;
   7:     connBuilder.IntegratedSecurity = useIntegratedSecurity;
   8:     connBuilder.UserID = userName;
   9:     connBuilder.Password = password;
  10:     return new SqlConnection(connBuilder.ConnectionString);
  11: }

I'll be using this helper methods also in rest of the examples

How to enumerate tables of the given database

In general, the procedure of retrieval tables is the same as the procedure described for databases, in a sense that the GetSchema method of SqlConnection instance is been called but this time with SqlClientMetaDataCollectionNames.Tables ("Tables") enumerated value.

The big difference between those two is in the fact that tables restriction are contained of four different constraint arguments:

  1. database name
  2. owner/schema name ("dbo")
  3. table name (which should contain null value if we want to retrieve all tables of database)
  4. table type (which can have values "VIEW" for views and "BASE TABLE" for tables

So, to retrieve the list of tables for a given database we could use code similar to the next one:

   1: public static IList<string> GetTables(string serverName, string databaseName, string userId, string password,
   2:                                       bool windowsAuthentication)
   3: {
   4:     string[] restrictions = new string[4];
   5:     restrictions[0] = databaseName; // database/catalog name   
   6:     restrictions[1] = "dbo"; // owner/schema name   
   7:     restrictions[2] = null; // table name   
   8:     restrictions[3] = "BASE TABLE"; // table type    
   9:     Collection<string> result = new Collection<string>();
  10:     using (
  11:         SqlConnection connection =
  12:             GetActiveConnection(serverName, databaseName, userId, password, windowsAuthentication))
  13:     {
  14:         connection.Open();
  15:         DataTable dt = connection.GetSchema(SqlClientMetaDataCollectionNames.Tables, restrictions);
  16:         foreach (DataRow row in dt.Rows)
  17:         {
  18:             if (!row[2].ToString().StartsWith("sys"))
  19:                 result.Add(string.Format(@"{0}", row[2]));
  20:         }
  21:     }
  22:     return result;
  23: }
Column keys of the columns of the data table returned are:
  • Column 0. "table_catalog"
  • Column 1. "table_schema"
  • Column 2. "table_name"
  • Column 3. "table_type"

How to enumerate columns of the given table

The list of restriction parameters for column retrieval is shorter and it contains next 3 string values:

  1. Database name
  2. Owner/schema name
  3. Table name

SqlConnection instance GetSchema method gets this time SqlClientMetaDataCollectionNames.Columns ("Columns") enumerated value and the resulting data table contains next 18 columns:

Column 0 - "TABLE_CATALOG"
Column 1 - "TABLE_SCHEMA"
Column 2 - "TABLE_NAME"
Column 3 - "COLUMN_NAME"
Column 4 - "ORDINAL_POSTION"
Column 5 - "COLUMN_DEFAULT"
Column 6 - "IS_NULLABLE"
Column 7 - "DATA_TYPE"
Column 8 - "CHARACTER_MAXIMUM_LENGTH"
Column 9 - "CHARACTER_OCTET_LENGTH"
Column 10 - "NUMERIC_PRECISION"
Column 11 - "NUMERIC_PRECISION_RADIX"
Column 12 - "NUMERIC_SCALE"
Column 13 - "DATETIME_PRECISION"
Column 14 - "CHARACTER_SET_CATALOG"
Column 15 - "CHARACTER_SET_SCHEMA"
Column 16 - "CHARACTER_SET_NAME"
Column 17 - "COLLATION_CATALOG"

I believe column names are self explanatory and familiar to all of us, so I'll skip explanation of what they stand for

In our little example we would return concatenated string containing the column name and data type, where data type in case of char data types would show maximal number  of characters and in case of decimal precision data.

The code doing that might look like this:

   1: public static IList<string> GetColumns(
   2:        string serverName, string databaseName, string userId,
   3:        string password, bool windowsAuthentication, string tableName)
   4:    {
   5:        SqlConnection connection =
   6:            GetActiveConnection(serverName, databaseName, userId, 
   7:                                password, windowsAuthentication);
   8:  
   9:        string[] restrictions = new string[3];
  10:        restrictions[0] = connection.Database; // database/catalog name      
  11:        restrictions[1] = "dbo"; // owner/schema name      
  12:        restrictions[2] = tableName; // table name      
  13:        IList<string> result = new Collection<string>();
  14:        using (connection)
  15:        {
  16:            connection.Open();
  17:            DataTable columns = connection.GetSchema(SqlClientMetaDataCollectionNames.Columns, restrictions);
  18:            foreach (DataRow row in columns.Rows)
  19:            {
  20:                string columnName = row[3].ToString();
  21:                string columnDataType = row[7].ToString();
  22:                if (columnDataType.IndexOf("char") > -1)
  23:                {
  24:                    // row[8] - CHARACTER_MAXIMUM_LENGTH    
  25:                    columnDataType = string.Format("{0}({1})", columnDataType, row[8]);
  26:                }
  27:                if (columnDataType.IndexOf("decimal") > -1)
  28:                {
  29:                    // row[10] - CHARACTER_OCTET_LENGTH    
  30:                    // row[11] - NUMERIC_PRECISION    
  31:                    columnDataType = string.Format("{0}({1},{2})", columnDataType, row[10], row[11]);
  32:                }
  33:                result.Add(string.Format("{0},{1}", columnName, columnDataType));
  34:            }
  35:            return result;
  36:        }
  37:    }

How to enumerate indexes of the table

List of restrictions which can be used for indexes is the same as the one used for table, with 4 elements: database name, schema, table name and table type

We are executing GetSchema method of SqlConnection instance with SqlClientMetaDataCollectionNames.IndexColumns ("IndexColumns") enumerated value sent as a parameter and the resulting data table contains next 9 columns

  • Column 0 - "constraint_catalog"
  • Column 1 - "constraint_schema"
  • Column 2 - "constraint_name"
  • Column 3 - "table_catalog"
  • Column 4 - "table_schema"
  • Column 5 - "table_name"
  • Column 6 - "column_name"
  • Column 7 - "ordinal_position"
  • Column 8 - "KeyType"
  • Column 8 - "index_name"

Column 8 ("KeyType") describes the data type of the index and contains a numeric value which points to certain data type.

There's a list:

34 :  image
35 :  text
48 :  tinyint
52 :  smallint
56 :  int
58 :  smalldatetime
59 :  real
60 :  money
61 :  datetime
62 :  float
98 :  sql_variant
99 :  ntext
104 :  bit
106 :  decimal
108 :  numeric
122 :  smallmoney
127 : bigint
165 :  varbinary
167 :  varchar
173 :  binary
175 :  char
189 :  timestamp
231 :  nvarchar
239 :  nchar

So to enumerate indexes, one might write next code:

   1: public static IList<string> GetIndexes(SqlConnection connection, string tableName)
   2:       {
   3:           string[] restrictions = new string[3];
   4:           restrictions[0] = connection.Database; // database/catalog name      
   5:           restrictions[1] = "dbo"; // owner/schema name      
   6:           restrictions[2] = tableName; // table name      
   7:           IList<string> result = new Collection<string>();
   8:           using (connection)
   9:           {
  10:               connection.Open();
  11:               DataTable columns = connection.GetSchema(SqlClientMetaDataCollectionNames.IndexColumns, restrictions);
  12:               foreach (DataRow row in columns.Rows)
  13:               {
  14:                   string columnName = row["column_name"].ToString();
  15:                   string indexName = row["index_name"].ToString();
  16:                   bool isPrimaryKey = row["constarint_name"].ToString().StartsWith("PK");
  17:                   result.Add(string.Format("Index:{0}, on column:{1}, PK:{2}", indexName, columnName, isPrimaryKey));
  18:               }
  19:               return result;
  20:           }
  21:       }

How to enumerate parameters of the stored procedure

Enumeration of parameters used in a stored procedure is been done through usage of the SqlCommandBuilder static DeriveParameters method which accepts the SqlCommand instance constructed for a given sql connection and ctored procedure

According to http://www.codeproject.com/useritems/DetermineSql2005SPParams.asp, there is a difference in how SQL 2000 and SQL 2005 and there's a need of handling that problem with some additional approach, but according to my personal experience that's not the case - I never had problems he described.
So, IMHO to enumerate parameters of a stored procedure next simple code should be used regardless of the SQL version:

   1: public static SqlParameter[] DiscoverStoredProcedureParameters(SqlConnection sqlConnection,
   2:                                                                string storedProcedureName)
   3: {
   4:     SqlCommand cmd = new SqlCommand(storedProcedureName, sqlConnection);
   5:     cmd.CommandType = CommandType.StoredProcedure;
   6:     using (sqlConnection)
   7:     {
   8:         sqlConnection.Open();
   9:         SqlCommandBuilder.DeriveParameters(cmd);
  10:     }
  11:     SqlParameter[] discoveredParameters = new SqlParameter[cmd.Parameters.Count];
  12:     cmd.Parameters.CopyTo(discoveredParameters, 0);
  13:     return discoveredParameters;
  14: }

Test drive

Bellow you can find a source code of a small example which enumerates the databases (on left), tables of selected database (top right) and columns selected table (right down).

image[5]


Conclusion

ADO NET 2.0 removes the need of using ADOX or SQLDMO components for the tasks covering examining the structure of the database objects. It is almost trivial (with a bit reading of documentation) to do the thing which were before not-so trivial. But...
Although already very simple to use, I would like to see in future ADO NET 3.0 version  next enhancements:

  • Replacing the property bags as a way of passing arguments with DTOs as data carriers instead of string arrays. I guess that would have to be done in some new SQL connection related helper class to preserve compatibilty
  • For the same reasons I don't like property bags as a method parameter data carriers, I don't like the result data tables
    Having LINQ in place, I don't see the reason why we won't replace the returning DataTables with some more OOP friendly solution

You can download source code of this example here




Posted by tornado
|

몰랐네...

속도도 괜찮고 쓸만하군.

vss 버려야긋다~

http://ankhsvn.tigris.org/servlets/ProjectDocumentList?folderID=7315

사용자 삽입 이미지

Posted by tornado
|
[펌] --> http://www.ensimple.net/enSimple/show.aspx?cnum=301&b_id=kb&page=1

[MSTDC][Transaction][TransactionScope] 기본 트랜잭션 관리자와 통신하지 못했습니다
[키워드] MSTDC,Transaction,TransactionScope
[증상]
하나의 레코드 작업 수행시 성공하지만, 여러 레코드를 TransactionScope로 묶어서 처리할 때 DTC 관련 에러 발생 "기본 트랜잭션 관리자와 통신하지 못했습니다......(비슷한 에러)"

[해결]
서버의 MSDTC 설정 확인
로컬의 MSTDC 설정 확인
서로 간에 컴퓨터이름(NetBIOS Name)으로 ping 작동하는지 확인

만일 작동하지 않는다면,
로컬이 도메인에 참여하지 않은 경우, DNS 또는 Hosts 파일을 이용해 로컬 컴퓨터에 대한 레코드 등록하여 서로 간에 ping 작동하도록 함.

로컬이 도메인에 참여한 경우, AD 상에 컴퓨터계정이 존재하는지 확인
(존재하지 않는 경우, 로컬 컴퓨터의 도메인 참여를 다시 수행: 워크그룹을 빠졌다가 다시 도메인에 참여시킴)

그래도 안되면, Windows Firewall 설정이 켜져 있는지 확인 후, 켜져 있으면 끄거나 DTC 서비스에 대해 예외 설정을 한다.

그래도 안되면 DTCPing 유틸리티를 사용하여 RPC 연결에 문제가 없는지 확인 후 조치함.


DTCPing Download



문제해결 MSDN 참조
http://msdn2.microsoft.com/en-us/library/aa561924.aspx

Posted by tornado
|

               
// Reflection 으로 Field 를 찾는다.
 
FieldInfo fieldInfo = null;
Label lbl = null;

fieldInfo = this.GetType().GetField("treatmentLbl_" + i, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);

if(fieldInfo != null){
    lbl = (Label)fieldInfo.GetValue(this);
    lbl.Text = "xxx";
}

Posted by tornado
|

음... 프로젝트 하나 생성하고..
프로젝트에 System.Management 를 참조시킨다.

그리고...

using System;
using System.Management; 

로 사용할 네임스페이스 지정하고...

메서드를 하나 만든담에

아래와 같이 코딩한다..


        ManagementObject disk = new ManagementObject("win32_logicaldisk.deviceid=\"c:\"");

        disk.Get();

        Console.WriteLine("Logical Disk Size = " + disk["Size"] + " bytes");  
        Console.WriteLine("Logical Disk FreeSpace = " + disk["FreeSpace"] + " bytes"); 

------------------------------------------------------------

참고 : http://msdn2.microsoft.com/en-us/library/aa394173.aspx




Posted by tornado
|
출처 : http://msdn2.microsoft.com/ko-kr/library/3517w44b(VS.80).aspx


.NET Framework 개발자 가이드 
SQL Server에 BLOB 값을 쓸 때 리소스 절약 

데이터베이스의 필드 형식에 따라 필드에 문자열 값이나 바이트 배열을 삽입하거나 업데이트하여 데이터베이스에 BLOB(Binary Large Object)를 쓸 수 있습니다(데이터 소스에 BLOB 값 쓰기 참조). 그러나 BLOB가 너무 크면 단일 값으로 쓸 때 시스템 메모리를 너무 많이 차지하여 응용 프로그램 성능이 낮아질 수 있습니다.

BLOB 값을 쓸 때 사용되는 메모리 양을 줄이는 일반적인 방법은 데이터베이스에 BLOB를 "청크"로 쓰는 것입니다. 이 방식으로 데이터베이스에 BLOB를 쓰는 과정은 데이터베이스의 성능에 따라 달라집니다.

다음 샘플에서는 SQL Server에 BLOB를 청크로 쓰는 방법을 보여 줍니다. 이 샘플에서는 Northwind 데이터베이스의 Employees 테이블에 BLOB인 직원 이미지를 비롯한 새 레코드를 추가합니다. 즉, SQL Server의 UPDATETEXT 함수를 사용하여 Photo 필드에 새로 추가한 직원의 이미지를 지정된 크기의 청크 단위로 씁니다.

UPDATETEXT 함수를 사용하려면 업데이트되는 BLOB 필드에 대한 포인터가 있어야 합니다. 이 샘플에서는 새 직원 레코드를 추가할 때 SQL Server TEXTPTR 함수가 호출되어 새 레코드의 Photo 필드에 대한 포인터가 반환됩니다. 반환된 포인터 값은 출력 매개 변수로 다시 전달됩니다. 이 샘플 코드에서는 이 포인터가 유지되며 데이터의 청크를 추가할 때 UPDATETEXT로 전달됩니다.

다음은 새 직원 레코드를 삽입하고 Photo 필드에 대한 포인터를 유지하는 데 사용되는 Transact-SQL의 예제입니다. 여기서 @Identity@PointerSqlCommand의 출력 매개 변수로 인식됩니다.

INSERT INTO Employees (LastName, FirstName, Title, HireDate, ReportsTo, Photo) 
  Values(@LastName, @FirstName, @Title, @HireDate, @ReportsTo, 0x0)
SELECT @Identity = SCOPE_IDENTITY()
SELECT @Pointer = TEXTPTR(Photo) FROM Employees WHERE EmployeeID = @Identity

0x0의 초기 값(null)이 Photo 필드에 삽입되기 때문에 새로 삽입하는 레코드의 Photo 필드에 대한 포인터 값을 검색할 수 있습니다. 그러나 null 값은 추가된 데이터 청크에는 영향을 주지 않습니다.

새로 삽입한 레코드에 Photo 필드에 대한 포인터가 유지되면 이 샘플을 통해 SQL Server의 UPDATETEXT 함수를 사용하여 BLOB 필드에 데이터 청크를 추가할 수 있습니다. UPDATETEXT 함수는 Employees.Photo와 같은 필드 식별자, BLOB 필드에 대한 포인터, 현재 청크가 쓰여질 BLOB의 위치를 나타내는 오프셋 값 및 추가할 데이터 청크를 입력으로 사용합니다. 다음 코드 예제에서는 UPDATETEXT 함수에 대한 구문을 보여 줍니다. 여기서 @Pointer, @Offset,@BytesSqlCommand의 입력 매개 변수로 식별됩니다.

UPDATETEXT Employees.Photo @Pointer @Offset 0 @Bytes

오프셋 값은 응용 프로그램의 필요에 따라 사용자가 정하는 메모리 버퍼 크기에 의해 결정됩니다. 버퍼 크기가 크면 BLOB 쓰기 속도는 빠르지만 시스템 메모리가 더 많이 사용됩니다. 이 샘플에서는 비교적 적은 128바이트의 버퍼 크기를 사용합니다. 오프셋 값은 데이터의 첫 번째 청크에 대해 0부터 시작하여 각 연속 청크에 대해 버퍼 크기만큼 늘어납니다.

이 예제의 경우 제시한 파일 경로에서 직원 사진을 청크 단위로 검색합니다. 각 청크를 지정된 버퍼 크기당 바이트 배열로 읽어옵니다. 그러면 바이트 배열은 SqlCommand@Bytes 입력 매개 변수 값으로 설정됩니다. 그런 다음 @Offset 매개 변수 값이 업데이트되고 SqlCommand가 실행되어 직원 레코드의 Photo 필드에 현재 청크 바이트가 추가됩니다.

Visual Basic
Imports System
Imports System.Data
Imports System.Data.SqlClient
Imports System.IO

Public Class EmployeeData

    Public Shared Sub Main()
      Dim hireDate As DateTime = DateTime.Parse("4/27/98")
      Dim newID As Integer = _
          AddEmployee("Smith", "John", "Sales Representative", hireDate, 5, "smith.bmp")
      Console.WriteLine("New Employee added. EmployeeID = " & newID)
    End Sub

    Public Shared Function AddEmployee(lastName As String, firstName As String, title As String, hireDate As DateTime, _
       reportsTo As Integer, photoFilePath As String) As Integer

    Dim connection As SqlConnection = New SqlConnection("Data Source=localhost;Integrated Security=SSPI;Initial Catalog=Northwind;")

    Dim addEmp As SqlCommand = New SqlCommand("INSERT INTO Employees (LastName, FirstName, Title, HireDate, ReportsTo, Photo) " & _
      "Values(@LastName, @FirstName, @Title, @HireDate, @ReportsTo, 0x0);" & _
        "SELECT @Identity = SCOPE_IDENTITY();" & _
        "SELECT @Pointer = TEXTPTR(Photo) FROM Employees WHERE EmployeeID = @Identity", connection) 

    addEmp.Parameters.Add("@LastName", SqlDbType.NVarChar, 20).Value = lastName
    addEmp.Parameters.Add("@FirstName", SqlDbType.NVarChar, 10).Value = firstName
    addEmp.Parameters.Add("@Title", SqlDbType.NVarChar, 30).Value = title
    addEmp.Parameters.Add("@HireDate", SqlDbType.DateTime).Value     = hireDate
    addEmp.Parameters.Add("@ReportsTo", SqlDbType.Int).Value          = reportsTo

    Dim idParm As SqlParameter = addEmp.Parameters.Add("@Identity", SqlDbType.Int)
    idParm.Direction = ParameterDirection.Output
    Dim ptrParm As SqlParameter = addEmp.Parameters.Add("@Pointer", SqlDbType.Binary, 16)
    ptrParm.Direction = ParameterDirection.Output

    connection.Open()

    addEmp.ExecuteNonQuery()

    Dim newEmpID As Integer = CType(idParm.Value, Integer)

    StorePhoto(photoFilePath, ptrParm.Value, connection)

    connection.Close()

    Return newEmpID
  End Function

  Public Shared Sub StorePhoto(fileName As String, pointer As Byte(), connection As SqlConnection)

    Dim bufferLen As Integer = 128   ' The size of the "chunks" of the image.

    Dim appendToPhoto As SqlCommand = New SqlCommand("UPDATETEXT Employees.Photo @Pointer @Offset 0 @Bytes", connection)

    Dim ptrParm As SqlParameter = appendToPhoto.Parameters.Add("@Pointer", SqlDbType.Binary, 16)
    ptrParm.Value = pointer
    Dim photoParm As SqlParameter = appendToPhoto.Parameters.Add("@Bytes", SqlDbType.Image, bufferLen)
    Dim offsetParm As SqlParameter = appendToPhoto.Parameters.Add("@Offset", SqlDbType.Int)
    offsetParm.Value = 0

    ''''''''''''''''''''''''''''''''''''
    '' Read the image in and write it to the database 128 (bufferLen) bytes at a time.
    '' Tune bufferLen for best performance. Larger values write faster, but
    '' use more system resources.


    Dim fs As FileStream = New FileStream(fileName, FileMode.Open, FileAccess.Read)
    Dim br As BinaryReader = New BinaryReader(fs)

    Dim buffer() As Byte = br.ReadBytes(bufferLen)
    Dim offset_ctr As Integer = 0

    Do While buffer.Length > 0
      photoParm.Value = buffer
      appendToPhoto.ExecuteNonQuery()
      offset_ctr += bufferLen
      offsetParm.Value = offset_ctr
      buffer = br.ReadBytes(bufferLen)
    Loop

    br.Close()
    fs.Close()
  End Sub

End Class
using System;
using System.Data;
using System.Data.SqlClient;
using System.IO;

public class EmployeeData
{
  public static void Main()
  {
    DateTime hireDate = DateTime.Parse("4/27/98");
    int newID  = AddEmployee("Smith", "John", "Sales Representative", hireDate, 5, "smith.bmp");
    Console.WriteLine("New Employee added. EmployeeID = " + newID);
  }

  public static int AddEmployee(string lastName, string firstName, string title, DateTime hireDate , int reportsTo, string photoFilePath)
  {
    SqlConnection connection = new SqlConnection("Data Source=localhost;Integrated Security=SSPI;Initial Catalog=Northwind;");

    SqlCommand addEmp  = new SqlCommand("INSERT INTO Employees (LastName, FirstName, Title, HireDate, ReportsTo, Photo) " +
      "Values(@LastName, @FirstName, @Title, @HireDate, @ReportsTo, 0x0);" +
      "SELECT @Identity = SCOPE_IDENTITY();" +
      "SELECT @Pointer = TEXTPTR(Photo) FROM Employees WHERE EmployeeID = @Identity", connection);

    addEmp.Parameters.Add("@LastName",  SqlDbType.NVarChar, 20).Value = lastName;
    addEmp.Parameters.Add("@FirstName", SqlDbType.NVarChar, 10).Value = firstName;
    addEmp.Parameters.Add("@Title",     SqlDbType.NVarChar, 30).Value = title;
    addEmp.Parameters.Add("@HireDate",  SqlDbType.DateTime).Value = hireDate;
    addEmp.Parameters.Add("@ReportsTo", SqlDbType.Int).Value = reportsTo;

    SqlParameter idParm = addEmp.Parameters.Add("@Identity", SqlDbType.Int);
    idParm.Direction = ParameterDirection.Output;
    SqlParameter ptrParm = addEmp.Parameters.Add("@Pointer", SqlDbType.Binary, 16);
    ptrParm.Direction = ParameterDirection.Output;

    connection.Open();

    addEmp.ExecuteNonQuery();

    int newEmpID = (int)idParm.Value;

    StorePhoto(photoFilePath, (byte[])ptrParm.Value, connection);

    connection.Close();

    return newEmpID;
  }

  public static void StorePhoto(string fileName, byte[] pointer,  SqlConnection connection)
  {
    int bufferLen = 128;  // The size of the "chunks" of the image.

    SqlCommand appendToPhoto = new SqlCommand("UPDATETEXT Employees.Photo @Pointer @Offset 0 @Bytes", connection);

    SqlParameter ptrParm  = appendToPhoto.Parameters.Add("@Pointer", SqlDbType.Binary, 16);
    ptrParm.Value = pointer;
    SqlParameter photoParm = appendToPhoto.Parameters.Add("@Bytes", SqlDbType.Image, bufferLen);
    SqlParameter offsetParm = appendToPhoto.Parameters.Add("@Offset", SqlDbType.Int);
    offsetParm.Value = 0;

    //''''''''''''''''''''''''''''''''''
    // Read the image in and write it to the database 128 (bufferLen) bytes at a time.
    // Tune bufferLen for best performance. Larger values write faster, but
    // use more system resources.

    FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
    BinaryReader br = new BinaryReader(fs);

    byte[] buffer = br.ReadBytes(bufferLen);
    int offset_ctr = 0;

    while (buffer.Length > 0)
    {
      photoParm.Value = buffer;
      appendToPhoto.ExecuteNonQuery();
      offset_ctr += bufferLen;
      offsetParm.Value = offset_ctr;
      buffer = br.ReadBytes(bufferLen);
    }

    br.Close();
    fs.Close();
  }
}

참고 항목

Posted by tornado
|

사용자가 생성한 쓰레드내 (사용자 쓰레드) 에서, 메인 쓰레드가 소유한 컨트롤 객체를 제어하기 위해서는 Invoke 를 통해 해결하셔야 합니다.


간략히 이해하시려면 사용자 쓰레드에서 이벤트를 발생시켜서, 메인 쓰레드에서 이벤트로 받아 처리하라는 이야기 인데요. (이게 더 말이 어렵나??


개발자는 머니머니해도 소스 몇줄 보여드리면 이해가 팍팍..


        // 버튼을 누르면 쓰레드 동작..

        private void button1_Click(object sender, System.EventArgs e)

        {           

            hTread = new Thread(new ThreadStart(Test));

            hTread.Start();

        }


        private void Test()

        {

            try

            {

                while(true)

                {

                    // Form2 를 열기위한 이벤트 발생..

                    this.Invoke(new EventHandler(InvokeShowDialog));

                    Thread.Sleep(5000);

                }

            }

            catch(Exception err)

            {

                MessageBox.Show(err.ToString());

            }

           

        }

     

        // 이벤트 처리

        private void InvokeShowDialog(object sender, EventArgs e)

       {

            Form2 f = new Form2();

            f.Show();

       }

Posted by tornado
|

예전에 자바로 겁나 헤메던거 무지무지 간단하게 끝나네 그랴~


-- 출처 : http://www.codeproject.com/useritems/Audio_Player__with_Winmm.asp 


Note: This is an unedited contribution. If this article is inappropriate, needs attention or copies someone else's work without reference then please Report this article.

Sample Image - Audio_Player__with_Winmm.jpg

Introduction

After looking for a simple, yet free, mp3 player I deceided to make my own. I based myself on a commercial package that shall remain nameless [ Let's just say it that package was expensive considering it was importing the winmm.dll ]  Almost every example I found for playing audio file [in my case MP3s] using the winmm.dll only had play/stop capabilities (and sometimes pause). Which is fine, I just wanted a bit more, and still keep it simple. Of course, if I had wanted a full blown MP3 player, I propably would have download one of the many free application out there. That wasn't my purpose.
So the code is fairly simple. It uses the winmm.dll from Windows to play,stop,pause etc. As well as control the volume of the left/right channels (if there are more then 1). Also, I had fun trying my hand at parsing XML, so the application gets audio file infomartion from a Windows Media Playlist [Making one is easy, just use Windows Media Player].

Just please keep in mind, that I'm not a programmer by trade and this is my first contribution to the CodeProject. I know that I'm not re-inventing the wheel here, just hoping this will help someone somewhere.

The project has a couple of files:
-Player.cs [Which has all of the winmm.dll string commands]
more can be found here http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/htm/_win32_multimedia_command_strings.asp
Which in my opinion, is a pain to understand sometimes.
-readPlaylist.cs
This opens up a open dialog window and helps you select a *.wpl file
-MainPlayer.cs
Basically the buttons and click events etc etc.

Let's look at the Player.cs
Tried putting as many relevant comments in the code as I code with out going over board like I'm doing writting this acticle.

Collapse
using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text; namespace MP3player { class Player { private string Pcommand; private bool isOpen; [DllImport("winmm.dll")] private static extern long mciSendString(string strCommand, StringBuilder strReturn, int iReturnLength, int bla); /// <SUMMARY> /// Not much to conctruct here /// </SUMMARY> public Player() { } /// <SUMMARY> /// Stops currently playing audio file /// </SUMMARY> public void Close() { Pcommand = "close MediaFile"; mciSendString(Pcommand, null, 0, 0); isOpen = false; } /// <SUMMARY> /// Opens audio file to play /// </SUMMARY> /// This is the audio file's path and filename public void Open(string sFileName) { Pcommand = "open \"" + sFileName + "\" type mpegvideo alias MediaFile"; mciSendString(Pcommand, null, 0, 0); isOpen = true; } /// <SUMMARY> /// Plays selected audio file /// </SUMMARY> /// If True,audio file will repeat public void Play(bool loop) { if (isOpen) { Pcommand = "play MediaFile"; if (loop) Pcommand += " REPEAT"; mciSendString(Pcommand, null, 0, 0); } } /// <SUMMARY> /// Pauses currently playing audio file /// </SUMMARY> public void Pause() { Pcommand = "pause MediaFile"; mciSendString(Pcommand, null, 0, 0); } /// <SUMMARY> /// Returns the current status player: playing,paused,stopped etc. /// </SUMMARY> public string Status() { int i = 128; System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder(i); mciSendString("status MediaFile mode", stringBuilder, i, 0); return stringBuilder.ToString(); } /// <SUMMARY> /// Get/Set Lelf Volume Factor /// </SUMMARY> public int LeftVolume { get { return 0; //Guess could be used to return Volume level: I don't need it } set { mciSendString(string.Concat("setaudio MediaFile left volume to ", value), null, 0, 0); } } /// <SUMMARY> /// Get/Set Right Volume Factor /// </SUMMARY> public int RightVolume { get { return 0; //Guess could be used to return Volume level: I don't need it } set { mciSendString(string.Concat("setaudio MediaFile right volume to ", value), null, 0, 0); } } /// <SUMMARY> /// Get/Set Main Volume Factor /// </SUMMARY> public int MasterVolume { get { return 0; //Guess could be used to return Volume level: I don't need it } set { mciSendString(string.Concat("setaudio MediaFile volume to ", value), null, 0, 0); } } /// <SUMMARY> /// Get/Set Bass Volume Factor /// </SUMMARY> public int Bass { get { return 0; } set { mciSendString(string.Concat("setaudio MediaFile bass to ", value), null, 0, 0); } } /// <SUMMARY> /// Get/Set Treble Volume Factor /// </SUMMARY> public int Treble { get { return 0; } set { mciSendString(string.Concat("setaudio MediaFile treble to ", value), null, 0, 0); } } } } 

 

Now for reading the .wpl file to get MP3s [or whatever] to play
readPlaylist.cs

Collapse
using System; using System.Collections; using System.Text; using System.Xml; namespace MP3player { class readPlaylist { private ArrayList name = new ArrayList(); private string m_xmlFile; /// <SUMMARY> /// The Windows Media Playlist Path xxx.wpl file /// </SUMMARY> public string playListPath { get { return m_xmlFile; } set { m_xmlFile = value; Makeplaylist(); } } /// <SUMMARY> /// Return an Arraylist of file found in Windows Media Playlist file /// </SUMMARY> public ArrayList PlayList { get { return name; } } /// <SUMMARY> /// Fills up an Arraylist with titles found in the Windows Media Playlist file. /// Using XmlTextReader /// </SUMMARY> private void Makeplaylist() { XmlTextReader readList = new XmlTextReader(m_xmlFile); while (readList.Read()) { if (readList.NodeType == XmlNodeType.Element) { if (readList.LocalName.Equals("media")) { name.Add(readList.GetAttribute(0).ToString()); } } } } } }

Let's use the code now.
Here's a part of the file with all the click event and so on.
So here's the start, make sure you got all our references...

MediaPlayer.cs

Collapse
using System; using System.Collections; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace MP3player { public partial class MainPlayer : Form { ArrayList nowPlaylist = new ArrayList(); Player pl = new Player(); public MainPlayer() { InitializeComponent(); } private void btnOpen_Click(object sender, EventArgs e) { lstBoxPlayList.Items.Clear(); openPlaylistDialog.ShowDialog(); readPlaylist readList = new readPlaylist(); readList.playListPath = openPlaylistDialog.FileName; nowPlaylist = readList.PlayList; for (int x = 0; x < nowPlaylist.Count; x++) { lstBoxPlayList.Items.Add(nowPlaylist[x]); } lstBoxPlayList.SetSelected(0, true); } 


The above code is pretty straight foward. The btnOpen_click event will open a OpenFileDialog window. Get the selected .wpl file and send it to the readPlaylist class, which will in turn parse through it return an Arraylist with all the file names and there paths. Once that done, loop it to display it's content [in this case a listbox]. Now you have all your files ready to be played, all that's needed is to select one and press play. Or doudle-click on it start it (I won't show that part here).

To play the selected file in the listbox:

 private void btnPlay_Click(object sender, EventArgs e) { if (lstBoxPlayList.Items.Count > 0) { pl.Open(lstBoxPlayList.SelectedItem.ToString()); pl.Play(false); } } 

A simple way of checking that a file is really selected before playing.
Besides that, pretty simple. Of course, if you've never done this, it's not. It's called the learning process.
As mentionned above, I think the comments in the code are pretty good. That and the MSDN link that's at the top... you should do fine.

Another thing, also tried my hand at controlling the Bass/Treble. Don't know if it works, since my speaker system on my computer ain't great, and I'm hard of hearing [hence the reason my speaker system is crappy]. But if I read the MSDN right, it seems to work the same way as the volume control.

Guess that's about it, hope this little example will help someone out.

About loneferret


Studied English Teaching as a second language at university here in montreal(you wouldn't know it the way I type would ya), after that did some networking course with a bit of programming. Mostly working as a network admin these days.
I also like to write short stories, and draw..mostly black and white stuff...

Click here to view loneferret's online profile.

Posted by tornado
|

-- DB Server 감시 데몬 하나 만드는 중 --

-- 일본어 번역기로 돌렸음 --

-- http://www.atmarkit.co.jp/fdotnet/dotnettips/392notifyicon/notifyicon.html --



 Outlook (이)나MSN Messenger 등과 같이,Windows 어플리케이션에서는 시스템 트레이(task tray, 스테이터스 영역등이라고도 불린다)에 아이콘을 표시하고, 어플리케이션 상태를 나타내거나 어플리케이션의 폼을 표시하거나하기 위한 쇼트 컷으로서 이용할 수 있다.

 .NET Framework 의 클래스·라이브러리에는, 시스템 트레이에 아이콘을 표시하기 위한NotifyIcon 컴퍼넌트가 준비되어 있어 이것을 사용하는 것으로써, 상기와 같은 어플리케이션을 간단하게 작성할 수 있다.

 본고에서는, 이하와 같은 사양의 어플리케이션을 작성하면서,NotifyIcon 컴퍼넌트의 기본적인 이용 방법에 대해 정리한다.

  • 기동시에 폼과 동시에 시스템 트레이에 아이콘을 표시한다
  • 아이콘을 오른쪽 클릭해 표시되는 문맥·메뉴의[종료]로, 어플리케이션을 종료할 수 있다.
  • 폼의 우상구석에 있는[닫는]버튼의 클릭으로, 폼을 비표시로 한다(어플리케이션은 종료하지 않는다).
  • 아이콘의 더블 클릭으로 폼을 표시해, 한편 액티브하게 한다.

시스템 트레이에의 아이콘의 표시

 우선 어플리케이션의 기동시에, 시스템 트레이에 아이콘이 표시되도록 하자.

 Visual Studio .NET 그리고Windows 어플리케이션의 프로젝트를 신규 작성해,[툴 박스]윈도우로부터NotifyIcon 컴퍼넌트를 폼상에 드러그&드롭 한다.

 다음에,[프롭퍼티]윈도우에서,Icon 프롭퍼티로 적당한 아이콘·파일(.ico 파일)을 선택한다.여기서 지정한 아이콘이, 시스템 트레이에 표시되는 아이콘이 된다.이 설정을 실시하지 않으면, 어플리케이션을 실행해도 시스템 트레이에 아이콘은 표시되지 않는다.

 또,NotifyIcon 컴퍼넌트의Text 프롭퍼티에 문자열을 설정해 두면, 그것이 아이콘의 툴·힌트·텍스트로서 사용된다.이것은 마우스·커서를 아이콘상에 이동시켰을 때에 표시된다.

시스템 트레이·아이콘에 있어서의 문맥·메뉴의 표시

 계속 되어서는, 아이콘의 오른쪽 클릭에 의해[종료]메뉴를 표시해, 그것을 실행해 어플리케이션을 종료할 수 있도록 한다.

 이것에는,ContextMenu 컴퍼넌트를 폼상에 드러그&드롭 해,[종료]메뉴 항목을 추가한다.그리고[프롭퍼티]윈도우에서,NotifyIcon 컴퍼넌트의ContextMenu 프롭퍼티에, 지금 작성했다ContextMenu 컴퍼넌트를 설정한다.

[종료]메뉴의 항목을 추가했다ContextMenu 컴퍼넌트
여기에서는 폼의 메뉴로서 디자인하지만, 메뉴(이 화면에서는contextMenu1 )(을)를NotifyIcon 컴퍼넌트의ContextMenu 프롭퍼티로 설정하는 것으로써, 아이콘을 오른쪽 클릭했을 때에 표시되게 된다.□

아이콘의[종료]메뉴에 의한 어플리케이션의 종료

 다음에, 지금 추가한[종료]메뉴 항목을 더블 클릭 하고, 메뉴 항목의 선택시에 실행되는 이벤트·핸들러를 이하와 같이 기술한다.

private void menuItem1_Click(object sender, System.EventArgs e)
{
  notifyIcon1.Visible = false; // 아이콘을 트레이로부터 없앤다
  Application.Exit(); // 어플리케이션의 종료
}
Private Sub MenuItem1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItem1.Click
  NotifyIcon1.Visible = False ' 아이콘을 트레이로부터 없앤다
  Application.Exit() ' 어플리케이션의 종료
End Sub
문맥·메뉴의[종료]의 이벤트·핸들러의 기술(위:C# , 아래:VB.NET )

 통상,Windows 폼을 종료시킬 때는Close 메소드를 호출하지만, 이번 경우에서는 다음의 항목으로 말하고 있도록(듯이)Close 메소드 호출에 의해 발생한다Closing 이벤트를 캔슬해 버리므로, 여기에서는Application.Exit 메소드에 의해 어플리케이션을 강제적으로 종료시킨다.

 또, 어플리케이션의 종료시에는 시스템 트레이에 아이콘이 남아 버리는 일이 있으므로, 아이콘(NotifyIcon 오브젝트)의Visible 프롭퍼티를false (으)로 설정하고, 명시적으로 시스템 트레이로부터 지워 둔다.

 시스템 트레이·아이콘을 이용한 어플리케이션을 작성한 경우에는, 어플리케이션이 종료했음에도 불구하고 아이콘이 남아 버려, 그 아이콘을 마우스·커서로 덧써 주면 사라진다고 하는 현상이 이따금 발생하는 일이 있지만, 그러한 경우에는 이 방법을 시험해 주셨으면 한다.

폼이[닫는]버튼·클릭에 의한 폼의 비표시

 시스템 트레이·아이콘을 표시하는, 이른바 상주형의 어플리케이션에서는, 폼의 우상구석에 있는[닫는]버튼이 클릭되어도 어플리케이션을 종료시키지 않고 , 폼을 비표시로 할 만한 경우가 많다.

 이 동작을 실장하려면 , 폼을 닫으려고 했을 때에 발생한다Closing 이벤트의 이벤트·핸들러를 폼에 추가해, 다음과 같이 기술한다.

private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
  e.Cancel = true; // 종료 처리의 캔슬
  this.Visible = false; // 폼의 비표시
}
Private Sub Form1_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
  e.Cancel = True ' 종료 처리의 캔슬
  Me.Visible = False ' 폼의 비표시
End Sub
폼의Closing 이벤트·핸들러의 기술(위:C# , 아래:VB.NET )

 이 이벤트·핸들러에서는, 파라미터로 건네받는다CancelEventArgs 오브젝트의Cancel 프롭퍼티에true (을)를 설정하는 것으로써, 폼의 종료 처리를 캔슬할 수 있다.

 또 여기에서는, 폼의Visible 프롭퍼티에false (을)를 설정하는 것으로써, 폼을 비표시로 한다.

아이콘의 더블 클릭에 의한 폼의 표시

 마지막으로, 폼이[닫는]버튼에 의해 비표시가 된 폼을, 시스템 트레이의 아이콘을 더블 클릭 하는 것으로써 재차 표시되도록 하자.

 이것에는NotifyIcon 컴퍼넌트에DoubleClick 이벤트·핸들러를 추가해, 다음과 같이 기술한다.

private void notifyIcon1_DoubleClick(object sender, System.EventArgs e)
{
  this.Visible = true; // 폼의 표시
  if (this.WindowState == FormWindowState.Minimized)
    this.WindowState = FormWindowState.Normal; // 최소화를 그만둔다
  this.Activate(); // 폼을 액티브하게 한다
}
Private Sub NotifyIcon1_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles NotifyIcon1.DoubleClick
  Me.Visible = True ' 폼의 표시
  If Me.WindowState = FormWindowState.Minimized Then
    Me.WindowState = FormWindowState.Normal ' 최소화를 그만둔다
  End If
  Me.Activate() ' 폼을 액티브하게 한다
End Sub
아이콘(NotifyIcon 컴퍼넌트)의DoubleClick 이벤트·핸들러의 기술(위:C# , 아래:VB.NET )

 여기에서는, 폼이 최소화되고 있는 경우에는, 폼의WindowState 프롭퍼티에FormWindowState.Normal (을)를 설정하는 것으로써, 폼의 통상 상태에 되돌리고 있다.

 또, 폼의Activate 메소드를 호출해 폼을 액티브하게 하고 있다.이것에 의해, 폼이 다른 윈도우에 숨어 있었을 경우에도, 맨 앞면에 표시되게 된다.End of Article

Posted by tornado
|

[codeproject 펌]


http://www.codeproject.com/useritems/CrystalReport_DotNET2005.asp



Sample Image - ReportView.jpg

Introduction

In this article I have tried to cover a cycle of developing a web report using Crystal Report in .NET 2005. I haven't put any effort for the butification of the report. The report is just showing the Employee master data from the Northwind database of SQL Server.

The report is build on XML Schema and the data and binded the report at runtime.


Requirements

  1. Microsoft C#.NET 2005
  2. Windows 2000/2003/XP
  3. SQL Server 2000/2005(Optional). I have used SQL Server to fecth data. If in case SQL Server is not available then change the connection string in web.config and connection related syntax in Default.aspx.cs.


Creating your own Report

To start with Reports, you need start .NET 2005 Development Studio.

  1. Start a new ASP .NET Web site, Choose Location as "File System" and provide a path.
  2. Perform "Add New Item", choose "XML Schema".
       Add elements as the picture below.

Sample screenshot

         After saving the elements will look like this, in the XML Editor        


        <xs:element name="EmployeeID" type="xs:int" />
        <xs:element name="LastName" type="xs:string" />
        <xs:element name="FirstName" type="xs:string" />
        <xs:element name="Title" type="xs:string" />
        <xs:element name="BirthDate" type="xs:dateTime" />
        <xs:element name="Address" type="xs:string" />
        <xs:element name="City" type="xs:string" />
        <xs:element name="Region" type="xs:string" />
        <xs:element name="PostalCode" type="xs:string" />
        <xs:element name="Country" type="xs:string" />
        <xs:element name="HomePhone" type="xs:string" />
 

   3.  Perform "Add New Item", choose "Crystal Report".

    1. Give a name for the report.
    2. Choose -- Using the Report Wizard. -- OK.
    3. A Data window will appear, Click on "Create New Connection" and then "ADO .NET".
    4. A connection windows will appear. Provide the XML Schema file that u have created just now. Finish.
    5. The Schema will appear under the "ADO .NET" tag. Choose. And select using > button.
    6. Click Next. Fields windows will appear. Select all using >> button.
    7. Click Finish, for taking shortcut.

    4.  Open the Default.aspx in Design mode. Add CrystalReportViewer control in to it. The source will look like this.

 <CR:CrystalReportViewer ID="CrystalReportViewer1" runat="server" AutoDataBind="true" /> 

    5.  Open the Default.aspx.cs file and paste the following codes.
 

Collapse
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
//--SqlClient for SqlConnection and etc.
using System.Data.SqlClient;
//--for CrystalReports's ReportDocument.
using CrystalDecisions.CrystalReports.Engine;
public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        //--Sql string
        String strCmd = "";
        strCmd += "Select EmployeeID, LastName, FirstName, Title, BirthDate, ";
        strCmd += "Address, City, Region, PostalCode, Country, HomePhone ";
        strCmd += "From Employees ";
        //--Opening Sql Connection
        string strConn = ConfigurationManager.AppSettings["connectionstring"];
        SqlConnection sqlConn = new SqlConnection(strConn);
        DataSet ds = new DataSet();
        SqlDataAdapter da = new SqlDataAdapter(strCmd, sqlConn);
        //--this statement is very important, here the table name should
        //--match with the XML Schema table name
        da.Fill(ds, "Employees");
        //--Closing Sql Connection
        sqlConn.Close();
        //--(Optional) I have used it to disable the properties
        CrystalReportViewer1.DisplayGroupTree = false;
        CrystalReportViewer1.HasCrystalLogo = false;
        //--Initializing CrystalReport
        ReportDocument myReportDocument;
        myReportDocument = new ReportDocument();
        myReportDocument.Load(Server.MapPath("Employees.rpt"));
        myReportDocument.SetDataSource(ds);
        //--Binding report with CrystalReportViewer
        CrystalReportViewer1.ReportSource = myReportDocument;
        CrystalReportViewer1.DataBind();
    }
}

    6.  Open the Web.config file and change the connection string under <appSettings> as per your machine (ip address, username, password).


<appSettings>
     <add key="connectionString" value="Data Source=9.182.223.80;Initial Catalog=Northwind;Persist Security Info=True;User ID=testUser;Password=password" />
    
 </appSettings>
   If in case the file is not available then perform "Add New Item", choose "Web Configuration File", and follow the same thing.

    7.  Using the script

Just to check wheather Employees master table is available with data
   . Open SQL Server Query Analyzer
   . Copy the scripts
   . Paste into Query Analyzer
   . Press F5 to execute

---------------------------------
-----Using Database
---------------------------------
Use Northwind;
---------------------------------
-----Selecting data from Table
---------------------------------
Select EmployeeID, LastName, FirstName, Title, BirthDate,
 Address, City, Region, PostalCode, Country, HomePhone
 From Employees;
    7.  Now build the Web project. Press F5/Ctrl F5 to view the report. Hope everything will go fine.


 

About Suranjan Nandi


Suranjan Nandi has 7 years of working experience in Software Development using Microsoft Technology. During this period he was involved with .NET Technologies, COM, Client Server Architecture, Multi-tier Architecture, Crystal Reports, Database Analysis & Designing in Microsoft Environment.

Click here to view Suranjan Nandi's online profile.


Other popular ASP.NET articles:

Posted by tornado
|

http://www.castleproject.org/


시간날때 다이나믹 프락시 점 봐야겠습니다.

Posted by tornado
|

[msmvps.com 펌]

http://msmvps.com/blogs/luisabreu/archive/2006/10/29/UpdatePanel_3A00_-having-fun-with-errors.aspx



UpdatePanel: having fun with errors

UpdatePanel has always given us some sort of error handling during partial postbacks (or, if you want to use the new official term, async postbacks). In previous CTPs, you could handle a page error event and perform your own error handling (which normally consisted in some form of logging). The problem previous versions had was related with the way that the error message was shown in the client side (by default, it showed an alert message box, though you could define a limited error template). The current release give us a lot more options as I'll show you in this post.

If you don't do anything, when you get an error during partial postback you'll get a simple alert message box showing you the error message associated with the exception you had in the server. As we all agree, this is not the best info to show to our users; it's also not a good idea to show a standard error message. If we don't mind showing an alert message in the client, then we can start by handling the AsyncPostBackError event generated by the ScriptManager control in order to customize the error message returned from the server. Here's a simple page that shows this approach:

<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
void handleClick(object sender, EventArgs e)
{
   int a = 0;
    int res = 10 / a;
}
void HandleError(object sender, AsyncPostBackErrorEventArgs e)
{
    //here we could log the error, and see which exception we're getting in order to set a specific error message
    //in this case, I'm just returning the current date/hour back
    manager.AsyncPostBackErrorMessage = "Ooops...error occurred:  " +
     DateTime.Now.ToString();
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
   <head runat="server">
     <title>Untitled Page</title>
    </head>
<body>
  <form id="form1" runat="server">
        <asp:ScriptManager runat="server" ID="manager"
               OnAsyncPostBackError="HandleError">
        </asp:ScriptManager>
        <asp:UpdatePanel runat="server" ID="panel">
            <ContentTemplate>
               <asp:Button runat="server" ID="bt" Text="gerar erro no servidor"
                OnClick="handleClick" />
            </ContentTemplate>
         </asp:UpdatePanel>
   </form>
</body>
</html>

As you can see, when the user clicks the button, he'll get a divide by zero exception error on the server side. The previous page shows how you could log the error and return a friendly error message back to the client (the AsyncPostBackErrorMessage was introduced in this version and lets us define the error message which is returned to the client when an exception occurs on the server side). If you run the page, you'll notice that you'll still get the alert message, but this time, it'll show our fridendly error message.

If you want, you can drop the standard alert message and show the error in any way you see fit. To illustrate the steps necessary to perform this operation, I'll start by adding a DIV ccontrol that will be used as a place holder for showing the error returned from the server:

<div id="err"></div>

The next thing we need to do is to handle the endRequest event which is fired by the PageRequestManager object which is present in all the pages that use UpdatePanels:

<script type="text/javascript">
   Sys.WebForms.PageRequestManager.getInstance().add_endRequest( endRequest );
   function endRequest( sender, e ) {
        if( e.get_error() ){
               document.getElementById("err").innerText =  e.get_error().description;
               e.set_errorHandled( true );
        }
   }
</script>

I start by adding a method that will handle the endRequest event by using the add_endRequest method over the Sys.WebForms.PageRequestManager global object. The method starts by checking if there's an error (by using the get_error method) and, when it finds one, it gets its description (through the description field) and sets the errorHandled field of the EventArgs object used to true so that the default alert message isn't shown to the user. Though the previous code is really simple, there's nothing preventing you from using the toolkit behaviors to get similar results to the ones that we had in the previous CTPS (btw, you can also stop processing the server side error event if you don't need logging and do everything in the client side: you're the one that need to decide on what's best here!).

For those that want to show a default error page, then there's still one additional property exposed by ScriptManager which you'll like: AllowCustomerErrors. When you set this property to true, you're saying that ScriptManager should check for a custom error page associated with the current error an show it to the user. To illustrate its usage, lets start by adding the following to the web.config file:

<customErrors mode="On">
     <error statusCode="404" redirect ="error.aspx"/>
</customErrors>

And now lets run the following page:

<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
void HandleClick(object sender, EventArgs e)
{
     this.Server.Transfer("nopage.aspx"); //don't do this in reall AJAX pages!!!!!
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
  <head runat="server">
      <title>Untitled Page</title>
   </head>
<body>
<form id="form1" runat="server">
   <asp:ScriptManager runat="server" ID="manager"
        AllowCustomErrors="true" />
   <asp:UpdatePanel runat="server" ID="panel">
       <ContentTemplate>
          <asp:Button runat="server" id="bt" Text="postback"
               onclick="HandleClick" />
      </ContentTemplate>
    </asp:UpdatePanel>
</form>
</body>
</html>

First, you should note that you should never use a Server.Transfer instruction on an ajax page. I'm using it since it's simplest way I could think of getting a known 404 error. Now, back to the important things: the AllowCustoErrors property. Since i've set it to true, when ScriptManager handles an exception during an async postback, it'll read the config file and see if there's any error page associated with the current error. If there is, it'll just send an AJAX message to client which instructs the browser to redirect the user to the desired page.

As you have seen, there's now a lot more control over the way exceptions are handled during a partial postback request. You do have to write more code than in the previous versions, but it's also true that the current release is a lot more flexible than the previous one.

Posted by tornado
|

[ajax.asp.net 포럼에서 펌]


atlas 에서는 <ErrorTemplate> 에다가 설정 해놨었는데, 조금 바뀌었습니다.

예제에는 DIV 로 배경색 바꿔서 div 로 처리하는데

저같은 경우는 masterPage 에다 ajaxToolkit 에 있는 ModalPopupExtender 으로

처리했습니다.


Customizing Error Handling for UpdatePanel Controls

Introduction

When an error occurs during partial-page updates in UpdatePanel controls, by default a script alert box is displayed with an error message. This tutorial shows you how to customize how the error is presented to the user and what information the message contains.

You can see the code in action in this tutorial by clicking the Run It buttons. To implement the procedures in your own development environment you need:

  • Visual Web Developer Express Edition or Visual Studio 2005.

  • The latest release of Microsoft ASP.NET AJAX installed and configured. For more information, see Installing ASP.NET AJAX.

  • An ASP.NET AJAX Web site.

To customize error handling in server code

  1. Create a new page and switch to Design view.

  2. In the AJAX Extensions tab of Toolbox, double-click the ScriptManager control and the UpdatePanel control to add them to the page.

  3. Add two TextBox controls, a Label control, a Button control, and some text inside of the UpdatePanel control. Set the text of the button to Calculate.

    Your page will look like the following:

    UpdatePanel Tutorial
  4. Double-click the Calculate button and add the following code for its event handler.

    CS

    protected void Button1_Click(object sender, EventArgs e){    try    {        int a = Int32.Parse(TextBox1.Text);        int b = Int32.Parse(TextBox2.Text);        int res = a / b;        Label1.Text = res.ToString();    }    catch (Exception ex)    {        if (TextBox1.Text.Length > 0 && TextBox2.Text.Length > 0)        {            ex.Data["ExtraInfo"] = " You can't divide " +                TextBox1.Text + " by " + TextBox2.Text + ".";        }        throw ex;    }        }

    VB

    Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs)    Try        Dim a As Int32        a = Int32.Parse(TextBox1.Text)        Dim b As Int32        b = Int32.Parse(TextBox2.Text)        Dim res As Int32 = a / b        Label1.Text = res.ToString()    Catch ex As Exception        If (TextBox1.Text.Length > 0 AndAlso TextBox2.Text.Length > 0) Then            ex.Data("ExtraInfo") = " You can't divide " & _              TextBox1.Text & " by " & TextBox2.Text & "."        End If        Throw ex    End TryEnd Sub

    The event handler code contains a try-catch statement. In the try block, the code divides the values from the text boxes. If the operation fails, code in the catch block adds the extra string information ExtraInfo to the exception and then rethrows the exception without handling it.

  5. Switch to Design view and select the ScriptManager control.

  6. In the toolbar of the Properties window, click the Events button and then double-click the AsyncPostBackError box to create a handler for that event.

    UpdatePanel Tutorial
  7. Add the following code to the AsyncPostBackError event handler.

    CS

    protected void ScriptManager1_AsyncPostBackError(object sender, AsyncPostBackErrorEventArgs e){    if (e.Exception.Data["ExtraInfo"] != null)    {        ScriptManager1.AsyncPostBackErrorMessage =            e.Exception.Message +            e.Exception.Data["ExtraInfo"].ToString();    }    else    {        ScriptManager1.AsyncPostBackErrorMessage =            "An unspecified error occurred.";    }}

    The code checks whether the ExtraInfo data item was defined for the exception. If so, the AsyncPostBackErrorMessage property is set to the string value. Otherwise, a default error message is created.

  8. Save your changes and then press CTRL+F5 view the page in a browser.

  9. Add a number greater than zero to each text box and click the Calculate button to demonstrate a successful postback.

  10. Change the second text box input to 0 and click the Calculate button to create an error condition.

    The browser displays a message box that contains the message set in the server code.

    UpdatePanel Tutorial
    note

    The style of the alert message box depends on what browser you are using, but the message is the same in all browsers.

    To see the full example in action, click the Run It button below.

Using Client Script to Customize Error Handling

The preceding procedure demonstrated how to customize errors during partial-page rendering by using setting properties of the server ScriptManager control. The following procedure builds on the customization by using the client PageRequestManager class to display the error in a <div> element instead of using the default browser alert message box.

To customize error handling in client script

  1. In the page you created earlier, switch to Source view

  2. Add the following markup to the page:

    CS

        <div id="AlertDiv" language="javascript" onclick="return AlertDiv_onclick()">        <div id="AlertMessage">        </div>        <br />        <div id="AlertButtons">            <input id="OKButton" type="button" value="OK" runat="server" onclick="ClearErrorState()" />        </div>    </div></div>

    VB

        <div id="AlertDiv" language="javascript" onclick="return AlertDiv_onclick()">        <div id="AlertMessage">        </div>        <br />        <div id="AlertButtons">            <input id="OKButton" type="button" value="OK" runat="server" onclick="ClearErrorState()" />        </div>    </div></div>

    The markup includes elements that you can use to display partial-page rendering errors. It defines a <div> element named AlertDiv that contains two other <div> elements. One of the nested <div> elements contains an <input> control that will enable users to hide the <div>.

  3. Add the following style markup in the <head> element.

    CS

    <style type="text/css">#UpdatePanel1 {  width: 200px; height: 50px;  border: solid 1px gray;}#AlertDiv{left: 40%; top: 40%;position: absolute; width: 200px;padding: 12px; border: #000000 1px solid;background-color: white; text-align: left;visibility: hidden;z-index: 99;}#AlertButtons{position: absolute; right: 5%; bottom: 5%;}</style>

    VB

    <style type="text/css">#UpdatePanel1 {  width: 200px; height: 50px;  border: solid 1px gray;}#AlertDiv{left: 40%; top: 40%;position: absolute; width: 200px;padding: 12px; border: #000000 1px solid;background-color: white; text-align: left;visibility: hidden;z-index: 99;}#AlertButtons{position: absolute; right: 5%; bottom: 5%;}</style>

    The styles make the error information stand out visually from the rest of the page content.

  4. Switch to Design view and verify that your page looks like the following:

    UpdatePanel Tutorial
  5. In the drop-down list at the top of the Properties window, select the DOCUMENT element (which represents the <body> element on the page) and set its Id property to bodytag.

    UpdatePanel Tutorial
  6. Switch to Source view.

  7. Add the following <script> block anywhere after the <asp:ScriptManager> element.

    CS

    <script type="text/javascript" language="javascript">var divElem = 'AlertDiv';var messageElem = 'AlertMessage';var bodyTag = 'bodytag';Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);function ToggleAlertDiv(visString){     if (visString == 'hidden')     {         $get(bodyTag).style.backgroundColor = 'white';                              }     else     {         $get(bodyTag).style.backgroundColor = 'gray';                              }     var adiv = $get(divElem);     adiv.style.visibility = visString;}function ClearErrorState() {     $get(messageElem).innerHTML = '';     ToggleAlertDiv('hidden');                     }function EndRequestHandler(sender, args){   if (args.get_error() != undefined)   {       var errorMessage;       if (args.get_response().get_statusCode() == '200')       {           errorMessage = args.get_error().message;       }       else       {           // Error occurred somewhere other than the server page.           errorMessage = 'An unspecified error occurred. ';       }       args.set_errorHandled(true);       ToggleAlertDiv('visible');       $get(messageElem).innerHTML = errorMessage;   }}</script>

    VB

    <script type="text/javascript" language="javascript">var divElem = 'AlertDiv';var messageElem = 'AlertMessage';var bodyTag = 'bodytag';Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);function ToggleAlertDiv(visString){     if (visString == 'hidden')     {         $get(bodyTag).style.backgroundColor = 'white';                              }     else     {         $get(bodyTag).style.backgroundColor = 'gray';                              }     var adiv = $get(divElem);     adiv.style.visibility = visString;}function ClearErrorState() {     $get(messageElem).innerHTML = '';     ToggleAlertDiv('hidden');                     }function EndRequestHandler(sender, args){   if (args.get_error() != undefined)   {       var errorMessage;       if (args.get_response().get_statusCode() == '200')       {           errorMessage = args.get_error().message;       }       else       {           // Error occurred somewhere other than the server page.           errorMessage = 'An unspecified error occurred. ';       }       args.set_errorHandled(true);       ToggleAlertDiv('visible');       $get(messageElem).innerHTML = errorMessage;   }}</script>

    This script does the following:

    • Defines a handler for the endRequest event of the PageRequestManager class. In the handler, the code displays the AlertDiv<div> element if there is an error condition.

    • Defines the ToggleAlertDiv function, which hides or shows the AlertDiv element and changes the color of the page based if there was an error condition.

    • Defines the ClearErrorState function, which hides the error message UI.

  8. Save your changes and then press CTRL+F5 view the page in a browser.

  9. Add a number greater than zero to each text box and click the Calculate button to demonstrate a successful postback.

  10. Change the second text box input to 0 and click the Calculate button to demonstrate an error condition.

    The custom AlertDiv element is displayed instead of default alert message box. The following figure shows an example of the error condition.

    UpdatePanel Tutorial

    To see the full example in action, click the Run It button below.

Review

This tutorial showed ways you can extend error handling during partial-page rendering by writing JavaScript code. In server code you can customize error handling by using the AsyncPostBackErrorMessage property and the AsyncPostBackError event of the ScriptManager control. In client code you can customize error handing by using the endRequest event of the PageRequestManager class.

This topic is ASP.NET AJAX pre-release documentation and is unsupported by Microsoft. Blank topics are included as placeholders and existing content is subject to change in future releases.

Posted by tornado
|

Written by 안재우(Jaewoo Ahn), 닷넷엑스퍼트(.netXpert)

 

6월달에 Vista Solution Builder 프로그램을 통해 WinFX 개발자 교육을 , 그동안 바쁜 일들 때문에 더이상 살펴보지 못했습니다. 지난번에 WinFX -> .NET Framework 3.0으로 이름 변경에서 소개한 뒤로 WinFX 이제 .NET 3.0이라는 명칭으로 이름이 바뀌었습니다. 그런데도 아직 여전히 WinFX 계속 익숙하네요. ^^

 

6월달 교육에서는 5월말경에 나왔던 Beta 2 사용했었습니다. 제가 맡았던 부분은 WCF(Windows Communication Foundation) WF(Workflow Foundation)이었는데, WCF 경우 Beta2 이전 CTP들이 상당히 달라서 고생을 했었습니다. 기존에 받아두었던 대부분의 예제들이 동작하지 않아서 그걸 일일이 수정하느라 시간이 걸렸습니다.

 

Beta2 이후 June CTP 등을 거쳐서, 9 1 Vista RC1 발표와 함께 .NET 3.0 RC1 버전이 나왔습니다. 이제 RC 단계에 들어갔으니깐 RTM 나올 때도 머지 않았기에 슬슬 다시 살펴봐야 시점이 같습니다.

 

일단 살펴보기 위해서 필요한 녀석들을 설치해야 하는데..

우선 노트북에는 이전 Beta2 기준의 Runtime SDK, Orcas 등이 깔려 있습니다.

RC1 설치하려면 이전 버전을 제거해야 하겠죠?

사실 가장 좋은 방법은 제어판의 프로그램 추가/삭제에서 직접 관련 요소들을 삭제하는 것입니다만, 다음과 같이 자동으로 제거를 수행해주는 도구가 있긴 합니다. 그러나 저같이 의심 많은 사람들은 "자동"이라는 믿지 않고 직접 삭제를 합니다. ^^

 

Pre-released Microsoft .NET Framework 3.0 Uninstall Tool

http://www.microsoft.com/downloads/details.aspx?familyid=AAE7FC63-D405-4E13-909F-E85AA9E66146&displaylang=en

 

 

.NET 3.0 개발을 위해 다운로드해야 하는 요소들을 안내하고 있는 페이지는 다음과 같습니다.

http://msdn.microsoft.com/windowsvista/downloads/products/getthebeta/

사실 여기에 가봐도 설명이 되어 있긴 하지만.. 다시 한번 설명하면..

 

일단 <SPAN style="FONT-FAMILY: 돋움; mso-bidi-font-family: 굴림; mso-font-kerning: 0pt; mso-bidi-font-size: 10.0pt; mso-ascii-font-family: Ver

Posted by tornado
|
Posted by tornado
|

http://forums.asp.net/thread/1348010.aspx


Re: Data Binding in an AccordionPane in a Repeater

finally, I managed to make it work on both IE and Firefox. Here goes the code:

======================

    <div id="Accordion1" runat="server" style="width: 460px; height:auto;">
                                    <asp:Repeater ID="Repeater1" runat="server" DataSourceID="SqlDataSource1">
                                     <ItemTemplate>
                                            <span id="<%# Eval("Uyghur") %>"><div>
                                            <div class="accordionHeader">
                                  My header comes from: <%# Eval("DataItemName") %></a>
                                         </div></div><div><div class="accordionContent">
                                                    My contects come from: <%# Eval("DataItemName") %>
                                         </div>
                                     </div></span>
                                      </ItemTemplate>
                                        </asp:Repeater>
                                </div>
                                <atlasToolkit:AccordionExtender ID="AccordionExtender1" runat="server">
                                         <atlasToolkit:AccordionProperties
                                          TargetControlID="Accordion1"
                                          AutoSize="none"
                                             SelectedIndex="0"
                                          FadeTransitions="true"
                                                TransitionDuration="250"
                                                FramesPerSecond="40"/>
                                </atlasToolkit:AccordionExtender>

======================

N.B.: DO NOT put a space between <span> and <div> tags, if not it does not work properly in Firefox... That is what I found, don't ask me why. Yes, it is strange, I am still looking for an answer... :)

Posted by tornado
|

CLR Profiler

.NET/.NET Framework 2006. 8. 16. 10:29
Posted by tornado
|

아주 큰~~~ 삽질

.NET/C# 2006. 7. 25. 19:46

현재 ASP.NET 2.0 으로 개발하고 있는데, 데이터베이스 관련해서 프레임워크를


하나 만들어서 사용한다.


COM+ 사용 안하고 멀티 트랜잭션 가능하고, 테이블과 객체 매핑 되고, Stored Procedure 에


최적화 시켜놨당.


그런데, 웹페이지 띠우고 새로고침 몇십번 하면 tcp resource 부족으로 먹통이 된다. ㅎㅎ


왜 그러나~ 하고 코드 자세히 뜯어보니...


private ArrayList dbts = new ArrayList();



public void CreateTransaction(bool isTransaction)
{


  DBTransaction dbt = new DBTransaction(true);

  dbts.add(dbt);

}


public void ReleaseTransaction()

{

    foreach(DBTransaction dbt in dbts){

        dbts.Clone();

    }

}


대충 이런 코드가 있는데... 빨간색 부분.... 허걱..


Close() 해야 하는데, Clone() 이당...


Visual Studio 에 코드 자동완성 뜨는거에 대충 엔터쳐서 작성해 놨더니


저렇게 되었음.



즉 트랜잭션 열어놓구, 종료두 안하고 ArrayList 를 계속 복사한 상황이다.


빨리 알아냈으니 다행이지 큰일날뻔했네 ㅎ



Posted by tornado
|