Surface2012.04.26 10:08
private void Snapshot(UIElement source, double scale, int quality)
       {
           double actualHeight = source.RenderSize.Height;
           double actualWidth = source.RenderSize.Width;

           double renderHeight = actualHeight * scale;
           double renderWidth = actualWidth * scale;

           RenderTargetBitmap renderTarget = new RenderTargetBitmap((int)renderWidth, (int)renderHeight, 96, 96, PixelFormats.Pbgra32);
           VisualBrush sourceBrush = new VisualBrush(source);

           DrawingVisual drawingVisual = new DrawingVisual();
           DrawingContext drawingContext = drawingVisual.RenderOpen();

           using (drawingContext)
           {
               //drawingContext.PushTransform(new ScaleTransform(scale, scale));
               drawingContext.DrawRectangle(sourceBrush, null, new Rect(new Point(0, 0), new Point(actualWidth, actualHeight)));
           }
           renderTarget.Render(drawingVisual);

           JpegBitmapEncoder jpgEncoder = new JpegBitmapEncoder();
           jpgEncoder.QualityLevel = quality;
           jpgEncoder.Frames.Add(BitmapFrame.Create(renderTarget));

           using (FileStream stm = File.OpenWrite(@"C:\test2.png"))
               jpgEncoder.Save(stm);
       }

일단 소스는 이렇다 source에 해당 usercontrol을 넣는다.

만약 DrawingVisual에 넣어서 rectangle을 만들지 않으면 해당 유저컨트롤만 찍히는게 아니라 전체가 찍힌다.

전체가 찍히긴하지만 해당 컨트롤만 나옴

참고 :

http://www.grumpydev.com/2009/01/03/taking-wpf-screenshots/
Posted by 동동(이재동)
Windows Phone 72012.01.03 21:20

예를들어 하위 UserControl 안에

public double CurrentCount { get; set; }

 

이런 property가 있다고 하자. 이것을 하위 View에서 보고 싶다. 그럴때는?

바인딩을 이렇게 하면 된다.

  <ct:SelectPersonControl Margin="10" x:Name="SPC"/>
<TextBlock Text="{Binding Path=CurrentCount, ElementName=SPC}" />

이렇게 하면 UserControl의 CurrentCount값이 바인딩 된다.

 

너무 기초인가… 혹시나 하는 마음에 알아두길~

Posted by 동동(이재동)
Windows Phone 72012.01.03 21:16

회사에서 ViewModelBase(회사에서 쓰는 ViewModel dll)을 이용한다.

하지만 이건 ViewModel만들때 상속해서 써야 한다.

하지만 UserControl을 만들어 버리면 이미 UserControl을 상속받았기 때문에 ViewModelBase를 다중상속받아야 한다.

하지만 Property Binding이 목적이라면 이렇게도 쓸 수 있다.

 

#region CurrentCount

      private double _currentCount;

      /// <summary>
      ///
      /// </summary>
      public double CurrentCount
      {
          get
          {
              return _currentCount;
          }
          set
          {
              _currentCount = value;
              
              OnPropertyChanged("CurrentCount");
          }
      }

      #endregion CurrentCount

      #region Event

      /// <summary>
      /// PropertyChanged 이벤트 핸들러.
      /// </summary>
      public event PropertyChangedEventHandler PropertyChanged;

      /// <summary>
      /// OnPropertyChanged()
      /// </summary>
      /// <param name="propertyName"></param>
      protected void OnPropertyChanged(string propertyName)
      {
          if (PropertyChanged == null)
              return;
          PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
      }

      #endregion Event

이렇게 이벤드 핸들러를 만들어서 OnPropertyChanged를 구현한다.

Posted by 동동(이재동)
Windows Phone 72011.12.07 14:10

Custom UserControl을 만들고 안에 TextBox를 하나 넣었다고 가정하자

여기 TextBox에 Text를 바꾸기 위해서는 어떻게 하는게 좋을까?

Behind에서 그냥 강제로 바꾸는것이 좋을까? 아니다 그거보다 쉬운방법이 있다.

바로 DataContext에 넣어서 바인딩 하는 방법이다.

일단 유저컨트롤을 만들고 상위 Grid의 이름을 정하자 기본적으로 "LayoutRoot" 로 지정되어 있을것이다.

그리고 비하인드에서 의존 프로퍼티를 하나 만들자. 이름은 그냥 ItemSource로 지었다

#region ItemSource

       /// <summary>
       /// Gets or sets the ItemSource possible Value of the TransferTrnInfoModel object.
       /// </summary>
       public TrnInfoModel ItemSource
       {
           get { return (TrnInfoModel)GetValue(ItemSourceProperty); }
           set { SetValue(ItemSourceProperty, value); }
       }

       /// <summary>
       /// Identifies the ItemSource dependency property.
       /// </summary>
       public static readonly DependencyProperty ItemSourceProperty =
                   DependencyProperty.Register(
                         "ItemSource",
                         typeof(TrnInfoModel),
                         typeof(GeneralTrainInfoControl),
                         new PropertyMetadata(OnItemSourcePropertyChanged));

       /// <summary>
       /// ItemSourceProperty property changed handler.
       /// </summary>
       /// <param name="d">TrainInfoControl that changed its ItemSource.</param>
       /// <param name="e">DependencyPropertyChangedEventArgs.</param>
       private static void OnItemSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
       {
           GeneralTrainInfoControl _TrainInfoControl = d as GeneralTrainInfoControl;
           if (_TrainInfoControl != null)
           {
               _TrainInfoControl.SetItemSource((TrnInfoModel)e.NewValue);
           }
       }

       #endregion ItemSource

       private void SetItemSource(TrnInfoModel param)
       {
           LayoutRoot.DataContext = param;
       }

그리고 source를 받으면

LayoutRoot.DataContext = param;

이렇게 dataContext에 넣게 바꿨다.

TrnInfoModel은 모델 클래스이고

<ct:GeneralTrainInfoControl ItemSource="{Binding GeneralTrainInfoSource}">

이런식으로 사용 하면 된다.

물론 모델 클래스에는 값이 다 정의 해서 넘겨줘야 한다.

이렇게 하면 해당 UserControl에서 Text같은곳에 바인딩만 걸어주면 끝~

구지 textbox.Text = TrnInfoModel.name

이런식으로 일일히 하지 않아도 되는것이다.

그리고 그냥 usrcontrol만들고 그안에 text만 binding할려면 젤 쉬운방법은

위처럼 궂이 Itemsource 의존 프로퍼티를 만들지 않고

그냥 DataContext에 넣으면 된다.

Posted by 동동(이재동)
Windows Phone 72011.11.21 16:05

일단 UserControl을 하나 만들고

메인 페이지 xaml에 넣는다.

<uc:RadJobId x:Name="RadJobIDUserControl" Visibility="{Binding RadJobIdPopupVisiblity}"/>

이런식으로 넣었다. 이제 이 UserControl 안에 Button을 넣고

버튼을 클릭시에 메인페이지(상위 페이지)에 있는 메소드나 ViewModel에 접근해보겠다.

 

private void CancelBtn_Click(object sender, RoutedEventArgs e)
        {
            PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
            var parentView = frame.Content as ReserveTicketSelectView;
            var parentViewModel = parentView.DataContext as ReserveTicketSelectViewModel;
            parentViewModel.RadJobIdPopupVisiblity = Visibility.Collapsed;
        }

 

간단하다.

접근해서 viewModel의 Peroperty를 변경한 예제 이다.

Posted by 동동(이재동)
Windows Phone 72010.09.30 17:52

먼저 UserControl을 이용하여 Dependecy Property를 쓴 간략한 예제를 먼저 보자

<UserControl x:Class="WorldHoliday.Views.HolidayText"
 
    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}"
 
    x:Name="RootText"
 
    >    
 
    <StackPanel>
 
        <TextBlock Text="{Binding Path=HolidayTextValue,ElementName=RootText}" VerticalAlignment="Center"/>
 
        <Path Data="M0,52 L480.02109,52" Fill="#FFF4F4F5" Height="1" Margin="0,0,-1.021,7" Stretch="Fill" Stroke="White" UseLayoutRounding="False" VerticalAlignment="Bottom"/>
 
    </StackPanel>
 
</UserControl>
 
 

 

그냥 usercontrol에 Textbox 하나 넣은 것이다. 이미 구현된 완성본을 넣었다. 일단 완성 해 놓고 시작을 했다.

 

자 이제 behind코드를 보자.

public partial class HolidayText : UserControl
 
   {
 
       public string HolidayTextValue
 
       {
 
           get { return (string)GetValue(HolidayTextValueProperty); }
 
           set { SetValue(HolidayTextValueProperty, value); }
 
       }
 
 
       public static readonly DependencyProperty HolidayTextValueProperty =
 
          DependencyProperty.Register("HolidayTextValue", typeof(string), typeof(HolidayText), new PropertyMetadata(string.Empty));
 
 
 
 
       public HolidayText()
 
       {
 
           InitializeComponent();            
 
       }
 
   }

 

그냥 간단하게 넣은것이다.

 

약간 설명을 하자면

Name = 등록할 속성의 이름

Propeprty=  속성의 타입

ownerType = 속성을 포함한 부모의 타입

typeMetaData = 속성 메타데이타 지정 (보통 callback 함수를 지정함)

 

마지막은 null로 지정가능하고 필요에 따라서 call back 함수를 만들어서 사용할수도 있다. 자세한 설명은

 

http://drum-83.tistory.com/82

 

여기를 참조 하자

 

자 이제 이 유저컨트롤을 사용한 코드를 보자

 

HolidayText ht = new HolidayText()
 
{
 
    HolidayTextValue = day
 
}; 
 
 
HolidayMonthList.Children.Add(ht);

 

자 이제 이 간단한 코드를 자세히 살펴보자..

 

이건 HolidayText라는 유저 컨트롤에 HolidayTextValue라는 Dependency Property를 정의 하고 그냥 string형 값을

 

주면 usercontrol안의 TextBlock에 내용을 뿌려주는 것이다.

 

중요한 건 저렇게 Dependency Property를 주는데 꼭 ElementName을 줘야 한다는 것이다 중요!!!!

 

<TextBlock Text="{Binding Path=HolidayTextValue,ElementName=RootText}" VerticalAlignment="Center"/>

 

이부분에서 ElementName은 위에 UserControl에 x:Name="RootText" 이렇게 정의 하였다…

 

만약 ElementName을 주지 않는다면 바인딩이 제대로 되지 않으므로 주의 하자

 

참고 : http://decav.com/blogs/andre/archive/2007/05/27/wpf-binding-to-properties-in-your-usercontrol-or-window.aspx <—elementName의 중요성

Posted by 동동(이재동)