2010년 11월 28일 일요일

C# Convert Int to Bool












 다른 모듈과 설정파일을 공유하는 경우가 있다. 한 예로 MFC 모듈과 .NET 모듈이 XML 파일로 설정을 공유하는데, 특정 기능의 사용, 사용 안함을 1 과 0 으로 정의하여 사용하고 있다. 설정을 읽고 체크박스 컨트롤의 상태를 결정할 때 다음과 같은 코드를 주로 사용하였다.





int useUpdate = [xml파일로 부터 설정 읽기];


ckbUseUpdate.Checked = useUpdate == 1;





 몰랐는데 int 값을 bool값으로 변환해주는 FCL이 있었다. 바로 Convert.ToBoolean


매개변수로 int 값을 받을 때, 0일 경우 false 그 외에 경우에는 모두 true 를 리턴한다.










 코딩할 때, 어쩔 수 없는 경우라면 직접 만들어야 하지만 가능하면 FCL을 이용하려 한다.





But,

프로그래밍 잘 한다고 생각하는 친구로 부터 조언을 받았다. 항상 고맙게 생각하는 친구다.

어느 언어를 막론하고 형 변환은 조심스럽게 사용해야 한다. 수 형들간의 형변환 시, Convert의 정적 메소드, 데이터 타입의 Parse, TryParse 정적 메소드를 사용하게 된다. 이 중 형 변환 시 예외를 발생시키지 않는 것은 TryParse 이다. try-catch 문을 과도하게 쓰는 코드는 좋지 않다. 따라서 TryParse 메소드의 사용이 유리한 점이 많다.




2010년 11월 27일 토요일

Create a Login Window in WPF



출처 : Create a Login Window in WPF - Paul Sheriff's Blog










Create a Login Window in WPF

Most business applications require some sort of security system. You can always use Windows Authentication to authenticate a user, but sometimes you might want your own authentication scheme. When you do, you will need to create a login screen for your user to enter her login id and password. This article will explore creating a login window in WPF.

The UI for your login screen can contain any images and controls that you would like. In Figure 1 you can see a sample login screen that has an image of a key, a large title label across the top, two labels, a text box, a password box and two button controls. You can also make the border of the window rounded so that there is no close, minimize or maximize button and no title bar.

Figure 1: A Login Screen

Of course this is just one version of a login screen but let’s take a look at how this is put together.

Creating the Window

To start, you need to create a window with no border and can be made into any shape you want. To do this you will set a few different attributes. The WindowStyle attribute normally allows you to set a single border, three-D border, or a Tool Window border. Setting this attribute to None will eliminate the border. The ShowInTaskbar attribute is optional, but if you are building a login screen you probably won’t want this window to show up in the Task Bar as it is going to be modal style form. The next two attributes, AllowsTransparency and Background work together. You must set AllowsTransparency to True to allow the Background to be set to Transparent. If you do not set these two attributes, then your border will still show up. Below is the xaml for this window.

<Window ...
   WindowStartupLocation="CenterScreen"
   AllowsTransparency="True"
   ShowInTaskBar=False
   Background="Transparent"
   WindowStyle="None"
   SizeToContent="WidthAndHeight"
   FocusManager.FocusedElement=
          "{Binding ElementName=txtUserName}">

   ...
   ...

</Window>

There are three additional attributes that are set on this window. The WindowStartupLocation attribute is set to “CenterScreen”  to ensure that the login screen is displayed in the middle of the screen when it is shown. You also set the SizeToContent attribute to WidthAndHeight to just take as much room for this window as the controls need that are contained within this window. The FocusManager.FocusedElement attribute is data-bound to the textbox control next to the User Name label. This tells WPF to place the cursor in this textbox once the screen is displayed.

The Border

Now that you have the Window xaml defined you now can create the look for the outside border of the window. A Border control is used to form the outside of this login screen. You will set the CornerRadius attribute to “10” to give the nice rounded corners. You can set the BorderBrush to “Gray” and the BorderThickness to “3”. You also want to give this border a nice wide Margin to allow room for the DropShadowEffect that we add to the outside of this border. If you do not do this, then the drop shadow will be chopped off. To achieve the shadow effect on this window, you will use the new Border.Effect and the DropShadowEffect that was added in WPF 3.5. This drop shadow effect is drawn using the Graphical Processing Unit (GPU) instead of being drawn using software. Thus drawing drop shadows is much more performant than in previous versions of WPF.

<Border CornerRadius="10"
        BorderBrush="Gray"
        BorderThickness="3"
        Background="Beige"
        Margin="24"
        Padding="4">
  <Border.Effect>
    <DropShadowEffect Color="Gray"
                      Opacity=".50"
                      ShadowDepth="16" />
  </Border.Effect>

   ...
   ...

</Border>

Using a Grid Layout

To place each of the login screen elements within the border, a Grid control is used with specific column and row definitions. There are three columns in this login screen. One for the image of the key, one for the labels and one for the TextBox, PasswordBox and Button controls.

<Grid>
  <Grid.ColumnDefinitions>
    <ColumnDefinition Width="60" />
    <ColumnDefinition Width="100" />
    <ColumnDefinition Width="*" />
  </Grid.ColumnDefinitions>
  <Grid.RowDefinitions>
    <RowDefinition />
    <RowDefinition />
    <RowDefinition />
    <RowDefinition />
  </Grid.RowDefinitions>

   ...
   ...

</Grid>

Placing the Key Image

The Key image that is in the upper left hand corner of this login screen is placed there by using a StackPanel control and an Image control. The StackPanel gives us just a little more control over the placement within the Grid. Notice the Grid.Column, Grid.Row and Grid.RowSpan attributes that are set on the StackPanel. The Grid.Row and Grid.Column specify in which row and column of the grid you wish to display the StackPanel. The Grid.RowSpan allows the key to float down over the next three rows of the Grid control. If you were to use a smaller or larger key image, then you would probably need to adjust this attribute accordingly. The Image control sets the source of its image to the Key.jpg file located in the /Images folder. A drop shadow effect is applied to this image control just like you did with the Border control.

<StackPanel Grid.Column="0"
            Grid.Row="0"
            Grid.RowSpan="3">
  <Image Name="imgKey"
         Margin="8"
         Source="/Images/Key.jpg">
    <Image.Effect>
      <DropShadowEffect Color="Gray"
                        Opacity=".50"
                        ShadowDepth="8" />
    </Image.Effect>
  </Image>
</StackPanel>

The Large Title Label

The large label across the top of the login screen is simply a Label control with the appropriate Grid.Row, Grid.Column and Grid.ColumnSpan attributes set for placement. A FontSize of 18 is applied to make the text appear larger than the other labels on this screen. A Margin of 10 is used to give us some spacing from the border of the grid.

<Label Grid.Column="1"
       Grid.Row="0"
       Grid.ColumnSpan="2"
       FontSize="18"
       Margin="10">Please Login To Access This Application
</Label>

The Login Data Controls

The controls that gather the user name and password should be fairly familiar to you if you have been doing any WPF at all. Each control is placed into a specific row and column of the Grid control. Notice the use of the Tooltip attribute on the TextBox and the PasswordBox control. This gives the user an idea of what to put into each control if they hover their mouse over that control.

<Label Grid.Column="1"
       Grid.Row="1">User Name</Label>
<TextBox Grid.Column="2"
         Grid.Row="1"
         ToolTip="Enter Your User Name"
         Name="txtUserName" />
<Label Grid.Column="1"
       Grid.Row="2">Password</Label>
<PasswordBox Grid.Column="2"
             Grid.Row="2"
             ToolTip="Enter Your Password"
             Name="txtPassword" />

The Buttons

The two buttons at the bottom of the screen are placed into the last row of the Grid control and into the second column of the grid by wrapping them into a StackPanel. The StackPanel has its HorizontalAlignment attribute set to Center and it’s Orientation attribute to Horizontal to allow the buttons to be centered within the StackPanel and to have the buttons appear side-by-side to each other.

<StackPanel Grid.Column="2"
            Grid.Row="3"
            Margin="10"
            HorizontalAlignment="Center"
            Orientation="Horizontal">
  <Button Name="btnCancel"
          IsCancel="True"
          Content="Cancel"
          Click="btnCancel_Click">
    <Button.Effect>
      <DropShadowEffect Color="Gray"
                        Opacity=".50"
                        ShadowDepth="8" />
    </Button.Effect>
  </Button>
  <Button Name="btnLogin"
          IsDefault="True"
          Content="Login"
          Click="btnLogin_Click">
    <Button.Effect>
      <DropShadowEffect Color="Gray"
                        Opacity=".50"
                        ShadowDepth="8" />
    </Button.Effect>
  </Button>
</StackPanel>

There are two special attributes that are set on these buttons. The IsCancel attribute is set to true on the Cancel button. Setting this attribute to true will fire the click event procedure on the Cancel button if the user presses the Escape key. The IsDefault attribute is set to true on the on the Login button. Setting this attribute to true will fire the click event procedure on the Login button if the user presses the Enter key.

Writing the Code for the Login Screen

In each of the click event procedures you will need to close the screen. In the Cancel click event procedure you will set the DialogResult property of the screen to a false value. This will inform the calling procedure that the user clicked on the Cancel button on this screen. In the Login click event procedure you will set the DialogResult property of the screen to a true value. This informs the calling procedure that the user clicked on the Login button and was authenticated. I am leaving it up to you to write the code for authenticating the user. Here is the code for the Cancel event procedure.

C#private void btnCancel_Click(object sender, RoutedEventArgs e)
{
  DialogResult = false;
  this.Close();
}

Visual BasicPrivate Sub btnCancel_Click(ByVal sender As System.Object, _
 ByVal e As System.Windows.RoutedEventArgs)
  DialogResult = False
End Sub

And, here is the code for the Login event procedure.

C#private void btnLogin_Click(object sender, RoutedEventArgs e)
{
  // Write code here to authenticate user
  // If authenticated, then set DialogResult=true
  DialogResult = true;
}

Visual BasicPrivate Sub btnLogin_Click(ByVal sender As System.Object, _
  ByVal e As System.Windows.RoutedEventArgs)
  DialogResult = True
End Sub

Displaying the Login Screen

At some point when your application launches, you will need to display your login screen modally. Below is the code that you would call to display the login form (named frmLogin in my sample application). This code is called from the main application form, and thus the owner of the login screen is set to “this”. You then call the ShowDialog method on the login screen to have this form displayed modally. After the user clicks on one of the two buttons you need to check to see what the DialogResult property was set to. The DialogResult property is a nullable type and thus you first need to check to see if the value has been set.

C#private void DisplayLoginScreen()
{
  frmLogin frm = new frmLogin();

  frm.Owner = this;
  frm.ShowDialog();
  if (frm.DialogResult.HasValue && frm.DialogResult.Value)
    MessageBox.Show("User Logged In");
  else
    this.Close();
}

Visual BasicPrivate Sub DisplayLoginScreen()
  Dim frm As New frmLogin()

  frm.Owner = Me
  frm.ShowDialog()
  If frm.DialogResult.HasValue And frm.DialogResult.Value Then
    MessageBox.Show("User Logged In")
  Else
    Me.Close()
  End If
End Sub

Summary

Creating a nice looking login screen is fairly simple to do in WPF. Using the DropShadowEffect can add a nice finished look to not only your form, but images and buttons as well. Using a border-less window is a great way to give a custom look to a login screen or splash screen. The DialogResult property on WPF Windows allows you to communicate back to the calling routine what happened on the modal screen. I hope this article gave you some ideas on how to create a login screen in WPF.



2010년 11월 20일 토요일

[Coding Style] Using C# predefined types or alias ?

C# Coding Standard by IDesign 문서를 읽고 있다. 읽다 보니까 다음과 같은 지침이 있다.

"Always use C# predefined types rather than the aliases in the System namespace"



자주 사용하는 string 타입을 예로 들면,

C# predefined type : System.String
Alias                    : string


"string" 은 System.String 의 Alias 즉 별칭이다. 예전에 읽었던 문서에서는 해당 타입의 alias가 있으면 alias를 사용하라고 했었는데 지금 읽는 문서에서는 또 그러길 비추 하고 있다. 


 딱히 어떤것이 더 유리한지 떠오르지 않아 검색해 보았다. 검색해 보니까 나와 똑같은 고민을한 흔적들이 보인다.


 자료를 읽던 중 신기한 현상을 발견했다. enum 타입을 정의할 때 요소의 데이터 타입을 지정해 줄 수 있다. 데이터 타입을 명시할 때 데이터의 전체이름(C# predefined type)을 지정해 주면 컴파일이 되지 않는다. 




또한 C# 3.5에 추가된 익명타입 var 의 사용에서도 제한이 따른다.




 어차피 코딩 스타일이라는게 개인마다 정하기 나름이지만 대부분의 경우에 있어서 alias를 사용하는것 같다. alias를 사용하면 코드의 가독성이 높아진다.  단, 메소드 이름에 데이터 타입이 들어갈때는 alias 보다는 predefined type 이름을 사용하는게 더 명확하다.