Surface2015.02.13 13:44
ScatterViewItem svi = new ScatterViewItem();
svi.Background = new SolidColorBrush(Colors.Transparent);
svi.ShowsActivationEffects = false;
svi.BorderBrush = System.Windows.Media.Brushes.Transparent;

RoutedEventHandler loadedEventHandler = null;
loadedEventHandler = new RoutedEventHandler(delegate
{
    svi.Loaded -= loadedEventHandler;
    Microsoft.Surface.Presentation.Generic.SurfaceShadowChrome ssc;
    ssc = svi.Template.FindName("shadow", svi) as Microsoft.Surface.Presentation.Generic.SurfaceShadowChrome;
    ssc.Visibility = Visibility.Hidden;
});
svi.Loaded += loadedEventHandler;

참고 : http://stackoverflow.com/questions/4602013/removing-shadow-from-scatterviewitem-isnt-working

Posted by 동동(이재동)
Surface2014.07.16 13:35

만들어봤다.

 

렌더링을 이용해서 따로 타이머를 이용하지 않았다.

 

LongClickButtonTest.zip

 

 

Posted by 동동(이재동)
Surface2014.06.03 11:06

Surface 프로젝트는 윈8에서 터치이벤트가 작동하지 않는다.

 

이때 SurfaceWindow를 Window로 바꿔주는것만으로 작동되게 만들수 있다.

 

Posted by 동동(이재동)
Surface2014.04.10 11:32

일단 스토리보드는 타겟이 있어야 한다 대부분 디자이너나 블랜드에서 만들면 타겟을

 

Storyboard.TargetName="xDetailItem"

 

이런코드가 삽입된다

 

일단 xaml에서 TargetName을 다 제거한다.. 그리고 이 타겟을 Behind에서 추가해준다.

 

일단 아래와 같이 제거

 

 <Storyboard x:Key="CalculatorOpen">
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)">
                <EasingDoubleKeyFrame KeyTime="0" Value="0" />
                <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="1" />
            </DoubleAnimationUsingKeyFrames>
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
                <EasingDoubleKeyFrame KeyTime="0" Value="0" />
                <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="1" />
            </DoubleAnimationUsingKeyFrames>
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
                <EasingDoubleKeyFrame KeyTime="0" Value="0" />
                <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="1" />
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>

 

 

자 이제 code behind에서

 

  ScatterViewItem svi = new ScatterViewItem()
                {
                    Center = (e.Source as DragAndDropScatterViewItem).Center,
                    Content = CalUc,
                    Orientation = 0,
                    Width = 263,
                    Height = 311,
                    RenderTransformOrigin = new Point(0.5, 0.5),
                    CanScale = false,
                };
                TransformGroup transGroup = new TransformGroup();
                transGroup.Children.Add(new ScaleTransform());
                transGroup.Children.Add(new TranslateTransform());
                transGroup.Children.Add(new RotateTransform());
                transGroup.Children.Add(new SkewTransform());
                svi.RenderTransform = transGroup;
                xScatterView.Items.Add(svi);

 

이런식으로 오브젝트를  하나 만들었다.

xaml에 Transform을 이용하기 떄문에 오브젝트에서도 이렇게 만들어줘야 된다.

 

자 간단하게 타겟을 지정해보자.

 

   Storyboard sb = this.Resources["CalculatorOpen"] as Storyboard;

   sb.Begin(svi);

 

아... 간단하다. begin(오브젝트)만 붙이면 된다.

Posted by 동동(이재동)
Surface2014.04.09 16:55

 private readonly Stopwatch _DoubleTapStopwatch = new Stopwatch();

 private Point _LastTapLocation;



  private bool IsDoubleTap(TouchEventArgs e)

        {

            Point currentTapPosition = e.GetTouchPoint(this).Position;

            bool tapsAreCloseInDistance = currentTapPosition.GetDistanceTo(_LastTapLocation) < 15;

            _LastTapLocation = currentTapPosition;


            TimeSpan elapsed = _DoubleTapStopwatch.Elapsed;

            _DoubleTapStopwatch.Restart();

            bool tapsAreCloseInTime = (elapsed != TimeSpan.Zero && elapsed < TimeSpan.FromSeconds(0.4));


            return tapsAreCloseInDistance && tapsAreCloseInTime;

        }


 private void DragAndDropScatterViewItem_PreviewTouchDown(object sender, TouchEventArgs e)

        {

            if (IsDoubleTap(e))

            {

//더블탭시 구현될 코드         

            }

        }



자세한 설명은 생략..

Posted by 동동(이재동)
Surface2014.04.08 11:51

비쥬얼스튜디오에 비디오 파일을 추가하고 단순히 비디오만 나오게 할려고 했는데 안되길래 봤더니 (물리 폴더는 잘되었다 c:\..)


출력디렉토리 복사를 항상복사나,변경된 내용만 복사를 안해놔서 그랬다... 그러니 경로를 못찾을수밖에


이걸 왜 디폴트로 안해놓는건지...



Posted by 동동(이재동)
Surface2014.01.14 11:00

일단 ScatterView안에서 ScatterViewItem A가 있으면 이걸 ScatterviewItem B로 끌어놓으면 없어지면서 이벤트가 발생하고 싶었다.

 

일단 Item A에 ContainerManipulationStarted 이벤트를 걸어서

 

 var svi = e.OriginalSource as ScatterViewItem;
            svi.BeginDragDrop(svi.DataContext);

 

이런식으로 BeginDragDrop 메소드를 실행해야만 한다.

 

그뒤에 끌어놓아질 Item B에는 AllowDrop = true로 하고

 

<s:ScatterViewItem s:SurfaceDragDrop.Drop="xScatterItem_Drop" AllowDrop="True"/>

 

xaml에서 s:SurfaceDragDrop.Drop="xScatterItem_Drop" 이렇게 이벤트를 걸면된다.

 

근데 이상하게 behind에는 안되는데 이유는 찾아봐야 할듯한다.

 

 

 

Posted by 동동(이재동)
Surface2012.05.10 17:47

사용자가 터치하는 Brush 크기를 조절하고 싶어서

SurfaceInkCanvasContainer.DefaultDrawingAttributes.Height = 7;
SurfaceInkCanvasContainer.DefaultDrawingAttributes.Width = 7;

이렇게 height,width값을 조정하였지만 적용이 되지 않았다.

문제는

SurfaceInkCanvasContainer.UsesTouchShape = false;

이것이 true로 되어 있어서였다.(기본이 True)

이걸 false로 하면 유저의 손가락 크기에 굵기가 달라지는게 아니라 일정하게 유지되도록 변경된다.

Posted by 동동(이재동)
Surface2012.05.10 11:05

우왕 이것때문에 삽질 많이 했다.

일단 내가 하고 싶었던건 ScatterViewItem내 컨트롤에서 버튼을 누르면 MaxWidth,MaxHeight로 변경하고 싶었다.

근데 이상하게 Content내에서 사이즈를 변경하면 외부 ScatterViewitem 크기는 변경되지 않고 내부의 Content만 크기가 커졌다. 그래서 그냥 확대되는 느낌? 사이즈는 그대로 두고..

그래서 Scale로 어떻게든 해볼려고 했지만 역시 리사이즈할때도 문제이고 근본적인 원인이 해결되지 않아서

길복이 형한테 물어봤더니 길복이형이 이미 구현해 놓은 코드가 있었다.

 

if (Owner != null)
           {
               var container = Owner.GetContainer(this);
               if (container != null)
               {
                   container.Width = this.MaxWidth;
                   container.Height = this.MaxHeight;
               }
           }

 

대충 이런코드다 Owner라는게 있어서 Container를 잡을수가 있다!!!!!

최고다… 이걸 몰랐으면 엄청 고생했을듯

Posted by 동동(이재동)
Surface2012.05.04 12:00

Xaml이 아닌 코드로 만들어서 범용적이고 실용적으로 사용 가능

public static class FadeAnimationControl
{
    public static void Fade(UIElement target, double ValueFrom, double ValueTo, double Duration)
    {
        DoubleAnimation da = new DoubleAnimation();
        da.From = ValueFrom;
        da.To = ValueTo;
        da.Duration = TimeSpan.FromSeconds(Duration);
        da.AutoReverse = false;

        System.Windows.Media.Animation.Storyboard.SetTargetProperty(da, new PropertyPath("Opacity"));

        System.Windows.Media.Animation.Storyboard.SetTarget(da, target);

        System.Windows.Media.Animation.Storyboard sb = new System.Windows.Media.Animation.Storyboard();
        sb.Children.Add(da);

        EventHandler eh = null;
        eh = (s, args) =>
        {
            //target.Visibility = Visibility.Collapsed;
            sb.Stop();
            sb.Completed -= eh;
            target.Opacity = ValueTo;
        };
        sb.Completed += eh;

        sb.Begin();
    }
}

참고 : http://forums.create.msdn.com/forums/p/87462/525024.aspx

Posted by 동동(이재동)
Surface2012.04.27 10:40

일반적으로 Button(ContentControl 상속)과 같이 Content를 넣으면 이를 표현해주는데 Text를 넣으면 Text를 이미지를 넣으면 Image를 이런식으로 알아서 표현해준다.

이를 구현하기 위해서

ContentControl을 상속받은 컨트롤을 하나 만들고

 public class VirtualKeyboard : ContentControl

해당 컨트롤 xaml에

<ContentPresenter Content="{TemplateBinding Content}" Width="300" Height="300"/>

이렇게 만들어 놓고

            <c:VirtualKeyboard >
                <c:VirtualKeyboard.Content>
                    <Image Source="Images/sample.jpg"/>
                </c:VirtualKeyboard.Content>
            </c:VirtualKeyboard>

 

이런식으로 Content를 주입하면 Image가 나타난다.

아주 기초적인것이지만 활용하면 편하니 활용하길~

참고: http://www.mediamob.co.kr/infoland/blog.aspx?id=278585

Posted by 동동(이재동)
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 동동(이재동)
Surface2012.04.25 14:41

반대로 Media.Color를 Brush로 바꾸는건 쉬웠지만

 

Brush를 Color로 바꾸는건 힘들었다.

 

var temp = ((e.Source as ListBox).SelectedItem as Brush);
         SolidColorBrush c = new BrushConverter().ConvertFromString(temp.ToString()) as SolidColorBrush;

         SurfaceInkCanvasContainer.DefaultDrawingAttributes.Color = c.Color;

내가 사용한 방법이다. brush를 SolidColorBrush로 BrushConvert의 도움을 받아서 컨버팅한후 Color프로퍼티를 이용하였다.

참고 : http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/fb164db0-c169-4d0e-85dc-c79163ea3aac/

Posted by 동동(이재동)
Surface2012.04.25 11:46

보통 control을 만들때 genneric.xaml에 디자인을 구현하고 x:Name을 이용해서 해당 control의 cs안에서 컨트롤 하고 싶을때

이렇게 하면 된다.

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using Microsoft.Surface.Presentation.Controls;

namespace MyControl
{
    [TemplatePart(Name = SurfaceInkCanvasName, Type = typeof(SurfaceInkCanvas))]
    public class DrawPanelControl : Control
    {
        //template
        internal const string SurfaceInkCanvasName = "xSurfaceInkCanvas";
        internal SurfaceInkCanvas SurfaceInkCanvasContainer;

        public DrawPanelControl()
        {
            DefaultStyleKey = typeof(DrawPanelControl);
        }

        public override void OnApplyTemplate()
        {
            SurfaceInkCanvasContainer = this.GetTemplateChild(SurfaceInkCanvasName) as SurfaceInkCanvas;

            SurfaceInkCanvasContainer.DefaultDrawingAttributes.Height = 10;
            SurfaceInkCanvasContainer.DefaultDrawingAttributes.Width = 10;
            SurfaceInkCanvasContainer.DefaultDrawingAttributes.Color = Colors.Red;

            base.OnApplyTemplate();
        }
    }
}

저렇게 TemplatePart를 class밖에서 잡고 OnApplyTemplate에서

SurfaceInkCanvasContainer = this.GetTemplateChild(SurfaceInkCanvasName) as SurfaceInkCanvas;

이렇게 정의 하면 된다.

generic.xaml에는 그냥 일반적으로 x:name을 썻다.

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:controls="clr-namespace:MyControl"
                    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                    xmlns:Custom="http://schemas.microsoft.com/surface/2008"
                    xmlns:sf="clr-namespace:Microsoft.Surface.Presentation.Controls;assembly=Microsoft.Surface.Presentation"
                    mc:Ignorable="d">

    <Style TargetType="{x:Type controls:DrawPanelControl}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type controls:DrawPanelControl}">
                    <Grid>
                        <sf:SurfaceInkCanvas x:Name="xSurfaceInkCanvas" Background="Bisque"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>
Posted by 동동(이재동)
Surface2012.04.25 11:25

어휴 그냥 내가 컨트롤 프로젝트를 만들었을때 그냥 일반 c# 프로젝트를 만들어서 그런거 같다.

 

일단 많은 레퍼런스를 추가해야하고

 

꼭 AssemblyInfo.cs에

 

[assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]

 

이구문이 추가 되어야 한다.

이구문이 추가 되기위해서

사용한 네임스페이스는

using System.Resources;

using System.Windows;

이두개가 using되어야 한다.

이거때문에 완전 삽질함

 

참고 : http://charlass.wordpress.com/2012/02/17/wpf-onapplytemplate-is-not-getting-called/

Posted by 동동(이재동)
Surface2011.09.14 19:18
Surface2011.05.27 11:15

휴 힘들었다. 거의 이틀만에 만들으라고해서 아직 surface 개념이 없던 나에게 철야까지 하면서

 

힘들게 만들었다. 기계가 바로 전날 와서 테스트를 못해봐서.. 에물레이터에 맞추어서 만들었는데

 

태그 인식이 잘안되고 됐다가 안됐다가를 반복해서 행사 바로 전날 다시 전체 수정을 했다..

 

Tagvisualizer를 이용해서 멋있게 만들었지만 약간 보여주기 용으로 급수정을 해서 마음이 안좋았다..

 

기계만 좋았어도 ㅠㅠ

 

간략하게 소개를 하자면

 

처음 기계를 켜면 이런 화면이 나온다.

 

image

 

그다음에 책을 올리면

 

image

 

 

 

 

image

 

image

 

image

 

이런식으로 책을 넘길때마다 화면이 바뀌고 동영상이 뜬다.

 

마지막에 Develope에 내이름이 써있다. ㅋㅋ

 

많은 사람들에게 시연하는것이라 긴장도 되었지만 재미 있었다. ㅋㅋ

 

실제 시연 동영상은 여기서 볼수 있다.

 

http://www.youtube.com/watch?feature=player_detailpage&v=ruZvqF9ynJY

Posted by 동동(이재동)
Surface2011.05.27 11:06

WPF에서 이런식으로 스토리를 보여주고 싶었다.(이건 완성된버전 ㅋㅋ)

 

image

 

이건 그냥 TextBlock으로 되는것이 아니다.

 

그래서 FlowDocument를 사용하였다..

 

일단 xaml에서 이렇게 코딩을 했다.

 

<FlowDocumentScrollViewer Grid.Row="1" Grid.ColumnSpan="2" VerticalScrollBarVisibility="Hidden" >
    <FlowDocument Background="Transparent">                                        
        <Paragraph FontFamily="Bell MT" FontSize="24" x:Name="DescriptionParagraph">
            <Floater Width="500"  HorizontalAlignment="Left">                            
                <BlockUIContainer>
                    <Rectangle Height="250" />
                </BlockUIContainer>
            </Floater>
            One Day, most of the town’s roads are ruined by the heavy rain. On that day, school bus-Schoobi happens to be late because of constructions on the road. Worrying that children may be waiting at the bus stop, Schoobi drives through the traffic with full speed, even though other cars are starring at him in a disapproving manner. Schoobi gets to a costal road, however, the road condition there is also messy. Dilly-dallying and regreting to go back. Schoobi ends up ramming into the guardail. Schoobi is now in the danger of falling down the cliff. Can Robocar Poli and his team save Schoobi?
        </Paragraph>
    
    </FlowDocument>
   
</FlowDocumentScrollViewer>
 
보면 알겠지만 FlowDocument에서 Paragraph를 사용하고 안에 Floater를 이용해서 안에 투명한 사각형을 왼쪽에 정렬하고 바깥쪽에 글을 입력하였다.
 
그럼 이제 안에 내용 Text를 계속 유동적으로 바꿔야 한다.
그럼 어떻게 해야할까? behind에서 수정하면 된다.
 
paragrah의 x:name을 DescriptionParagraph를 정의 했으니 이걸 변경하면 된다. 소스를 보자
 
private void SetDescriptionPlaceholder(string param)
        {
            DescriptionParagraph.Inlines.Remove(DescriptionParagraph.Inlines.Where(c => c is System.Windows.Documents.Run == true).Select(c => c).FirstOrDefault());
            DescriptionParagraph.Inlines.Add(param);
        }
 

이렇게 inline을 삭제하고 다시 추가하는 형식으로 바꾸었다.

 

이렇게 하면 끝~

Posted by 동동(이재동)
Surface2011.05.19 16:06

아 이것때문에 시간 아까운데 2시간이나 까먹었다…

 

실버라이트랑 다르게 이상하게

 

Blend로 VisualState를 만들고

 

VisualStateManager.GoToState(this, "Title", true);

 

이렇게 state간의 전환을 할려고 했으나 계속 false를 return 했다. ㅡ.ㅡ!!!

 

인터넷 찾아보니…

 

WPF 버그라던데…

 

해결법은

 

VisualStateManager.GoToElementState(this.Content as FrameworkElement, "Title", true);

 

이렇게 element단위에서 해야한다.. 내참 인터넷에 왜 이런거 해결하는 법 하나도 없는거야?

Posted by 동동(이재동)