PhonePasswordBox

.Net/Windows Phone 2012.06.08 09:51

툴킷에 있는 PhoneTextBox 는 정말 맘에 드는 컨트롤 중 하나이다.

따로 TextBlock 을 둬서 TextBox에 어떤내용인지 설명을 하지 않아도 된다.

화면사이즈에 제약이 있는 Phone 환경에서는 꼭 필요한 컨트롤 중 하나이다.

 

하지만 PasswordBox 에서는 해당 기능이 지원되지 않는다.

그래서 찾아본 링크

http://damianblog.com/2011/01/21/wp7-password-watermark/

 

링크를 참조하여 내게 필요한 몇가지 기능을 추가했다.

아래는 소스.

======================== PhonePasswordBox.cs =======================

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace BloodAria.MyMusic.Controls
{
    public partial class PhonePasswordBox : UserControl
    {
        #region DependencyProperty

        public static readonly DependencyProperty HintProperty =
            DependencyProperty.Register("Hint", typeof(string), typeof(PhonePasswordBox), new PropertyMetadata("Password",
                    new PropertyChangedCallback(OnHintPropertyChanged)
                )
            );
        private static void OnHintPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        {
            PhonePasswordBox phonePasswordBox = sender as PhonePasswordBox;
            if (phonePasswordBox != null && phonePasswordBox.txtBoxPasswordHint != null && args.NewValue != null)
            {
                phonePasswordBox.txtBoxPasswordHint.Text = args.NewValue as string;
            }
        }

        public static readonly DependencyProperty PasswordProperty =
            DependencyProperty.Register("Password", typeof(string), typeof(PhonePasswordBox), new PropertyMetadata(
                    new PropertyChangedCallback(OnPasswordPropertyChanged)
                )
            );
        private static void OnPasswordPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        {
            PhonePasswordBox phonePasswordBox = sender as PhonePasswordBox;
            if (phonePasswordBox != null && phonePasswordBox.txtBoxPassword != null && args.NewValue != null)
            {
                phonePasswordBox.txtBoxPassword.Password = args.NewValue as string;
                phonePasswordBox.CheckPasswordWatermark();
            }
        }

        #endregion

        #region Properties

        public string Hint
        {
            get { return base.GetValue(HintProperty) as string; }
            set { base.SetValue(HintProperty, value); }
        }
        public string Password
        {
            get { return base.GetValue(PasswordProperty) as string; }
            set { base.SetValue(PasswordProperty, value); }
        }

        #endregion

        #region Events

        public event RoutedEventHandler PasswordChanged;

        #endregion

        public PhonePasswordBox()
        {
            InitializeComponent();
            txtBoxPassword.PasswordChanged += (s, e) => this.Password = txtBoxPassword.Password;
            txtBoxPassword.PasswordChanged += (s, e) => { if (PasswordChanged != null) PasswordChanged(this, e); };
            txtBoxPasswordHint.TextChanged += (s, e) => this.Hint = txtBoxPasswordHint.Text;
            txtBoxPasswordHint.Text = "Password";
        }

        protected override void OnGotFocus(RoutedEventArgs e)
        {
            base.OnGotFocus(e);
            this.txtBoxPassword.Focus();
        }
       
        private void PasswordLostFocus(object sender, RoutedEventArgs e)
        {
            CheckPasswordWatermark();
        }
       
        public void CheckPasswordWatermark()
        {
            var passwordEmpty = string.IsNullOrEmpty(txtBoxPassword.Password);
            txtBoxPasswordHint.Opacity = passwordEmpty ? 100 : 0;
            txtBoxPassword.Opacity = passwordEmpty ? 0 : 100;
        }

        private void PasswordGotFocus(object sender, RoutedEventArgs e)
        {
            txtBoxPasswordHint.Opacity = 0;
            txtBoxPassword.Opacity = 100;
        }
    }
}
======================== PhonePasswordBox.xaml =======================

<UserControl x:Class="BloodAria.MyMusic.Controls.PhonePasswordBox"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    d:DesignHeight="100" d:DesignWidth="400">

    <Grid>
        <TextBox x:Name="txtBoxPasswordHint" TextWrapping="Wrap" Foreground="{StaticResource PhoneTextBoxReadOnlyBrush}" IsHitTestVisible="False"/>
        <PasswordBox x:Name="txtBoxPassword" LostFocus="PasswordLostFocus" Opacity="0" GotFocus="PasswordGotFocus"/>
    </Grid>
</UserControl>

설정

트랙백

댓글

Enum.GetValues()

.Net/Windows Phone 2012.06.05 17:11

WPF 에서는 당연한듯 썼던 Enum.GetValues() 가 없다. (실버라이트 동일)

열거형 타입의 모든 값을 가져와서 ListPicker 에 바인딩 시킬려고 했는데 너무 손이 많이 갔다.

아이템을 수동으로 추가하는 방법도 있으나 맘에 안들고...

 

찾던중 발견한 링크.

http://cjbhaines.wordpress.com/2011/07/12/enum-getvalues-in-silverlight/

 

아래는 소스.

 

using System.Linq;

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Diagnostics;

 

namespace BloodAria.MyMusic.Common
{
    public static class EnumHelper
    {
        public static T[] GetValues<T>()
        {
            Type enumType = typeof(T);
            if (!enumType.IsEnum)
                throw new ArgumentException("Type '" + enumType.Name + "' is not an enum");

            IEnumerable<FieldInfo> fields = enumType.GetFields().Where(field => field.IsLiteral);

            return fields.Select(field => field.GetValue(enumType)).Select(value => (T)value).ToArray();
        }
    }
}

 

설정

트랙백

댓글

C#에서 Excel 연동

.Net/C# 2012.04.02 11:20

C#에서 Excel 연동하는 법?

따로 라이브러리로 정리해야겠당.

후배가 물어봐서 링크전달 ㅋㅋ

알아서 해바~


http://csharp.net-informations.com/excel/csharp-excel-tutorial.htm

설정

트랙백

댓글

네트워크 경로에 있는 프로젝트 열기

.Net 2012.03.30 14:53

난 그냥 안되는줄 알았네...

http://msdn.microsoft.com/en-us/library/bs2bkwxc(v=vs.80).aspx

설정

트랙백

댓글

ClickOnce 주요 API

.Net/배포 2012.03.30 14:31

참조 dll : System.Deployment.dll

네임스페이스 : System.Deployment.Application

클래스 : ApplicationDeployment

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

IsNetworkDeployed : ClickOnce 배포를 통하여 실행되었는가?

                              ClickOnce API를 이용하기 전 항상 체크 해야 함.

IsFirstRun : 현재 버전이 처음 실행 되었는가?

Update(). UpdateAsync(), CheckForUpdate(), CheckForUpdateAsync() : 업데이트 관련

IsFileGroupDownloaded(), DownloadFileGroup(). DownloadFileGroupAsync() : 추가 파일 그룹별 다운로드 관련

 

설정

트랙백

댓글

프로그램 경로

.Net/C# 2012.03.30 14:17

난 시작 경로를 가져오고 싶은 경우, 그러니까, *.exe 파일이 있는 경로를 가져오고 싶은 경우

Enviroment.CurrentDirectory를 썼었다.

뭐.. 콘솔응용프로그램에서는 문제가 없었다.

하지만 Winform 이나 WPF 의 경우.. OpenFileDialog 등과 같이 경로 변경이 일어날 경우

Enviroment.CurrentDirectory 이놈은 같이 변한다.

 

그래서 수정했던게 System.Windows.Forms.Application.StartupPath 이 놈.

잘가져왔다.

하지만 ClickOnce 배포후 실행되는 경우는 난감하다. 닷넷 프레임워크 기본경로를 통해서 실행되기 때문이다.

그래서 어디서나 제대로 된 프로그램의 시작 경로를 가져 오고 싶을 때는

System.AppDomain.CurrentDomain.BaseDirectory 이 곳을 참조하자.

설정

트랙백

댓글

부트스트래퍼(BootStrapper)

.Net/배포 2012.03.30 14:01

비주얼 스튜디오 시작시 부트스트래퍼 경로에 있는 부트스트랩을 읽어 온다.

부트스트래퍼 경로 : \Program Files\Microsoft Visual Studio\SDK\v2.0\BootStrapper\Packages

단순히 파일만 있어서 되는게 아니라 XML스키마를 따르는 XML파일, 설치프로그램을 설명하는 매니페스트 파일이 필요하다.

생성시 아래 툴을 이용하라.

Bootstrapper Manifest Generator Tool (http://archive.msdn.microsoft.com/bmg)

생성 - Project Code: "게시자.제품명.버전"

          Display Name: 필수항목에 노출될 이름

          System Checks : 필요한 항목 설정(파일, GAC, 레지스트리)

          Install Conditions

          Exit Code: Success, Fail 등..

          빌드

 

----

첨부 : wic_bootstrapper_patch.exe

        Windows 2003, Windows XP sp2 이하 버전에서 .net framework 설치시 반드시 포함되어야 함.

----------- 2012.4.2 추가 ----------

----------- 2012.4.9 수정 ----------

많은 분들이 이 포스트를 검색으로 타고 오시기에.. 다시 수정.

Windows XP 64bit에서는 첨부한 WIC가 정상적으로 설치되지만 Windows 7 64bit 에서는 

VersionPMHdll64 이놈을 만족하지 못하는 문제가 발생한다. (오히려 32bit의 조건인 VersionPMHdll 이 놈을 만족시킨다.)

따라서 편법으로 64bit의 경우 32bit의 조건을 추가로 주도록한다. (즉, 둘 다 체크하도록)

<BypassIf Property="VersionPMHdll64" Compare="VersionGreaterThanOrEqualTo" Value="6.0.5840.16388"/>

<BypassIf Property="VersionPMHdll" Compare="VersionGreaterThanOrEqualTo" Value="6.0.5840.16388"/>

이렇게 해두면 Windows XP 64bit, Windows 7 64bit 모두 정상적으로 WIC를 배포할 수 있다.

수정된 Product.xml을 첨부한다.


내가 했던 삽질을 다른 분들은 하지 않길 바라며...

설정

트랙백

댓글

WatermarkTextBox for Silverlight

.Net/Silverlight 2011.12.27 15:38
이상하다.. 전에 툴킷에 있었던거 같은데 없네...

http://silverscratch.blogspot.com/2010/03/watermarked-textbox-part-i.html

설정

트랙백

댓글

Phone Thema에 따른 Color, Content변경

.Net/Windows Phone 2011.12.27 00:19
폰 테마가 밝게 일때와 어둡게 일때 나눠서 컨텐트 또는 색상을 준비해놔야 되는구나...
젠장.. 신경쓸거 많네..

나중에 정리하기로하고..
일단 찾아놓은 링크만 포스트!



테마관련 MSDN 링크 : http://msdn.microsoft.com/en-us/library/ff769554(v=VS.92).aspx
테마 리소스 목록 : http://msdn.microsoft.com/en-us/library/ff769552(v=VS.92).aspx
예제 : http://www.mendzapp.com/archives/196
         http://timdams.wordpress.com/2011/06/21/creating-a-wp7-app-supporting-dark-and-light-themes/

설정

트랙백

댓글

아놔... 툴킷 만들었으면 제대로 관리하라고!!

.Net/Windows Phone 2011.12.22 11:03
헤이! 이것봐!!! 이런걸 보고 다 해주고 욕먹는거라자나!

툴킷 만들고 수정했으면 제대로 올려야지 이넘들아!

2011 Nov 버전이라고 해서 다운받아서 설치했더니...
설치된 버전은 2011 Oct 버전이자나!!!

아놔.. 한참 찾아해맸네...

msi 파일 다시 말아!

소스는 정상적이더군... 소스 내려받아서 수정완료! 

설정

트랙백

댓글