InkPresenter 방명록 만들기 - 6. Stroke Size Controler User Control 만들기


1. InkPresenter 객체 겉핥기 (InkPresenter XAML 구조)
2. InkPresenter를 사용한 간단한 샘플 만들어보기 (작동완구)
3. Undo & Redo 구현하기
4. InkPresenter User Control 만들기
5. Color Palette User Control 만들기
6. Stroke Size Controler User Control 만들기
7. HTTP Request와 Response를 이용하여 정보 교환하기 (Get, Post 전송)
8. Page Navigation User Control 만들기

사용자 삽입 이미지


5주만에 강좌를 재계합니다. 정말 바빴습니다. 믿어주십시오!

그 사이 Silverlight Demo 사이트 쉬버라이트닷넷을 약간 단장하였구요.
저희 회사 휴즈플로우의 웹사이트도 간단하게 만들어서 오픈을 하였습니다.

0. Sample Project

체험장 :  http://shiverlight.net/InkPresenterSample/InkPresentationSample_StrokeSize


1. Stroke Size Controler User Control 디자인 (UCStrokeSize.xaml)

진행하기에 앞서 다음 포스트를 읽어보실 것을 권장합니다.

   Blend를 통해 User Control 추가하기

사용자 삽입 이미지

사용자 삽입 이미지

사용자 삽입 이미지

위와 같이 디자인이 되었습니다.
이제 XAML 엘리먼트 트리만 보셔도 감이 팍팍 오시죠?

XAML 엘리먼트 트리 맨 아래의 HFSlider _oSizeSlider는 아래와 같은 모습의
녀석으로 Slider 역할을 소화하는 녀석입니다. 자세한 사항은 소스를 참고해 주십시오.

사용자 삽입 이미지


3. Stroke Size Control 비하인드 코드 작성 (UCStrokeSize.xaml.cs)

기본적인 것들은 이전 강좌와 비슷하므로 설명하지 않겠습니다. (소스를 보시면 아실 겁니다. ^^)
여기서는 Slider와 관련된 부분만 설명을 드리도록 하겠습니다.

XAML에 추가한 Slider를 참조하기 위해서 클래스에 다음 변수를 추가합니다.

// 슬라이더
HFSlider _oSizeSlider;

생성자나 Loaded 함수에 아래와 같은 코드를 추가하여,
실제 객체를 찾아 연결해주고 Slider에 관련된 설정을 해줍니다.

// 슬라이드를 2~40까지의 정수 값을 가지게 하고, Current Value를 1/2 하여 Stroke 사이즈로 사용한다.
_oSizeSlider = _cvMyself.FindName("_oSizeSlider") as HFSlider;
_oSizeSlider.NumberType = NumberType.Integer;
_oSizeSlider.MinValue = 2;
_oSizeSlider.MaxValue = 40;
_oSizeSlider.ValueChanging += new EventHandler(_oSizeSlider_ValueChanging);
_oSizeSlider.ValueChanged += new EventHandler(_oSizeSlider_ValueChanged);


결과적으로 Slider는 2~40 사이의 범위 안에서 정수를 반환해 주게 됩니다.
이것은 0.5 단위의 Stroke Size를 얻어내기 위해서 사용한 꼼수 입니다. (주석 참조)

이벤트가 2가지 보이는데,
ValueChanging은 사용자가 Slider의 Handle을 잡고 움직이는 동안(MouseMove)에도 이벤트가 발생하고,
ValueChanged는 사용자가 Slider를 움직이다가 손을 때었을 때(MouseLeftButtonUp) 이벤트가 발행합니다.

void _oSizeSlider_ValueChanging(object sender, EventArgs e)
{
    // 스트로크 사이즈를 업데이트
    StokeSize = GetStrokeSizeFromSlider();
}

void _oSizeSlider_ValueChanged(object sender, EventArgs e)
{
    // 스트로크 사이즈를 업데이트
    StokeSize = GetStrokeSizeFromSlider();

    // 이벤트 발생
    OnSizeChanged();
}

그럼, StokeSize 프로퍼티의 set을 살펴보면 값이 할당되면 동적으로 어떤 일들을 하는지 보실 수 있습니다.

// 스트로크 사이즈
double _dStrokeSize;
public double StokeSize
{
    get { return _dStrokeSize; }
    set
    {
       _dStrokeSize = value;
       _oSizeSlider.CurrentValue = _dStrokeSize * 2;

       // Outline Thickness 고려
       _elSize.Width = _dStrokeSize + 4;
       _elSize.Height = _dStrokeSize + 4;

       _elSize.SetValue(Canvas.LeftProperty, (_cvCurSize.Width - _elSize.Width) / 2);
       _elSize.SetValue(Canvas.TopProperty, (_cvCurSize.Height - _elSize.Height) / 2 - 3);

       _tbSize.Text = string.Format("{0:F1}", _dStrokeSize);
       _tbSize.SetValue(Canvas.LeftProperty, (_cvCurSize.Width - _tbSize.ActualWidth) / 2);
    }
}


4. 샘플 프로젝트에 적용


Page.xaml을 Blend에서 Open 합니다.

Asset Library를 통해서 UCStrokeSize User Control을 Page.xaml에 추가합니다.
(만약 모르시는 부분이면 다음 포스트를 먼저 읽으십시오. http://gilverlight.net/2674)

사용자 삽입 이미지

이름을 _oStrokeSize라고 줍니다.

Page.xaml.cs의 생성자에서 다음과 같이 초기화를 해줍니다.

// Stroke Size Controler 설정
_oStrokeSize.StokeSize = _dInitialStrokeSize;
_oStrokeSize.Color = _oPalette.Color;
_oStrokeSize.SizeChanged += new EventHandler(_oStrokeSize_SizeChanged);

SizeChanged 이벤트를 구현해 줍니다.

void _oStrokeSize_SizeChanged(object sender, EventArgs e)
{
    _oInkEditor.StrokeSize = new Size(_oStrokeSize.StokeSize, _oStrokeSize.StokeSize);
}

팔레트의 색상이 변경될 때마다 Stroke Size Controler에서도 자기가 보여주고 있는
Stroke 미리보기의 색상을 변경해 줍니다.

void _oPalette_ColorChanged(Color color)
{
    _oInkEditor.StrokeColor = color;
    _oStrokeSize.Color = color;
}

이제 Stroke Size Controler 추가가 끝났습니다.

사용자 삽입 이미지

간단하죠?


5. 보너스 팁

<부제 : 그리는 도중 InkPresenter 영역을 벗어났다 들어와도 계속 그려지게 하는 방법>

UCInk.xaml.cs에 간단히 bool 변수 하나를 이용해서 구현합니다.

일단 아래와 같이 변수를 하나 추가해 주십시오.

// 영역 밖에 나갔다 들어와도 그려지게 해줌
private bool _bDrawContinue = false;

전에 없던 MouseEnter 이벤트를 추가합니다.

public UCInk(Size sz, bool bEditable)
{
    (전략...)

    // InkPresenter Mouse Event 필수 4종세트
    _ink.MouseLeftButtonDown += new MouseEventHandler(ink_MouseLeftButtonDown);
    _ink.MouseMove += new MouseEventHandler(ink_MouseMove);
    _ink.MouseEnter += new MouseEventHandler(_ink_MouseEnter);
    _ink.MouseLeftButtonUp += new MouseEventHandler(ink_MouseLeftButtonUp);
    _ink.MouseLeave += new EventHandler(ink_MouseLeave);
}

void _ink_MouseEnter(object sender, MouseEventArgs e)
{
    if (_bDrawContinue == true)
    {
       StartNewStroke(e.GetStylusPoints(_ink));
    }
}

_bDrawContinue의 값을 MouseLeftButtonDown에서 true, MouseLeftButtonUp에서 false로 설정합니다.

void ink_MouseLeftButtonDown(object sender, MouseEventArgs e)
{
    if (Editable == false)
 return;

    _ink.CaptureMouse();
    StartNewStroke(e.GetStylusPoints(_ink));
    _bDrawContinue = true;
}

void ink_MouseLeftButtonUp(object sender, MouseEventArgs e)
{
    _ink.ReleaseMouseCapture();
    _strokeCurrent = null;
    _bDrawContinue = false;
}

이렇게 하면 그리는 도중 영역 밖을 나갔다 들어와도 계속해서 그림이 그려집니다.

이것으로 이번 강좌를 마칩니다.

감사합니다.




 


설정

트랙백

댓글

  • 구피 2008.02.27 12:02 신고 ADDR 수정/삭제 답글

    정말 잘만드셨네요

    디자인도 너무 깔끔해...ㅠㅠ요

  • BlogIcon 길버트 2008.02.28 00:11 신고 ADDR 수정/삭제 답글

    안녕하세요! 길버트 이길복입니다.
    그렇게 말씀해 주시니 감사합니다!
    강좌를 아직 마무리 짓지 않아서 죄송할 따름입니다.

  • ^^ 2008.10.14 13:20 신고 ADDR 수정/삭제 답글

    나머지 강좌 어서해주세용 ㅠㅠ
    감사히 잘 볼게요 ~

    • BlogIcon 길버트 2008.10.15 09:44 신고 수정/삭제

      죄송합니다. ㅜ_ㅠ
      요즘 눈코뜰새없이 바빠서
      강좌를 못쓰겠네용...