'Windows Phone 7'에 해당되는 글 113건

  1. 2010.08.09 [wp7] Navigate를 Page Control 이외에서 하기
  2. 2010.07.26 [wp7] 리소스 파일 적용하기 (지역화) 2
  3. 2010.07.13 [wp7] Windows 7 Phone SDK Beta 릴리즈
  4. 2010.07.09 [wp7] 유동적인 Button 에서 Template 입히기
  5. 2010.07.07 [wp7] 다른 프로젝트에 있는 페이지로 Navigate 하기
  6. 2010.06.29 [wp7] CommandPattern DataList의 Item Templete 안의 Button 이벤트 빼기
  7. 2010.06.28 [wp7] StartWith의 편리함 String내에서 자동완성 기능 할때 좋음.
  8. 2010.06.23 [wp7] ModelView에서 View의 Control을 제어 하고 싶을때?
  9. 2010.06.16 [WP7] List 내용값 정렬하기(Custrom List Sorting)
  10. 2010.06.15 [wp7] XmlSerializer 를 이용하여 xml 데이터를 만들어보자
  11. 2010.06.15 [wp7] CommandPatton 쓰기
  12. 2010.06.15 [wp7] mvvm 쓰는법 정리
  13. 2010.06.14 [wp7] Application Bar를 사용해보자.
  14. 2010.06.14 [wp7] Camel Case? Pascal Case? 네이밍 규칙?
  15. 2010.06.11 [wp7] Facebook 인증 및 게시물 올리기 2
  16. 2010.06.09 [wp7] Event Handler러 대신 Callback 이용하여 return 하기
  17. 2010.06.09 [wp7] Event Handler 에서 받은값 return 하기~
  18. 2010.06.08 [wp7] compact .net framework 에서는 SortDictionary를 사용할수 없다?
  19. 2010.06.07 [wp7] 윈도우폰 sdk에서 md5 를 사용할수없다?
  20. 2010.05.27 [wp7] XmlSerializer 하위 엘리먼트 로드 하기
  21. 2010.05.27 [wp7] XmlSerializer 사용하기
  22. 2010.05.26 [wp7] 외부 url xml 파서 하기..
  23. 2010.05.19 [wp7] textbox 선택시 keypad 바꾸기
Windows Phone 72010. 8. 9. 16:33

MVVM을 쓰면서 페이지 이동을 할때에는 꼭 Page 에서 해야만 했다.


즉 뷰딴에서만 이동이 가능했다.


예를 들면

var uri = new Uri(string.Format("/TypenWork;component/Views/OptionPage.xaml"), UriKind.RelativeOrAbsolute);
NavigationService.Navigate(uri);

이렇게 하여야만 했지만


그래서 꼭 behind딴에서 코딩을 하여 mvvm 고유의 깔끔함이 없어졌다.


하지만 페이지 이동을 딴 곳 즉 ViewModel 이나 Model쪽에서 하고 싶을때가 많다(거의 90%)


그럴때는 어떻게 할까... 언제까지 datacontext를 형변환 하여 사용할것인가?


팀장님이 발견한 방법이다


var temp = App.Current.RootVisual as PhoneApplicationFrame;
temp.Navigate(new Uri("/UnitConverter;component/Views/MainListView.xaml",UriKind.RelativeOrAbsolute));


이렇게 app의 RootVisual를 PhoneApplicationFrame을 캐스팅하여 사용하는 방법이다 굿~^^


이제 자유롭게 어디서든 Navigate 를 사용할수 있다.

Posted by 동동(이재동)
Windows Phone 72010. 7. 26. 16:22

이건 Silverlight나 WPF나 다 했던 것인데 잊어먹어서 다시 쓴다…

일단 리소스 파일을 하나 만든다. add new item~ 으로 만든후 리소스를 적는데

image

 

위에 보면 "Access Modifier” 에  internal로 되어있다. 이걸 public 으로 꼭 고치자  왜냐하면 나는 전 구역에 사용해야 하기때문이다 ~

 

<phone:PhoneApplicationPage.Resources>
<local:LocalizedStrings x:Key="LocalizedStrings"/>
</phone:PhoneApplicationPage.Resources>
 
자 이렇게 해당 View Xaml에 리소스를 등록하자 공용으로 사용하고 싶으면 app.xaml에 저장~
자  이제 리소스를 받는 클래스를 만들자~
 
public class LocalizedStrings
{
private static AppResources localizedresources = new AppResources();

public LocalizedStrings()
{
}

public AppResources LocalizedResources
{
get
{
return localizedresources;
}
}
}
 
이제 실제 Text 에 바인딩 시켜보자~
<TextBlock Text="{Binding Path=LocalizedResources.Title, Source={StaticResource LocalizedStrings}}" x:Name="textBlockListTitle" FontSize="60"/>            

리소스에  등록된 Title 이 나오는걸 볼수 있다.
Posted by 동동(이재동)
Windows Phone 72010. 7. 13. 15:16

드디어 오늘 나왔다.
지금까지 CTP 버전으로 얼마나 힘들게 개발하였던가?
근데 응? 추가된거는 별로 없고 클래스이름들만 다 바껴서 지금까지 CTP로 만들었던거 다시 교체 작업을 해야 한다 ㅠ.ㅠ

일단 다운은 http://www.silverlight.net/getstarted/devices/windows-phone/ 여기서 받을수 있고
바뀐점은 안에 문서를 보면 안다. 일단 내가 만든 프로젝트에서 바꿔야 하는것을 알아보자~

App.xaml

<!--RootFrame points to and loads the first page of your application-->
<Application.RootVisual>
<phoneNavigation:PhoneApplicationFrame x:Name="RootFrame" Source="/Views/ExchangeConverterMainView.xaml"/>
</Application.RootVisual>





이렇게 되어 있던 처음 스타트 페이지를 설정하는 부분이

Properties-WMAppManifest.xml 여기로 옮겨졌다(저 윗부분은 app,xaml에서 삭제할 것 )





<Tasks>
<DefaultTask Name ="_default" PlaceHolderString="Default task"/>
</Tasks>





기존 이렇게 되어 있던것이




<Tasks>
<DefaultTask Name ="_default" NavigationPage="/Views/ExchangeConverterMainView.xaml"/>
</Tasks>





이렇게 바꾸면 시작페이지가 잘 설정된다.



자 이제 예전의 sdk 레퍼런스를 지우자~ 원래 이걸 젤첨에 했어야 했는데 ㅋ



기존이 경고가 떳다.





이걸 삭제하고



새로 추가하자..  달라진점은 보면 알것이다~

그리고 app.xaml 정의 부분




<Application 
x:Class="ExchangeConverter.App"
xmlns:local="clr-namespace:ExchangeConverter"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone">





도 이렇게 간단하게 바꾸고~ 중요한건 app.xaml.cs 도 바꿔야 한다는것이다



여기에는 너무 많으니 차라리 새로운 프로젝트를 만들어서 app.xaml.cs에 내용을 복사해 넣자!!!




<phoneNavigation:PhoneApplicationPage
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phoneNavigation="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Navigation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:phone="clr-namespace:HugeFlow.Phone.Controls;assembly=HugeFlow.Phone.Controls"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" xmlns:HugeFlow_CommandPattern_Interactivity="clr-namespace:HugeFlow.CommandPattern.Interactivity;assembly=HugeFlow.MVVM" x:Name="phoneApplicationPage"
x:Class="ExchangeConverter.MainPage"
mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="800"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}">





기존 이렇게 되어있던 Page~ phoneNavigation으로 되어있던 것을

phoneNavigation을 바꾸고 phone으로 바꾸고 phonNavigation을 삭제하고 아까 레퍼런스에 추가했던 phone이랑 Shell을 추가하자(저위에 phone은 중복된거라 이름을 바꿨다)





<phone:PhoneApplicationPage
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
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"
xmlns:c="clr-namespace:HugeFlow.Phone.Controls;assembly=HugeFlow.Phone.Controls"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" xmlns:HugeFlow_CommandPattern_Interactivity="clr-namespace:HugeFlow.CommandPattern.Interactivity;assembly=HugeFlow.MVVM" x:Name="phoneApplicationPage"
x:Class="ExchangeConverter.MainPage"
mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="800"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}">





자 바꾸었다~

그리고 applicationBar도 업글이 되었는데 이건 Text를 추가를 꼭해줘야 한다 안하면 에러남 ~






<phone:PhoneApplicationPage.ApplicationBar>
<shell:ApplicationBar IsVisible="True">
<shell:ApplicationBarIconButton IconUri="Images/appbar.feature.settings.dark.png" x:Name="SettingButton" Click="SettingButton_Click" Text="Setting"/>
</shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>





이렇게 바꾸면 될듯~




또 바뀐게 머가 있을까?

Posted by 동동(이재동)
Windows Phone 72010. 7. 9. 16:38

유동적인 Button에서 Template를 입혀보자

foreach (var item in _appBoxModel.GetFavoriteListFromFile())
{
Button favoriteButton = new Button()
{
Content = item.Name,
DataContext = item,
Width = 150,
Height = 150,
FontSize = 15,
Template = this.Resources["xControl"] as ControlTemplate,
Style = Application.Current.Resources[item.Style] as Style

};





일단 유동적으로 만들어질 버튼에 templete을 지정하고


xaml에


 



<phoneNavigation:PhoneApplicationPage.Resources>                    

<ControlTemplate x:Name="xControl" TargetType="Button" >
<StackPanel>
<StackPanel>
<Image Source="{Binding Image}" Width="100" Height="100" />
</StackPanel>
<TextBlock Text="{Binding Name}" HorizontalAlignment="Center"/>
</StackPanel>
</ControlTemplate>
</phoneNavigation:PhoneApplicationPage.Resources>



 


이렇게 리소스로 넣으면 된다~ 바인딩 데이터는 dataContext로~
Posted by 동동(이재동)
Windows Phone 72010. 7. 7. 16:30

 

내가 할려던 일은 윈도우7 폰 프로젝트에서 만든 프로젝트를 하나로 합쳐서 한개의 어플로 관리해야 하는데 지금까지 만든 프로젝트를 쭉 불러와서 또 다른 하나의 솔루션을 만들었다.

여기서 나의 문제점이 생겼다.

 

일단 같은 프로젝트에 있는 xaml 끼리는 navigation 이 잘된다.

하지만 다른 프로젝트에 있는 xaml로 가야 된다면?

일단 생각해낸 방법이 children.add() 이다.. 이건 물론 되긴하지만 command patton 이나 application bar 가 로딩이 안되서 패스

그래서 도저히 navigationService.Navigate(URI) 밖에 방법이 없다고 생각하여 킴팀장님한테 헬프를 왜쳤더니 오전내내 찾아도 없던걸 한방에 찾아내셧다…

이런… 나도 나름 검색 잘한다고 생각했는데 ㅠ.ㅠ

결과적으로는 이렇다.

 

var uri = new Uri("/RandomNumber;component/Views/RandomNumber.xaml", UriKind.RelativeOrAbsolute);
NavigationService.Navigate(uri);



 


/프로젝트 이름;component/해당 xaml 경로


 


잘되지만 app.Xaml은 읽어오지 못하므로 ServiceLocator 나 app.xaml에 있는 스타일은 사용할수 없다.


 


 




Posted by 동동(이재동)
Windows Phone 72010. 6. 29. 10:43

점점 mvvm에 대해서 아는것 같다…

일반 컨트롤의 이벤트는 command를 이용해서 빼는것은 이제 조금씩 익숙해지고 있다.

하지만 ListBox안의 Template에서 이벤트를 빼야 한다면? 자 해보자

<ListBox x:Name="SearchCountryListBox" ItemsSource="{Binding SearchCountryListBoxItemSource}" Height="240">
 
                   <ListBox.ItemTemplate>
 
                       <DataTemplate>
 
                           <Grid>
 
                               <Grid.ColumnDefinitions>
 
                                   <ColumnDefinition Width="Auto" />
 
                                   <ColumnDefinition Width="*" />
 
                                   <ColumnDefinition Width="Auto" />
 
                               </Grid.ColumnDefinitions>
 
                               <Image Source="{Binding Flag}"  Width="80" Height="50" Grid.Column="0" />
 
                               <TextBlock Text="{Binding Name}"  FontSize="35" Grid.Column="1" Margin="40,0,40,0"/>
 
                               <Button x:Name="button" Content="button "  Grid.Column="2" >
 
                                   <i:Interaction.Behaviors>
 
                                       <HugeFlow_CommandPattern_Interactivity:ExecuteAncestorInstantCommandBehavior CommandName="SearchCountrySelectButtonCommand">
 
                                           <i:Interaction.Triggers>
 
                                               <i:EventTrigger SourceName="button" EventName="Click">
 
                                                   <i:InvokeCommandAction CommandName="CommandTriggers"/>
 
                                               </i:EventTrigger>
 
                                           </i:Interaction.Triggers>
 
                                       </HugeFlow_CommandPattern_Interactivity:ExecuteAncestorInstantCommandBehavior>
 
                                   </i:Interaction.Behaviors>
 
                               </Button>
 
                           </Grid>
 
                       </DataTemplate>
 
                   </ListBox.ItemTemplate>
 
               </ListBox>
 
 




 




보이는가? 버튼에 command pattern 적용한것을?



이렇게 만들려면 치는거보다 블랜드에서 하는게 편하다…



 



 



 



 





해당 listbox item template에 들어가서



 



 



 



일단 ExecuteAncestorInstatntCommandBehavior를 더블 클릭하여 만든다.





여기서 부턴 일반 commandPattern이랑 같으니까 생략~


아 그리고 중요한건 블랜드에서 CommandName을 쓸때 수동으로 쓸수 밖에 없다 DataBinding이 뜨지 않기때문에

만든 커맨드 이름을 쓰면 된다.^^

Posted by 동동(이재동)
Windows Phone 72010. 6. 28. 11:40

대부분 문자를 찾을때는 포함되어 있는지 없는지 알기 위해 Contains를 이용한다.. 하지만

 

Korea가 있는데 내가 Ko라고 쳤는데 Korea만 나와야하는데 Contains를 쓰면 reaKo도 나오게 된다...

 

이럴때 사용하는것이 StrignWith이다.

 

첫글자부터 사용해준다.

 

이거 없었으면 toArray로 하나하나 비교해야됬었을수도

 

참고 : http://msdn.microsoft.com/en-us/library/ms228630(VS.80).aspx

Posted by 동동(이재동)
Windows Phone 72010. 6. 23. 17:26

아 몸이 아프다… 이놈의 편도선 하지만 써놔야하지.. 이거 알고 보면 쉽고 예전에 내가 wpf할떄도 해서 포스팅해놨었는데

왜 어렵게 생각하고 있었는지 모르겠다.

 

일단 내가 할려고 하던것은 View에서 어떠한 이벤트가 일어나면(SelectChanged 이벤트가 일어남)

그 View에 있는 ListBox에 하나씩하나씩 추가하는것이 목표였다.

이걸 mvvm패턴을 안쓰면 무지 쉽다.. 그냥 behind코드에서 쓱싹하면 되니깐 누워서 떡먹기?

 

하지만 mvmm 무섭다~ ㅋㅋ 일단 selectchange event가 일어나면

Command패턴으로 View에서 변경된 값을 ModelView쪽에서 가지고 있는다.

하지만 다시 View에게 이 변경된값을 전달하는것은 쉽지 않다.. view가 static이 아닌이상…

 

그래서 생각해낸방법 ObservableCollection을 이용하는법이다.

가장쉬운 string을 예제로 들어보자…

ObservableCollection<string> tempList = new ObservableCollection<string>();
public ObservableCollection<string> ListboxSource
{
get
{
tempList.Add("hi 1");
tempList.Add("hi 2");
tempList.Add("hi 3");
return tempList;
}
}





일단 listbox xaml에는




<ListBox x:Name="xListBox" ItemsSource="{Binding ListboxSource}"/>



이렇게 바인딩이 되어있으므로 실행하면 ListBox에 hi 1,2,3값이 출력된다.


자 여기서 4를 추가해보자….. 물론 itemSource를 안건드리고 어떤 특정한 값이 변경될때마다 혹은 SelectChanged 이벤트가 발생하여 ListBox에 add를 해야할때


 


tempList.Add("lee jaedong");


 


그냥 이렇게 쓰면 바인딩 되어 ui에 4가 추가된다.


 


끝 아~ 지금 너무 피곤해서 여기까지 써야겠다..

Posted by 동동(이재동)
Windows Phone 72010. 6. 16. 15:44

머 요즘에 SortedList이다 SortDicturary 이런게 있는데 Compact .net Framework 에서는 다 무용지물이다..

이번에는 List박스에서 정렬을 해보자…

많은 방법이 이것이 쉽다~

일단 정렬시킬 기준점이 필요하다…

나같은 경우는 정렬을 하기 위해서 List<T> 즉 기준이될 index값을 넣고 정렬을한다.

 

List<SaveLogData> saveLogList = new List<SaveLogData>();





이런식으로 하나 만들었다. SaveLogData에는




public class SaveLogData
{
[XmlElement]
public int Index { get; set; }

[XmlElement]
public string Number { get; set; }
}





이런식이다.



데이터를 넣을때 인덱스 값을 차례대로 넣고 나중에 이값을 이용해서 정렬을 할것이다.



자 정렬을 하기 위한 클래스를 만들자.




public class ListSorter : IComparer<SaveLogData>
{
public int Compare(SaveLogData obj1, SaveLogData obj2)
{
return obj2.Index.CompareTo(obj1.Index);
}
}





이렇게 listSorter를 하나 만들고 그 안에서 역순으로 비교를 한다.




saveLogList.Sort(new ListSorter());



 


이렇게 하면 List가 역순으로 정렬된다.


자세한 내용은 여기서 참고 하였다.


 


 


Posted by 동동(이재동)
Windows Phone 72010. 6. 15. 18:27

일단 소스 부터 보자.

private void SaveLog(string value)
{
StringBuilder logXMLValue = new StringBuilder();

XmlWriterSettings xmlWriterSettings = new XmlWriterSettings()
{
OmitXmlDeclaration = true,
Encoding = Encoding.UTF8,
Indent = true
};

RandomData randomData = new RandomData()
{
Date = System.DateTime.Today.ToString(),
RandomNumberData = value
};

XmlWriter xmlWriter = XmlWriter.Create(logXMLValue, xmlWriterSettings);
XmlSerializer serializer = new XmlSerializer(typeof(RandomData));
serializer.Serialize(xmlWriter, randomData);
xmlWriter.Close();

//IsolatedStorageSettings.ApplicationSettings.Add("SaveLog", sampleXml);


}





 



XmlWriterSettings를 이용하여 세팅을 하고



RandomData(데이터 클래스) 를 생성해서 데이터를 입력하고



 




XmlWriter xmlWriter = XmlWriter.Create(logXMLValue, xmlWriterSettings); 





이렇게 xml data를 만들 StringBuilder형 logXmlValue를 만들면  시리얼라이즈가 끝나고 값이 저장된다.



 



그래서 머 logXmlValue값을 가지고 파일로 만들든 저장을 하든 요리를 하든 하면 된다.

Posted by 동동(이재동)
Windows Phone 72010. 6. 15. 15:47

일단 처음에 해야할것은

역시 HugeFlow dll 레퍼런스에 로드 하고 ViewModel에 을 상속받아서 쓴다.

일단 코드를 보자~

#region StartButtonCommand
       /// <summary>
       /// StartButton InstantCommand for ViewModel
       /// </summary>
       private ICommand _StartButtonCommand;
       public ICommand StartButtonCommand
       {
           get
           {
               return _StartButtonCommand;
           }
           set
           {
               _StartButtonCommand = value;
               OnPropertyChanged("StartButtonCommand");
           }
       }
 
       public void StartButton(object param)
       {
             // code here
       }
       #endregion StartButtonCommand
 
 


code snipper를 이용하면 ic 를 입력하면 instantCommand를 이용할수 있다.



그리고 생성자에



 
public RandomNumberViewModel()
       {
           StartButtonCommand = new InstantCommand<object>(StartButton);
           //StartRandomCommand = new InstantCommand<string>(StartRandom);
       }
 
 


이렇게 넣어주면 땡~



xaml에서는



 
<phoneNavigation:PhoneApplicationPage
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phoneNavigation="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Navigation"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone.Shell"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"    
    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" xmlns:HugeFlow_CommandPattern_Interactivity="clr-namespace:HugeFlow.CommandPattern.Interactivity;assembly=HugeFlow.MVVM" 
    x:Class="RanDomNumber.MainPage"
    mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="800"    
    x:Name="phoneApplicationPage" 
    DataContext="{Binding RandomNumberViewModel, Source={StaticResource ServiceLocator}}"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}">
    <i:Interaction.Behaviors>
        <HugeFlow_CommandPattern_Interactivity:ExecuteInstantCommandBehavior x:Name="StartButtonCommand" Command="{Binding StartButtonCommand}">
            <i:Interaction.Triggers>
                <i:EventTrigger SourceName="TestButton" EventName="Click">
                    <i:InvokeCommandAction CommandName="CommandTriggers"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </HugeFlow_CommandPattern_Interactivity:ExecuteInstantCommandBehavior>
    </i:Interaction.Behaviors>
 
 


보면 알겟지만



xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" xmlns:HugeFlow_CommandPattern_Interactivity="clr-namespace:HugeFlow.CommandPattern.Interactivity;assembly=HugeFlow.MVVM"



를 추가하고



블랜드를 이용하여



<i:Interaction.Behaviors>

        <HugeFlow_CommandPattern_Interactivity:ExecuteInstantCommandBehavior x:Name="StartButtonCommand" Command="{Binding StartButtonCommand}">


            <i:Interaction.Triggers>


                <i:EventTrigger SourceName="TestButton" EventName="Click">


                    <i:InvokeCommandAction CommandName="CommandTriggers"/>


                </i:EventTrigger>


            </i:Interaction.Triggers>


        </HugeFlow_CommandPattern_Interactivity:ExecuteInstantCommandBehavior>


    </i:Interaction.Behaviors>



이 구문을 만들었다 블랜드를 이용해서 만드는 방법을 알아보자~



silverlight 4 rc 버전을 이용했다(정식버전은 아직 지원안됨 이것떄문에 지웠다 다시깜 ㅠㅠ)





 



그냥 간단하게 보자



위에서부터 Asset-ExucteInstantCommand-그리고 커맨드가 생기면 커맨드 클릭한후 event trriger 등록 하고 숨겨진창을



클릭하여 SourceName을 선택한후  마우스로 컨트롤을 선택하고 Command에 가서 icommand 가 있는 메소드를 선택하면 된다.



마지막으로 x:name 즉 이름 넣는곳에 알기 쉽게 아까 만든거와 같은 커맨드 네이밍을 입력하자



여기서는 StartButtonCommand~

Posted by 동동(이재동)
Windows Phone 72010. 6. 15. 10:44

 

일단 설명은 나중에 하고 설명부터 하자….(레퍼런스에 hugeflow.mvvm 이랑 core dll 넣는것은 기본~)

일단 ViewModels라는 폴더(안만들어도 상관없음)를 만들고 class를 만들자 예를들어 RandomNumberView.model.cs

그뒤에 Service locator를 등록하자

serviceLocator.cs 를 만들고

이렇게….

namespace RanDomNumber
{
    public class ServiceLocator
    {
        RandomNumberViewModel _randomNumberViewModel;
 
        public RandomNumberViewModel RandomNumberViewModel
        {
            get
            {
                _randomNumberViewModel = new RandomNumberViewModel();
                return _randomNumberViewModel;
            }
        }
    }
}
 
 


그리고 xaml MainPage에 등록하기전에 App.xaml에서 리소스를 추가시킨다.



 



 
<Application 
    x:Class="RanDomNumber.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"       
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:system="clr-namespace:System;assembly=mscorlib"
    xmlns:local="clr-namespace:RanDomNumber"
    xmlns:mpc="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls"
    xmlns:phoneNavigation="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Navigation">
    
    <!--RootFrame points to and loads the first page of your application-->
    <Application.RootVisual>
        <phoneNavigation:PhoneApplicationFrame x:Name="RootFrame" Source="/MainPage.xaml"/>
    </Application.RootVisual>
 
    <!-- Resources for following the Windows Phone design guidelines -->
    <Application.Resources>
        <!--************ THEME RESOURCES ************-->        
        <local:ServiceLocator x:Key="ServiceLocator" />
        <!-- Color Resources -->
 
 


xmlns:local="clr-namespace:RanDomNumber"



<Application.Resources>

       <!--************ THEME RESOURCES ************—>        
       <local:ServiceLocator x:Key="ServiceLocator" />



이렇게 추가하면



MainPage.xaml에서



 
 
    x:Class="RanDomNumber.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phoneNavigation="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Navigation"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone.Shell"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="800"    
    DataContext="{Binding Source={StaticResource ServiceLocator},Path=RandomNumberViewModel}"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}">
 
 


DataContext="{Binding Source={StaticResource ServiceLocator},Path=RandomNumberViewModel}"



이거를 추가해주면 된다.



 



브레이크 포인터를 ServicerLocator에서 걸어서 꼭 확인해보자.. 안되면 xaml에 잘못 쓰거나 이름을 다르게 썻을 경우이다.









자이제 아까 만든 RandomNumberView.model.cs 에 소스를 붙여 넣어보자…



 
namespace RanDomNumber.ViewModels
{
    public class RandomNumberViewModel : ViewModelBase
    {
        public RandomNumberViewModel()
        {
            
        }
 
        private string _StartNumberValue = "30";
        private string _EndNumberValue = "100";
        private string _countNumberValue = "2";
 
        public string StartNumberValue
        {
            get
            {
                return _StartNumberValue;
            }
            
            set
            {
                if (_StartNumberValue != value)
                {
                    _StartNumberValue = value;
                }
            }            
        }
 
        public string EndNumberValue
        {
            get
            {
                return _EndNumberValue;
            }
 
            set
            {
                if (_EndNumberValue != value)
                {
                    _EndNumberValue = value;
                }                
            }
        }
 
        public string CountNumberValue
        {
            get
            {
                return _countNumberValue;
            }
 
            set
            {
                if (_countNumberValue != value)
                {
                    _countNumberValue = value;
                }                      
            }
        }        
    }
}
 
 








이렇게  modelview를 작성해서 바인딩할 값을 넣어보자.샘플로~



이제 바인딩할 컨트롤에 적용해보자…




<TextBlock Text="Start"  Grid.Row="0"/>
<TextBox x:Name="StartNumberText" Text="{Binding StartNumberValue}" Grid.Row="1" />
<TextBlock Text="End" Grid.Row="2" />
<TextBox x:Name="EndNumberText" Text="{Binding EndNumberValue}" Grid.Row="3" />
<TextBlock Text="Count" Grid.Row="4" />
<TextBox x:Name="CountNumberText" Text="{Binding CountNumberValue}" Grid.Row="5" />





 



그러면 이렇게 보일것이다.



 





 



끝~ 다음은 커맨트 패턴~

Posted by 동동(이재동)
Windows Phone 72010. 6. 14. 17:58

윈도우용 폰에서 아래에 Application Bar를 사용해보자~

image
 

하단에 버튼 3개 요게 application bar이다 ㅋㅋ

일단 소스를 보자..

xaml 상단을 보자

<navigation:PhoneApplicationPage 
x:Class="RanDomNumber.Page1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:navigation="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Navigation"
xmlns:phoneNavigation="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Navigation"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone.Shell"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
SupportedOrientations="Portrait"
mc:Ignorable="d" d:DesignHeight="800" d:DesignWidth="480"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}">

<phoneNavigation:PhoneApplicationPage.ApplicationBar>
<shell:ApplicationBar IsVisible="True">
<shell:ApplicationBarIconButton IconUri="/Images/appbar.new.dark.png" x:Name="BackButton" Click="BackButton_Click"/>
<shell:ApplicationBarIconButton IconUri="/Images/appbar.refresh.dark.png" x:Name="StartButton" Click="StartButton_Click"/>
<shell:ApplicationBarIconButton IconUri="/Images/appbar.feature.settings.dark.png" x:Name="SettingButton"/>
</shell:ApplicationBar>
</phoneNavigation:PhoneApplicationPage.ApplicationBar>

<Grid x:Name="LayoutRoot" Background="{StaticResource PhoneBackgroundBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="170"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>

<!--This is the name of the application and page title-->
<Grid Grid.Row="0" x:Name="TitleGrid">
<StackPanel>
<TextBlock Text="APP BOX" x:Name="textBlockPageTitle"/>
<TextBlock Text="Random Number" x:Name="textBlockListTitle" FontSize="60"/>
</StackPanel>
</Grid>

<!--This section is empty. Place new content here Grid.Row="1"-->
<Grid Grid.Row="1" x:Name="ContentGrid">

<TextBlock x:Name="ResultBox" Text="0" FontSize="200" HorizontalAlignment="Center"/>
</Grid>
</Grid>
</navigation:PhoneApplicationPage>





보이는거와 같이 젤 상단에서 설정한다. 대부분 grid안에 넣을꺼라고 생각했지만 오산..



물론 Phonenavigation 이랑 shell 레퍼런스는 추가해야 한다.



이벤트도 xaml에서 걸었다…(이상하게 이건 behind에서  안되더라…)



그리고 그냥 사용하면 된다. 이미지 uri  바꿔서…



그리고 젤 중요한거….



이미지 비쥬얼 스튜디오에 첨부시키면 이미지 속성(Build Action)이 resource로 나오는데 이걸 모두 Content 로 고친다.



이거만 해놓으면 문제 없다… Content를 꼭 기억하자…

Posted by 동동(이재동)
Windows Phone 72010. 6. 14. 11:22

예전 이노티브 회사를 다닐때는 Xaml의 X:name을 무조건 x네임 이런식으로 썻었다…

 

예를 들면? PlayButton은 xPlayButton 이런식으로… 나름 알기 쉽고 편했다…

 

하지만 휴즈 플로우에서는 CamelCase를 쓴다… 주로 C#에서 쓰는 표준이다…

 

단지 x를 빼버린거랑 똑같다. ㅡ.ㅡ;;

 

구분을 그냥 대문자로 하는것이다….(이건 머 다 아는것이니…)

 

하지만 Came Case는 첫글자를 소문자를 쓰는것이다. 이건 주로 변수 이름 쓸떼… (ex : playName)

 

그리고 Pascal Case라는게 있다… 이건 첫글자를 대문자로 쓰는것이다. (ex: PlayName)

 

근데 xaml에는 pascal case를 쓰는것같다(휴즈 플로우에서는…)

 

일단 머 믿어보자~ ㅋㅋ

추가(이길복 팀장님이 알려주신거)

CamelCase – 대문자로 시작하는 camelcase를 뜻합니다.
camelCase – 소문자로 시작하는 camelcase를 뜻합니다.

MSDN문서에서는 Lower camel case를 Camel Case라 일컫고, Upper camel case를 Pascal Case라 일컫습니다.
사실 Pascal Case는 Camel Case에 포함되는 개념입니다.
소문자로 시작하는 Lower camel case와 대문자로 시작하는 Upper camel case가 있습니다.
이 중 Lower camel case가 Pascal Case라고 알려져 있습니다.

Posted by 동동(이재동)
Windows Phone 72010. 6. 11. 16:47

어이쿠 완전 삽질 많이 했다….

 

첨에는 몰라서 샘플이 있는 오래된 rest api로 하였다… 하지만 역시 오래된거라서 그런지 안되는것도 많았다.. 특히 리스트 받아오는 부분.;;

 

이번에는 Graph API를 이용해서 facebook 정보를 얻고 feed를 던져보자~

 

일단 여기 Facebook API 공식 페이지를 참고하였다…

 

http://developers.facebook.com/docs/api#publishing

 

근데 iphone이나 안드로이드 폰이나 머 다 sdk가 있지만 여긴 없어서 노가다 작업을 할수 밖에 없다…ㅠㅠ

 

일단 제일 중요한… 인증부분 이것만 끝나면 거의 다 끝났다고 보면 된다.

 

일단 메소드를 사용 하기 위해서는 Access_token이 필요한데 또 이것을 얻기 위해서는 나름 험난한 여정(?)을 격어야 한다…

 

Access_token을 얻기위해 파라미터로는 api key(client_id), redirect_url, code 가 필요한데 여기서 또 code를 얻기위해서 페이지를 한번 이동시켜야 한다.

 

그렇기 때문에 webBrower control이 필요하다…

 

일단 code를 얻기 위한 url을 보자…

 

https://graph.facebook.com/oauth/authorize?client_id={Api Key}&redirect_uri=http://www.facebook.com/connect/login_success.html

 

api key는 facebook 어플에서 얻을수 있고 리다이렉션 url은 가장 유명하고 굴러다니는것을 썻다..내껀 웹이 아니기떄문에 (나름 웹 어플^^)

 

여기에 접속을 하게 되면 http://www.facebook.com/connect/login_success.html?code=블라블라블라~

 

라고 url로 준다.. 그러면 저것을 얻어서 이제 본격적으로 AccessToken을 얻자~

 

https://graph.facebook.com/oauth/access_token?client_id={API KEY}&redirect_uri=http://www.facebook.com/connect/login_success.html&client_secret=3d870d8731e358c16ae6c54530450561&code={아까 받은 코드}

 

이러면 Json으로 Access_Token을 리턴해준다.

 

이걸로 멀할수 있느냐?

 

Friends: https://graph.facebook.com/me/friends
News feed: https://graph.facebook.com/me/home
Profile feed (Wall): https://graph.facebook.com/me/feed
Likes: https://graph.facebook.com/me/likes
Movies: https://graph.facebook.com/me/movies
Books: https://graph.facebook.com/me/books
Notes: https://graph.facebook.com/me/notes
Photo Tags: https://graph.facebook.com/me/photos
Photo Albums: https://graph.facebook.com/me/albums
Videos: https://graph.facebook.com/me/videos
Events: https://graph.facebook.com/me/events
Groups: https://graph.facebook.com/me/groups

 

다양하다… ;;

 

예를들면

나의 news Feed를 받고 싶으면

 

https://graph.facebook.com/me/home?access_token={아까받은거}

 

넣으면 되는것이다..

 

혹시 저 url에 뒤에 일일히 token값을 넣기 귀찮다면 meta data를 이용하면 편하다.

https://graph.facebook.com/me?metadata=1

 

그리고 포스트 글을 쓸떼는

 

https://graph.facebook.com/me/feed?access_token?message=Helloworld(난 프로그래머니깐)

 

근데 중요한건 꼭 post방식으로 보내야 한다..Get은 안된다~

 

그리고 xml로는 안보내준다는거…

 

wp7에서는 이렇게 구현했다..

 

쓰는부분

public void WriteFeed(string accessToken, Action<string, Exception> callback)
       {
           string value = string.Empty;
 
           WebClient webClient = new WebClient();
           webClient.Headers["Content-Type"] = "";
 
           //var tokenUrl = new Uri(GetTokenUrl(code), UriKind.Absolute); //url도 나중에 파라미터로 넣으면 좋을듯            
           var url = GetWrtieFeedUrl(accessToken, "I am posting to my own feed");
           webClient.UploadStringAsync(new Uri(url),"POST",string.Empty);
           
           webClient.UploadStringCompleted += (s, e) =>
           {
               if (e.Error == null)
               {
                   value = e.Result;
               }
               callback(value, null);
           };            
       }
 
       public string GetWrtieFeedUrl(string token,string message)
       {            
           var url= string.Format("https://graph.facebook.com/me/feed?access_token={0}&message={1}",token,HttpUtility.UrlEncode(message));
 
           return url;
       }
 
 


 



인증부분



 
 
        public void  GetFacebookToken(string code, Action<string, Exception> callback)
        {
            string value = string.Empty;
 
            WebClient webClient = new WebClient();            
            var tokenUrl = new Uri(GetTokenUrl(code), UriKind.Absolute); //url도 나중에 파라미터로 넣으면 좋을듯
            
            webClient.DownloadStringAsync(tokenUrl);
            webClient.DownloadStringCompleted += (s, e) =>
                {
                    if (e.Error == null)
                    {
                        value = e.Result;
                    }
                    callback(value, null);
                };            
        }
public string GetTokenUrl(string code)
    {   
        return string.Format("https://graph.facebook.com/oauth/access_token?client_id={0}&redirect_uri={1}&client_secret={2}&code={3}",FacebookConfigrationManager.GetData("clientId"),FacebookConfigrationManager.GetData("redirectUrl"),FacebookConfigrationManager.GetData("clientSecret") ,code);            
    }
 
 


 



나중에 소스 첨부해야겠다~ 손이 피곤 ㅠㅠ

Posted by 동동(이재동)
Windows Phone 72010. 6. 9. 16:38
아까랑 다르게 이번에는 callback을 이용해서 해보겠다....

소스코드가 이상하게 올라가서 이제부터 <pre>태그를 써서 올려야겠다 ㅡ.ㅡ;;

 


 
public MainPage()
        {
            InitializeComponent();
 
            SupportedOrientations = SupportedPageOrientation.Portrait | SupportedPageOrientation.Landscape;
            Download.start(onStartComplete);                        
        }
 
        private void onStartComplete(string value, Exception ex)
        {
            Debug.WriteLine(value);
        }
 
 
 






일단 알아보기 쉽게 아까 소스를 재사용(?) 했다.





역시 download class가 있고 거기서 webClient에서 다운받은 웹소스를 저장혹은 출력하는것이다.







헉 더 간단하다. 그냥 onStartComplete 메소드 하나 만들어서 파라미터로 값을 넣는다.







사실 이것보다 이것을 먼저 봐야 할것이다.







download.cs



 
public class Download
    {
        public static void start(Action<string,Exception> callback)
        {
            WebClient webRequest = new WebClient();
            var apiURI = new Uri("http://www.google.co.kr", UriKind.RelativeOrAbsolute);
 
            webRequest.DownloadStringAsync(apiURI);
            webRequest.DownloadStringCompleted += (s, e) =>
                {
                    string value = "Good Data"; //보낼데이타 e를 보내도 됨
                    callback(value, null);
                };
        }
    }
 
 
 



코드가 한결 가벼워졌다...
</STRING,EXCEPTION>보면 Action 이라는것을 이용해서 값이랑 exception을 받고 DownloadCompete 시에 저 데이터를 callback 하는것이다.

이것도 말보다는 직접 소스를 보는게 나을것이다.

샘플소스

</STRING,EXCEPTION>[#FILE|Call_Back_Sample.zip|pds/201006/09/37/|mid|0|0|pds20|0#]


</STRING,EXCEPTION></STRING,EXCEPTION>
Posted by 동동(이재동)
Windows Phone 72010. 6. 9. 16:12

휴~ 이거 때문에 엄청 힘듬었다.



일단 내가 원하는건



Silverlight 혹은 wp7 에서 



async를 하여 데이터를 받거나 이벤트에서 얻어온값을 리턴시키는것을 하고 싶었다 예를 들면



 public static void start()

{

WebClient webRequest = new WebClient();

var apiURI = new Uri("http://www.google.co.kr", UriKind.RelativeOrAbsolute);



webRequest.DownloadStringAsync(apiURI);

webRequest.DownloadStringCompleted += new DownloadStringCompletedEventHandler(webRequest_DownloadStringCompleted);

}




이렇게 웹에 있는 내용을 다운받아서



static void webRequest_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)

{



}



이부분에서 구글 웹에 있는 페이지를 그 상위 페이지나 다른 class 에게 리턴 받고 싶었다...



이렇게 string webData = Download.Start();



근데 보면 알겠지만 DownloadStringCompleted 이벤트 메소드는 void 형이다... 어떻케 리턴시킬것인가?



만약 이벤트 뒤 webRequest.DownloadStringAsync(apiURI); 이부분뒤에 return을 한다고 해도 다운로드가 시작도 되기전에



이미 값을 리턴해 줘서 null값이 들어갈것이다...



그러면 방법은 Download가 다 되었을때 값을 리턴시켜야 한다. 



여기서 난 별짓을 다해보았지만 안되서 킴팀장님한테 물어봐서 겨우 알아냈다 (덕분에 핫식스 2개가 나갔지만)



방법은 Event핸들러를 밖에서 잡고 있는것과 Callback을 이용하는것이다.



일단 이벤트 핸들러를 이용해서 알아보자~





일단 Download.cs 라는 웹에서 긁어 오는 클래스가 있고



여기서 긁어온 웹데이타를 저장하는 mainpage.cs(기본) 가 있다. 



download class 전체 소스다



public class Download

{

//이벤트를 건다

public static event EventHandler<AsyncCompletedEventArgs> startCompleted;



public static void start()

{

WebClient webRequest = new WebClient();

var apiURI = new Uri("http://www.google.co.kr", UriKind.RelativeOrAbsolute);



webRequest.DownloadStringAsync(apiURI);

webRequest.DownloadStringCompleted += new DownloadStringCompletedEventHandler(webRequest_DownloadStringCompleted);

}



static void webRequest_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)

{

string value = "Good Data"; //보낼데이타 e를 보내도 됨



if (startCompleted != null)

{

startCompleted(null, new AsyncCompletedEventArgs(null,false,value));

}

}

}




위에 보면 알겠지만  public static event EventHandler<AsyncCompletedEventArgs> startCompleted;



이렇케 이벤트를 걸고



if (startCompleted != null)

{

       startCompleted(null, new AsyncCompletedEventArgs(null,false,value));

}



이렇게 전달할값 value를 보낸다.



mainPage에서는 



 public MainPage()

{

InitializeComponent();

SupportedOrientations = SupportedPageOrientation.Portrait | SupportedPageOrientation.Landscape;



Download.start();

Download.startCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(Download_startCompleted);

}



void Download_startCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)

{

Debug.WriteLine(e.UserState);

}




이렇게 아까 download class 에서 선정한 이벤트가 끝났을시  출력한다.



즉 다운로드가 끝났을때 출력한다는것이다. 이것을 저장을 하던지 요리를 하면 되는것이다.



알고 보면 쉽지만 인터넷에 나와있지 않다.... (단한군대도... 내가 구글링이 실력이 부족한가...)



일단 나중에 헷갈릴수 있으니 파일로 등록해 놓자.



sample for wp7



[#FILE|event_handler_sample.zip|pds/201006/09/37/|mid|0|0|pds20|0#]



Posted by 동동(이재동)
Windows Phone 72010. 6. 8. 17:03

사용할수 없다. ㅠㅠ


그래서 그냥 만들었다..


/// <summary>
/// Compact .Net Framework 에서 SortDictionary를 지원하지를 않아 직접 구현
/// /// </summary>
/// <param name="parameters"></param>
private Dictionary<string, string> SortDictionaryConverter(Dictionary<string, string> parameters)
{
var sortParameters = new Dictionary<string, string>();
var sortParametersEnum = from k in parameters.Keys orderby k select k;

foreach (var item in sortParametersEnum)
{
sortParameters.Add(item, parameters[item]);
}

return sortParameters;
}

Posted by 동동(이재동)
Windows Phone 72010. 6. 7. 18:22


System.Security.Cryptography에 있어야 할께없다.


왜 그럴까... 아마 뺏나보다 ㅡ.ㅡ;;;

그래서 4.0 framework 에 있는 dll도 붙여보고 별짓을 다했지만

결국 삽질로 끝나고 그냥 md5를 구현한 파일을 찾아보았다(만들기에는 어렵기에 ㅠㅠ)

그래서 찾아낸...

일단 전체 소스는 이렇고

다운은

[#FILE|md5core.cs|pds/201006/07/37/|mid|0|0|pds19|0#]


/Copyright (c) Microsoft Corporation.  All rights reserved.
using System;
using System.Text;

// **************************************************************
// * Raw implementation of the MD5 hash algorithm
// * from RFC 1321.
// *
// * Written By: Reid Borsuk and Jenny Zheng
// * Copyright (c) Microsoft Corporation.  All rights reserved.
// **************************************************************

// Simple struct for the (a,b,c,d) which is used to compute the mesage digest.   
struct ABCDStruct
{
    public uint A;
    public uint B;
    public uint C;
    public uint D;
}

public sealed class MD5Core
{   
    //Prevent CSC from adding a default public constructor
    private MD5Core() {}

    public static byte[] GetHash(string input, Encoding encoding)
    {
        if (null == input)
            throw new System.ArgumentNullException("input", "Unable to calculate hash over null input data");
        if (null == encoding)
            throw new System.ArgumentNullException("encoding", "Unable to calculate hash over a string without a default encoding. Consider using the GetHash(string) overload to use UTF8 Encoding");

        byte[] target = encoding.GetBytes(input);

        return GetHash(target);
    }

    public static byte[] GetHash(string input)
    {
        return GetHash(input, new UTF8Encoding());
    }

    public static string GetHashString(byte[] input)
    {
        if (null == input)
            throw new System.ArgumentNullException("input", "Unable to calculate hash over null input data");

        string retval = BitConverter.ToString(GetHash(input));
        retval = retval.Replace("-", "");

        return retval;
    }

    public static string GetHashString(string input, Encoding encoding)
    {
        if (null == input)
            throw new System.ArgumentNullException("input", "Unable to calculate hash over null input data");
        if (null == encoding)
            throw new System.ArgumentNullException("encoding", "Unable to calculate hash over a string without a default encoding. Consider using the GetHashString(string) overload to use UTF8 Encoding");
       
        byte[] target = encoding.GetBytes(input);

        return GetHashString(target);
    }

    public static string GetHashString(string input)
    {
        return GetHashString(input, new UTF8Encoding());
    }

    public static byte[] GetHash(byte[] input)
    {
        if (null == input)
            throw new System.ArgumentNullException("input", "Unable to calculate hash over null input data");

        //Intitial values defined in RFC 1321
        ABCDStruct abcd = new ABCDStruct();
        abcd.A = 0x67452301;
        abcd.B = 0xefcdab89;
        abcd.C = 0x98badcfe;
        abcd.D = 0x10325476;

        //We pass in the input array by block, the final block of data must be handled specialy for padding & length embeding
        int startIndex = 0;
        while (startIndex <= input.Length - 64)
        {
            MD5Core.GetHashBlock(input, ref abcd, startIndex);
            startIndex += 64;
        }
        // The final data block.
        return MD5Core.GetHashFinalBlock(input, startIndex, input.Length - startIndex, abcd, (Int64)input.Length * 8);
    }

    internal static byte[] GetHashFinalBlock(byte[] input, int ibStart, int cbSize, ABCDStruct ABCD, Int64 len)
    {
        byte[] working = new byte[64]; 
        byte[] length = BitConverter.GetBytes(len);

        //Padding is a single bit 1, followed by the number of 0s required to make size congruent to 448 modulo 512. Step 1 of RFC 1321 
        //The CLR ensures that our buffer is 0-assigned, we don't need to explicitly set it. This is why it ends up being quicker to just
        //use a temporary array rather then doing in-place assignment (5% for small inputs)
        Array.Copy(input, ibStart, working, 0, cbSize);
        working[cbSize] = 0x80;

        //We have enough room to store the length in this chunk
        if (cbSize <= 56)
        {
            Array.Copy(length, 0, working, 56, 8);
            GetHashBlock(working, ref ABCD, 0);
        }
        else  //We need an aditional chunk to store the length
        {
            GetHashBlock(working, ref ABCD, 0);
            //Create an entirely new chunk due to the 0-assigned trick mentioned above, to avoid an extra function call clearing the array
            working = new byte[64];
            Array.Copy(length, 0, working, 56, 8);
            GetHashBlock(working, ref ABCD, 0);
        }
        byte[] output = new byte[16];
        Array.Copy(BitConverter.GetBytes(ABCD.A), 0, output, 0, 4);
        Array.Copy(BitConverter.GetBytes(ABCD.B), 0, output, 4, 4);
        Array.Copy(BitConverter.GetBytes(ABCD.C), 0, output, 8, 4);
        Array.Copy(BitConverter.GetBytes(ABCD.D), 0, output, 12, 4);
        return output;
    }

    // Performs a single block transform of MD5 for a given set of ABCD inputs
    /* If implementing your own hashing framework, be sure to set the initial ABCD correctly according to RFC 1321:
    //    A = 0x67452301;
    //    B = 0xefcdab89;
    //    C = 0x98badcfe;
    //    D = 0x10325476;
    */
    internal static void GetHashBlock(byte[] input, ref ABCDStruct ABCDValue, int ibStart)
    {
        uint[] temp = Converter(input, ibStart);
        uint a = ABCDValue.A;
        uint b = ABCDValue.B;
        uint c = ABCDValue.C;
        uint d = ABCDValue.D;

        a = r1(a, b, c, d, temp[0 ], 7,  0xd76aa478);
        d = r1(d, a, b, c, temp[1 ], 12, 0xe8c7b756);
        c = r1(c, d, a, b, temp[2 ], 17, 0x242070db);
        b = r1(b, c, d, a, temp[3 ], 22, 0xc1bdceee);
        a = r1(a, b, c, d, temp[4 ], 7,  0xf57c0faf);
        d = r1(d, a, b, c, temp[5 ], 12, 0x4787c62a);
        c = r1(c, d, a, b, temp[6 ], 17, 0xa8304613);
        b = r1(b, c, d, a, temp[7 ], 22, 0xfd469501);
        a = r1(a, b, c, d, temp[8 ], 7,  0x698098d8);
        d = r1(d, a, b, c, temp[9 ], 12, 0x8b44f7af);
        c = r1(c, d, a, b, temp[10], 17, 0xffff5bb1);
        b = r1(b, c, d, a, temp[11], 22, 0x895cd7be);
        a = r1(a, b, c, d, temp[12], 7,  0x6b901122);
        d = r1(d, a, b, c, temp[13], 12, 0xfd987193);
        c = r1(c, d, a, b, temp[14], 17, 0xa679438e);
        b = r1(b, c, d, a, temp[15], 22, 0x49b40821);

        a = r2(a, b, c, d, temp[1 ], 5,  0xf61e2562);
        d = r2(d, a, b, c, temp[6 ], 9,  0xc040b340);
        c = r2(c, d, a, b, temp[11], 14, 0x265e5a51);
        b = r2(b, c, d, a, temp[0 ], 20, 0xe9b6c7aa);
        a = r2(a, b, c, d, temp[5 ], 5,  0xd62f105d);
        d = r2(d, a, b, c, temp[10], 9,  0x02441453);
        c = r2(c, d, a, b, temp[15], 14, 0xd8a1e681);
        b = r2(b, c, d, a, temp[4 ], 20, 0xe7d3fbc8);
        a = r2(a, b, c, d, temp[9 ], 5,  0x21e1cde6);
        d = r2(d, a, b, c, temp[14], 9,  0xc33707d6);
        c = r2(c, d, a, b, temp[3 ], 14, 0xf4d50d87);
        b = r2(b, c, d, a, temp[8 ], 20, 0x455a14ed);
        a = r2(a, b, c, d, temp[13], 5,  0xa9e3e905);
        d = r2(d, a, b, c, temp[2 ], 9,  0xfcefa3f8);
        c = r2(c, d, a, b, temp[7 ], 14, 0x676f02d9);
        b = r2(b, c, d, a, temp[12], 20, 0x8d2a4c8a);

        a = r3(a, b, c, d, temp[5 ], 4,  0xfffa3942);
        d = r3(d, a, b, c, temp[8 ], 11, 0x8771f681);
        c = r3(c, d, a, b, temp[11], 16, 0x6d9d6122);
        b = r3(b, c, d, a, temp[14], 23, 0xfde5380c);
        a = r3(a, b, c, d, temp[1 ], 4,  0xa4beea44);
        d = r3(d, a, b, c, temp[4 ], 11, 0x4bdecfa9);
        c = r3(c, d, a, b, temp[7 ], 16, 0xf6bb4b60);
        b = r3(b, c, d, a, temp[10], 23, 0xbebfbc70);
        a = r3(a, b, c, d, temp[13], 4,  0x289b7ec6);
        d = r3(d, a, b, c, temp[0 ], 11, 0xeaa127fa);
        c = r3(c, d, a, b, temp[3 ], 16, 0xd4ef3085);
        b = r3(b, c, d, a, temp[6 ], 23, 0x04881d05);
        a = r3(a, b, c, d, temp[9 ], 4,  0xd9d4d039);
        d = r3(d, a, b, c, temp[12], 11, 0xe6db99e5);
        c = r3(c, d, a, b, temp[15], 16, 0x1fa27cf8);
        b = r3(b, c, d, a, temp[2 ], 23, 0xc4ac5665);

        a = r4(a, b, c, d, temp[0 ], 6,  0xf4292244);
        d = r4(d, a, b, c, temp[7 ], 10, 0x432aff97);
        c = r4(c, d, a, b, temp[14], 15, 0xab9423a7);
        b = r4(b, c, d, a, temp[5 ], 21, 0xfc93a039);
        a = r4(a, b, c, d, temp[12], 6,  0x655b59c3);
        d = r4(d, a, b, c, temp[3 ], 10, 0x8f0ccc92);
        c = r4(c, d, a, b, temp[10], 15, 0xffeff47d);
        b = r4(b, c, d, a, temp[1 ], 21, 0x85845dd1);
        a = r4(a, b, c, d, temp[8 ], 6,  0x6fa87e4f);
        d = r4(d, a, b, c, temp[15], 10, 0xfe2ce6e0);
        c = r4(c, d, a, b, temp[6 ], 15, 0xa3014314);
        b = r4(b, c, d, a, temp[13], 21, 0x4e0811a1);
        a = r4(a, b, c, d, temp[4 ], 6,  0xf7537e82);
        d = r4(d, a, b, c, temp[11], 10, 0xbd3af235);
        c = r4(c, d, a, b, temp[2 ], 15, 0x2ad7d2bb);
        b = r4(b, c, d, a, temp[9 ], 21, 0xeb86d391);

        ABCDValue.A = unchecked(a + ABCDValue.A);
        ABCDValue.B = unchecked(b + ABCDValue.B);
        ABCDValue.C = unchecked(c + ABCDValue.C);
        ABCDValue.D = unchecked(d + ABCDValue.D);
        return;
    }

    //Manually unrolling these equations nets us a 20% performance improvement
    private static uint r1(uint a, uint b, uint c, uint d, uint x, int s, uint t)
    {
        //                  (b + LSR((a + F(b, c, d) + x + t), s))
        //F(x, y, z)        ((x & y) | ((x ^ 0xFFFFFFFF) & z))
        return unchecked(b + LSR((a + ((b & c) | ((b ^ 0xFFFFFFFF) & d)) + x + t), s));
    }

    private static uint r2(uint a, uint b, uint c, uint d, uint x, int s, uint t)
    {
        //                  (b + LSR((a + G(b, c, d) + x + t), s))
        //G(x, y, z)        ((x & z) | (y & (z ^ 0xFFFFFFFF)))
        return unchecked(b + LSR((a + ((b & d) | (c & (d ^ 0xFFFFFFFF))) + x + t), s));
    }

    private static uint r3(uint a, uint b, uint c, uint d, uint x, int s, uint t)
    {
        //                  (b + LSR((a + H(b, c, d) + k + i), s))
        //H(x, y, z)        (x ^ y ^ z)
        return unchecked(b + LSR((a + (b ^ c ^ d) + x + t), s));
    }

    private static uint r4(uint a, uint b, uint c, uint d, uint x, int s, uint t)
    {
        //                  (b + LSR((a + I(b, c, d) + k + i), s))
        //I(x, y, z)        (y ^ (x | (z ^ 0xFFFFFFFF)))
        return unchecked(b + LSR((a + (c ^ (b | (d ^ 0xFFFFFFFF))) + x + t), s));
    }

    // Implementation of left rotate
    // s is an int instead of a uint becuase the CLR requires the argument passed to >>/<< is of
    // type int. Doing the demoting inside this function would add overhead.
    private static uint LSR(uint i, int s)
    {
        return ((i << s) | (i >> (32-s)));
    }

    //Convert input array into array of UInts
    private static uint[] Converter(byte[] input, int ibStart)
    {
        if(null == input)
            throw new System.ArgumentNullException("input", "Unable convert null array to array of uInts");
       
        uint[] result = new uint[16];
       
        for (int i = 0; i < 16; i++)
        {
            result[i] = (uint)input[ibStart + i * 4];
            result[i] += (uint)input[ibStart + i * 4 + 1] << 8;
            result[i] += (uint)input[ibStart + i * 4 + 2] << 16;
            result[i] += (uint)input[ibStart + i * 4 + 3] << 24;
        }
      
        return result;
    }
}

출처 : http://www.izpia.com/main.php?page=board&home=9&&mode=LIST&ktype=T&kword=NULL&tab=1&lang=1&pno=1&no=9&idx=0

Posted by 동동(이재동)
Windows Phone 72010. 5. 27. 12:01

그냥 기본 1뎁스 


<ArticleData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ename>0</ename>
<sign>33</sign>
</ArticleData>


로드는 쉽다.. 클래스하나만 만듣면 되니깐 


하지만 하위 엘리먼트가 있는경우는?


예를 들어

<xavierresponse responsecode="200">
<fx_date>2010-05-26</fx_date>
<title>Xavier Finance - Exchange rates for 2010-05-26</title>
<link>http://finance.xaviermedia.com/</link>
<exchange_rates>
<basecurrency>EUR</basecurrency>
<fx_date>2010-05-26</fx_date>
<fx basecurrency="EUR">
<currency_code>EUR</currency_code>
<rate>1.0</rate>
</fx>
<fx basecurrency="EUR">
<currency_code>USD</currency_code>
<rate>1.230900</rate>
</fx>


이렇케 쭉 나가는거라면?


하위 안에 엘리먼트가 있고 또 안에 엘리먼트가 있으면


public class xavierresponse
{
[XmlElement]
public string fx_date { get; set; }

[XmlElement]
public List<exchange_rates> exchange_rates { get; set; }

[XmlElement]
public List<string> fx { get; set; }

[XmlElement]
public string basecurrency { get; set; }
}

public class exchange_rates
{
[XmlElement]
public string basecurrency { get; set; }

[XmlElement]
public string fx_date { get; set; }

[XmlElement]
public List<fx> fx { get; set; }
}

public class fx
{
[XmlElement]
public string currency_code { get; set; }

[XmlElement]
public string rate { get; set; }
}


이런식으로 하위의 엘리먼트들을 또 클래스로 만들어야 된다.


그러면 하위까지 긁어와서 보여준다..


물론 클래스 이름이랑 엘리먼트 이름이랑은 동일해야 한다.~


Posted by 동동(이재동)
Windows Phone 72010. 5. 27. 11:37

ㅋㅋ 해보니 별로 어려운게 아니다.



일단 큰것을 위해 샘플을 만들었다..



일단 C#이랑 중복되니 c# 부터 하겠다.



테스트를 위해



이런 xml을 하나 생성하고?



<?xml version="1.0" encoding="utf-16" ?>

<ArticleData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<ename>0</ename>

<sign>33</sign>

</ArticleData>



그리고 이걸 저장할 클래스를 하나 만든다.

public class ArticleData

{

[XmlElement]

public string ename { get; set; }



[XmlElement]

public string sign { get; set; }

}

}



코드에는

using (var reader = new StreamReader(@"d:\util\test2.xml"))

{

XmlSerializer xs = new XmlSerializer(typeof(ArticleData));

  var temp = (ArticleData)xs.Deserialize(reader);

  }



이렇게 한다.

그렇게 되면 temp 에 데이터가 저장이 되게 된다.



정말 심플하다... 



중요한건 xml에 상단에



<ArticleData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">



이렇게 되있는데 



클래스 이름을 꼭 ArticleData로 해야된다는 점이다..



그래야 직렬화가 된다.



c#은 끝냈으니 이제 wp7(실버라이트) 에서 해보자



웹기반이니



 var xmlWebPathUri = new Uri("http://api.finance.xaviermedia.com/api/latest.xml", UriKind.Absolute);

WebClient client = new WebClient();

client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);

client.DownloadStringAsync(xmlWebPathUri);




이런식으로 외부로부터 xml을 가져와서



 void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)

{

StringReader _stream = new StringReader(e.Result);

XmlReader _reader = XmlReader.Create(_stream);



System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer(typeof(xavierresponse));

  var temp = (xavierresponse)xs.Deserialize(_reader);



}



xavierresponse 이것이 xml 페이지  상단 이름이다 xml을 분석해서 클래스를 만들자~











Posted by 동동(이재동)
Windows Phone 72010. 5. 26. 10:57

wpf 처럼 하다가 피봄....


왜 system.xml에 XmlDocument를 지원안하는지 모르겠네?


힘들게 XmlReader로 해야 하잖아 ㄷㄷㄷ


var xmlWebPathUri = new Uri("http://www.naver.com/include/timesquare/widget/exchange.xml", UriKind.Absolute);
WebClient client = new WebClient();
client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
client.DownloadStringAsync(xmlWebPathUri);


일단 내가하는것은 외부 xml 읽고


void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
     StringReader stream = new StringReader(e.Result);

     XmlReader reader = XmlReader.Create(stream);
}


머 이렇케 해서 하면 된다. wpf는 로컬이여서 너무 쉬웠나보다...


머 디버깅해보면 다 나오는것들~


참고 : http://silverlight.whatisreal.com/2008/06/using-xmlreader-in-silverlight.php


실버라이트니까 따라가자~

Posted by 동동(이재동)
Windows Phone 72010. 5. 19. 09:58
c#에서는
InputScope inputScope = new InputScope();
InputScopeName inputScopeName = new InputScopeName();
inputScopeName.NameValue= InputScopeNameValue.Url;
inputScope.Names.Add(inputScopeName);

textbox.InputScope = inputScope;


xaml에서는

<TextBox Text="Hello Don">
<TextBox.InputScope>
<InputScope>
<InputScopeName NameValue="Url" />
</InputScope>
</TextBox.InputScope>
</TextBox>


inputScopeName.NameValue= InputScopeNameValue.Url;


이부분을 수정하면 번호만으로도 나오게 할수 있고 머 별게 다된다.


멤버는 


http://msdn.microsoft.com/en-us/library/system.windows.input.inputscopenamevalue.aspx


여기서 볼수 있다... 역시 msdn 짱



출처 

http://www.uxmagic.com/blog/post/2010/03/20/Working-with-the-On-Screen-Keyboard-with-Windows-Phone-7.aspx

http://www.ginktage.com/?p=603



추가  


하나하나 알아보기 힘듣므로 한꺼번에 보자~


http://dotnetgui.blogspot.com/2010/03/windows-phone-7-development-using.html


샘플은 내가 5분만에 만들었다.~


[#FILE|InputScopesViewer.zip|pds/201005/19/37/|mid|0|0|pds20|0#]






Posted by 동동(이재동)