GSI

데이터 바인딩#1 - 기본

WPF 2007. 11. 16. 10:04 |

▶데이터 바인딩#1 - 기본
데이터 바인딩#2 - Binding Mode
데이터바인딩#3 - DataContext
데이터 바인딩#4 - TextBox vs Run
데이터 바인딩#5 - FrameWorkElement Demo
데이터 바인딩#6 - IValueConverter

이번 내용은 기본 바인딩에 대해서 설명 합니다.
ScrollBar와 Label 연동 부분으로 설명합니다.

데이터 바인딩은 컨트롤과 엘리먼트의 데이터 연결하는 것을 말한다.
데이터 바인딩은 CheckBox 컨트롤을 불리언 변수에 연결하는 것과 같은 간단한 방법 부터 데이터 베이스와 데이터 엔터리 패널을 연결하는 것처름 복잡해질 수 있다.

데이터 바인딩은 소스(Source)와 타깃(target)가 필요하다.
일반적으로 소스는 데이터, 타깃은 컨트롤을 의미 한다. 하지만 컨트롤의 값을 데이터로 전달할 경우는 소스가 타깃이 되는 경우가 있다.

가장간단하게 데이터 바인딩을 생각해 보면 ScrollBar의 Value 프로퍼티를 보여주기 위한 Label 컨트롤을 생각해 볼 수 있다.

// 바인딩 소스
<ScrollBar Name="scroll" Orientation="Horizontal" Margin="20" Maximum="100" LargetChange="10" SmallChange="1" />
// 바인딩 타깃
<Label HorizontalAlignment="Center" Content="{Binding ElementName=scroll, Path=Value}"/>

바인딩 자체는 언제나 타깃 내에서 생성된다.
Content="{Binding ElementName=scroll, Path=Value}"

중괄호 내에 Binding가 정의 되어 있고, Binding 클래스의 프로퍼티중 ElementName, Path가 정의에 포함되게 된다. 즉, ElementName에 ScrollBar의 Name가 포함되고 Path에 ScrollBar의 Value가 포함되게 된다.
여기서 보게 되면 기존의 xaml 코드와 다르게 Binding의 코드는 내부에 "" 이것으로 묶지를 않았다. 솔직히 이 부분은 나도 아직도 애메하다. ^^
위의 코드를 조금더 풀어 쓰게 되면 아래와 같이 된다.

<Label HorizontalAlignment="Center">
   <Label.Content>
      <Binding ElementName="scroll" Path="Value" />
   </Label.Content>
</Label>

위의 코드 보다는 조금더 보기는 편한거 같다. 인텔리센서도 먹으니 편한듯 보이고 두개의 연관성을 고려해서 코드 짜는 법을 익혀야 할거 같다.

위의 코드로 구성되는 프로그램은 아래와 같습니다.
사용자 삽입 이미지

다음 내용은 Binding에 대해서 조금더 상세한 내용을 정리 하겠습니다.

참고 ^^
본 내용은 "찰스페졸드의 WPF"의 내용을 이해 하고 나름 생각과 같이 정리한 겁니다.
제제가 가해질 경우 바로 삭제하도록 하겠습니다. ^^;
Posted by gsi
:

사용자 삽입 이미지

Blend에서 처리한 Animation의 정보중에서 Value 값을 바꾸는 곳을 테스트한
데모 입니다.

관련소스
Posted by gsi
:

Blend를 사용해서 Animation을 작성하다 보면 Blend에서 작성한 코드만 가지고 안될때가 많다. 코드 중간 중간 실시간적으로 받은 데이터의 값을 에니메이션 Value에 추가해서 사용해야 할때가 많아 진다.

이럴 경우 코드 비하인드에서 스토리 보드 부터 다 짜게 되면야.
값 접근하는게 어렵지는 않다. 하지만 에니메이션 정보를 코드로 다 짜준다는건 캐 노가다거나 거의 비효율적인 작업이 될 것이다. 그래서 몇가지 예제를 찾아 봤는데.

다른 방법이 하나 있긴 하다 공도님 사이트에서 본것 ^^..
이것 > http://gongdo.tistory.com/110

하지만 그것도 좀 그렇다. 왠지 작업량이 복잡해 지고 불편하다.

그래서 내부 구조를 조금씩 보면서 아래와 같은 접근 방법을 사용하였다.

<Storyboard x:Key="Timeline1">
 <DoubleAnimationUsingKeyFrames x:Name="TestAni1" BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">
  <SplineDoubleKeyFrame x:Name="TestSpline1" KeyTime="00:00:00" Value="0"/>
  <SplineDoubleKeyFrame x:Name="TestSpline2" KeyTime="00:00:01" Value="192"/>
 </DoubleAnimationUsingKeyFrames>
 <DoubleAnimationUsingKeyFrames x:Name="TestAni2" BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)">
  <SplineDoubleKeyFrame x:Name="TestSpline3" KeyTime="00:00:00" Value="0"/>
  <SplineDoubleKeyFrame x:Name="TestSpline4" KeyTime="00:00:01" Value="62.206"/>
 </DoubleAnimationUsingKeyFrames>
</Storyboard>

위의 코드도 결국 cs 파일에서 하는거 처름 다 추가 되는거라고 생각하고.
아래와 같이 분해 해보았다.

이런 XAML 코드가 있다고 하고 192라는 값을 코드 중간에 바꾸고자 할때
아래와 같이 하면 접근이 되는 것을 확인 하였다.

// 스토리 보드를 가져 온다.
Storyboard st = (Storyboard)this.FindResource("Timeline1");
// 스토리 보드의 내부 타임 라인 그룹정보를 가져 온다.
TimelineCollection tgroup = (TimelineCollection)st.Children;
// TimelineCollection 안에 있는 객체 하나를 가져 온다.
// 근데 여기서 int형 배열 정보만 받는다. 그럼 내가 몇번째 것을 제어 하고 싶은지
// 알아야 할거 같다.
DoubleAnimationUsingKeyFrames dAniFrame = (DoubleAnimationUsingKeyFrames)tgroup[0];
// SplineDoubleKeyFrame  정보를 가져 오기 위해서
// DoubleKeyFrameCollection 의 정보를 가져 온다.
DoubleKeyFrameCollection dAniFrameGroup = (DoubleKeyFrameCollection)dAniFrame.KeyFrames;
// SplineDoubleKeyFrame  정보를 가져 온다.
SplineDoubleKeyFrame spAniFrame = (SplineDoubleKeyFrame)dAniFrameGroup[1];
// Value 값을 조정할 수 있게 된다.
spAniFrame.Value = 500;

코드 량은 좀 되는거 같아도 접근을 할 수 있는거 같은데요.
사실 이거 말고 다른게 있을듯도 한데.. ms가 이거 만들면서 이런거 고민했을텐데.
사실 다른건 아직 방법을 찾지 못했네요.

혹시 아시면 코멘트 부탁해요.

Posted by gsi
:

IIS 설정하고 xbap용 파일을 Publish를 할때 제대로 되지 않거나.
웹 페이지를 실행 하면 응용 프로그램 다운로드 실패 등의 오류가 나게 된다.
솔직히 이 부분은 쉽게 이해가 가지 않는다.

몇번 경우의 수를 두고 더 테스트를 해보는 수 밖에..

Publish를 할때도 localhost 로 시작하는 것과 IP를 할당하는것에
실패도 있을 수 있는거 같다.

우선 게시 하는거 자체가 이렇게 어려우니 ^^..
그냥 프로젝트로 조금 개발해서 올리는 방향으로 해야 할거 같다.

이거야원 ^^

Posted by gsi
:

출처 : http://xamlxaml.com/2006/08/04/unique-interfaces-in-wpfxaml/

PostItBoard Demo


이런 느낌의 사진 게시판은 느낌이 좋을거 같다.
카테고리별로 나누고 새로운 사진들은 바람에 흔들거린다던지 하는 효과도 좋은거 같다.

누르면 크게 보여 주고 다시 사라지고 하는 효과도 좋을거 같고
포스트잇을 연상케 하는 이 디자인은 나름 멋진듯 하네.

Posted by gsi
:

Win Form 만으로는 WPF 만큼의 효과를 구사하지 못한다.
그래서 생각한게 Custom Control 형태를 취하게 하면서 WPF 컨트를을 Win Form에
연동이 가능하다는 것을 알게 되었다.

즉, Visual Studio 2008에 있는 ElementHost를 선택해서 Form에 추가 합니다.

사용자 삽입 이미지





이후에 화면은 아래와 같으며, References에 windowBase, WindowsFormsIntegration이 추가 됩니다.
사용자 삽입 이미지

하지만 WPF 관련 xaml 파일이 없기 때문에 위와 같이 아무것도 적용할 수 없습니다.

이후에 xaml 파일을 추가 해야 합니다.
xaml 파일만 추가할 수도 있지만, WPF 어플리케이션을 추가한 후에 Blend로 작업하고,
프로젝트를 추가해서 하는게 더 좋은거 같습니다.

프로젝트 생성 후에 Window1.xaml 파일을 그대로 사용하지는 못하는듯 합니다.
UserControl을 상속 받은 xaml 파일을 사용해야 하기 때문에 파일을 하나 추가합니다.

이제 아래와 같은 추가할 수 있는 화면이 나옵니다.
사용자 삽입 이미지


이제 추가 하고 나면 아래의 화면 처름 배치를 할 수 있습니다.
사용자 삽입 이미지











이후의 컨트롤 접근은 다를거 없습니다.
해당 컨트롤.컨트롤이름. 이렇게 진행 됩니다.

궁금한 내용 있으시면.. 코멘트 부탁해요 ^^

Posted by gsi
:

이전에도 소스를 여기에 올린적이 있는듯 하다.
Tool3D 라이브러리를 사용해서 적용하는 3D의 효과를 어떻게 구현할지 이것을 가지고 생각을 해보자.

[관련 이미지]

사용자 삽입 이미지

Cube에 InteractiveMesh 적용 예





















[관련 소스]

Posted by gsi
:

WPF 이미지 표시하기

WPF 2007. 10. 5. 09:44 |

WPF 에서 이미지 표시하기

BitmapImage 는 XAML 로딩을 위해 최적화된 특수한 BitmapSource 이고 Image 컨트롤의  Source로 이미지를 표시하기 쉬운 방법입니다.

이미지 컨트롤 사용하기
Image는 프레임워크 엘리먼트이고 애플리케이션에서 이미지를 표시하는 주된 수단입니다. XAML 에서 Image는 어트리뷰트 문법 또는 프로퍼티 문법의 두 가지 방법으로 사용될 수 있습니다. 다음 예제는 어트리뷰트 문법과 프로퍼티 태그 문법을 모두 사용하여 이미지를 200 픽셀 너비로 그리는 바업ㅂ을 보여줍니다. 어트리뷰트 문법과 프로퍼티 문법의 더 자세한 정보는 Dependency Properties Overview를 참고 하십시오.

XAML
<!-- 간단한 이미지 렌더링. 그러나 이 방법으로 렌더링 하는 것은 애플리케이션 메모리의 사용량에는 좋지 않습니다. 같은 결과를 더 적은 메모리로 생성하는 아래쪽 마크업을 참고 하십시오. -->
<Image Width = "200" Source = "c:\Temp\aaa.jpg"/>

<Image Width = "200">
   <Image.Source>
      <!-- 상당한 애플리케이션 메모리를 아끼기 위해 이미지 소스의 BitmapImage의 DecodePixelWidth나 DecodePixelHeight 값을 원하는 높이와 너비로 설정하십시오. 그렇게 하지 않으면 애플리케이션은 이미지를 화면에 표시될 크기가 아닌 그것의 보통 크기로 렌더링 될 것이라고 생각하고 캐슁될 것입니다.-->
      <BitmapImage DecodePixelWidth = "200" UriSource = "c:\test\aaa.jpg"/>
   </Image.Source>
</Image>

다음 예제는 코드를 사용하여 이미지를 200 픽셀 너비로 그리는 방법을 보여줍니다.

노트 :
BitmapImage는 다중 속성에서 초기화 최적화를 위해 ISupportInitilize 인터페이스를 구현합니다. 속성 변경은 오직 객체 초기화 중에만 발생할 수 있습니다. 초기화가 시작되었음을 알리는 신호로 BeginInit을 호출하고 초기화가 완료되었음을 알리는 신호로 EndInit을 호출합니다. 일단 초기화 되면 속성 변경은 무시됩니다.

C#
// 이미지 엘리먼트 생성
Image myImage = new Image();
myImage.Width = 200;

//소스 생성
BitmapImage myBitmapImage = new BitmapImage();

// BitmapImage.UriSource는 반드시 BeginInit/EndInit 블럭 내에 있어야 합니다.
myBitmapImage.BeginInit();
myBitmapImage.UriSource = new Uri(@"c:\test\aaa.jpg");
myBitmapImage.DecodePixelWidth = 200;
myBitmapImage.EndInit();

//이미지 소스 설정
myImage.Source = myBitmapImage;

Posted by gsi
:

Expression 프로그램을 실행하다가 오류가 났다. 프로그램이 실행 되면서 바로 죽는 것이다.
DirectX 용 프로그램을 개발하다 보면 "Use Debug Version of Direct3D"로 설정해 놓고 하는게 대부분인데.. 그것 때문에 실행이 되지 않았던 것이다. ^^

Expression 용 프로그램을 테스트 하기 위해서는 "Use Retail Version of Direct3D" 로 체크 하기 바란다.

Posted by gsi
:

Posted by gsi
:

Where does a Binding find its data?

If you’ve look at much WPF Xaml you’ve probably seen bindings like this:

 

<TextBlock Text="{Binding Name" />

 

… which binds the Text property of the TextBlock to the Name property of some data object.

 

The question that begets is:  where does the data come from?  The rest of this post looks at the answer.

 

 

Properties on Binding

 

The Binding class has a few properties that provide ways to let you set the source of the data onto the Binding, depending on what works best for your situation.   Binding looks like this:

 

public class Binding : BindingBase

{

    ...

    public object Source { get; set; }

    public string ElementName { get; set; }

    public RelativeSource RelativeSource { get; set; }

    ...

}

 

 

The Source Property

 

The most straightforward way to set the source of the Binding is to use the Source property.  One of the more common ways to do that is to reference the data out of a resource dictionary:

 

<Grid>

  <Grid.Resources>

    <Int32Collection x:Key='DataSource1'>1,2,3</Int32Collection>

  </Grid.Resources>

 

  <ListBox ItemsSource='{Binding Source={StaticResource DataSource1}}' />

</Grid>

 

(This example creates a ListBox with 3 entries in it, labeled “1”, “2”, and “3”.)

 

You can be even more explicit by setting the Source directly, specifying the Binding in full Xml syntax (rather than the above markup extension syntax):

 

<Grid>

  <ListBox>

    <ListBox.ItemsSource>

      <Binding>

        <Binding.Source>

          <Int32Collection>1,2,3</Int32Collection>

        </Binding.Source>

      </Binding>

    </ListBox.ItemsSource>

  </ListBox>

</Grid>

 

You can also set the Binding.Source by referencing a static member:

 

namespace MyNamespace

{

    class MyClass

    {

        public static List<int> MyData;

        static MyClass()

        {

            MyData = new List<int>();

            MyData.Add(1);

            MyData.Add(2);

            MyData.Add(3);

        }

 

    }

}

 

 

<Page

    xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'

    xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'

    xmlns:my="clr-namespace:MyNamespace" >

 

  <ListBox ItemsSource='{Binding Source={x:Static my:MyClass.MyData}}' />

 

</Page>

 

 

The ElementName Property

 

Aside from the Binding.Source property, you can also reference your data by name, using Binding.ElementName, such as:

 

<StackPanel>

  <TextBox Name='TextBox1' />

  <Button Content='{Binding Text, ElementName=TextBox1}' />

</StackPanel>

 

(This example causes the button label to be whatever you type into the text box.)

 

 

The RelativeSource Property

 

The RelativeSource property provides a way to tell the Binding to look around where it’s used to find its source.  For example, the ‘Self’ RelativeSource binds to the object on which the Binding is placed, such as in the following (which creates a TextBlock that says “Hi”):

 

<TextBlock Tag='Hi' Text='{Binding Tag, RelativeSource={RelativeSource Self}}' />

 

As another example, the following binds the TextBlock.Text property to the Grid in its ancestry (again displaying “Hi” in this case):

 

<Grid Tag='Hi'>

 

  <Border Background='LightGray'>

    <TextBlock

         Text='{Binding Tag, RelativeSource={RelativeSource FindAncestor, AncestorType=Grid}}' />

  </Border>

 

</Grid>

 

The other two modes of a RelativeSource are TemplatedParent and PreviousData.

 

Explicit DataContext Property

 

A common way the Binding can get its source is via a DataContext property set on an element (on the element itself, not on the Binding).  For (a rather boring) example, this creates a Button that says “Click”:

 

<Button Content='{Binding}'>

  <Button.DataContext>

    <sys:String>Click</sys:String>

  </Button.DataContext>

</Button>

 

This gets more interesting and typical if you set the DataContext somewhere else, usually on the root of the page/window.  That works because the DataContext property inherits.  The following example shows that by setting the DataContext onto the root.  In this case, it is set to be an XmlDataProvider which is querying a Yahoo web service for the weather in Barrow, Alaska.  Since the DataContext inherits, Bindings throughout the page have access to it automatically.  Note also in this case that since we’re binding to XML, the Bindings are using XPath syntax.

 

<Page   

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 

    >

 

  <Page.DataContext>

    <XmlDataProvider

            Source="http://xml.weather.yahoo.com/forecastrss?p=99723" 

            XPath="/rss/channel"/>

  </Page.DataContext>

 

  <Border BorderBrush="Black"

          BorderThickness="1" Width="370" Height="170" CornerRadius="6">

    <StackPanel>

 

      <!-- Image for "Yahoo! News" -->

      <Image Margin="15,15,0,0"

                   Stretch="None" 

                   HorizontalAlignment="Left"

                   Source="{Binding XPath=image/url}" />

 

      <!-- Text to say e.g. "Yahoo! Weather - Bellevue, WA", with a hyperlink to a

           detailed weather page -->

      <TextBlock Margin="15,15,0,0">

        <Hyperlink NavigateUri="{Binding XPath=item[1]/link}">

          <TextBlock Text="{Binding XPath=title}"/>

        </Hyperlink>

      </TextBlock>

 

      <!-- Text to say e.g. "Conditions for Belleveue, WA at 9:53am ..." -->

      <TextBlock FontWeight="Bold"    Margin="15,15,0,0"

                 Text="{Binding XPath=item[1]/title}"/>

 

      <!-- Weather details  -->

      <TextBlock Margin="15,0,0,0">

 

        <!-- Text to say current condition and temp -->

        <TextBlock>

          <TextBlock.Text>

            <Binding >

              <Binding.XPath>

                item[1]/*[local-name()="condition" and

                namespace-uri()="http://xml.weather.yahoo.com/ns/rss/1.0"]/@text

              </Binding.XPath>

            </Binding>

          </TextBlock.Text>

        </TextBlock>,

        <TextBlock>

          <TextBlock.Text>

            <Binding >

              <Binding.XPath>

                item[1]/*[local-name()="condition" and

                namespace-uri()="http://xml.weather.yahoo.com/ns/rss/1.0"]/@temp

              </Binding.XPath>

            </Binding>

          </TextBlock.Text>

        </TextBlock>°

        <TextBlock>

          <TextBlock.Text>

            <Binding >

              <Binding.XPath>

                *[local-name()="units" and

                namespace-uri()="http://xml.weather.yahoo.com/ns/rss/1.0"]/@temperature

              </Binding.XPath>

            </Binding>

          </TextBlock.Text>

        </TextBlock>

        <LineBreak/>

 

        <!-- Text to say sunrise/sunset times -->

        Sunrise:

        <TextBlock>

          <TextBlock.Text>

            <Binding >

              <Binding.XPath>

                *[local-name()="astronomy" and

                namespace-uri()="http://xml.weather.yahoo.com/ns/rss/1.0"]/@sunrise

              </Binding.XPath>

            </Binding>

          </TextBlock.Text>

        </TextBlock>, sunset:

 

        <TextBlock>

          <TextBlock.Text>

            <Binding >

              <Binding.XPath>

                *[local-name()="astronomy" and

                namespace-uri()="http://xml.weather.yahoo.com/ns/rss/1.0"]/@sunset

              </Binding.XPath>

            </Binding>

          </TextBlock.Text>

        </TextBlock>

      </TextBlock>

    </StackPanel>

 

  </Border>

</Page>

 

… Sunrise at midnight, sunset at noon:

 

Attachment: barrow.jpg (11494 bytes)

 

 

Implicit DataContext

 

Finally, there are a couple of places where the DataContext gets set automatically for you.  That usually happens with ContentControl (e.g. Button) and ItemsControl (e.g. ListBox). 

 

Here’s a ContentControl example.  In this markup we have a DataTemplate set up in a ResourceDictionary so that it will be used for any ContentControl that has a String as its content.  So it’s automatically picked up in the subsequent Button.  In that DataTemplate, we have a binding to the data item, which in this case is the ContentControl.Content.  Therefore what we get here is a Button that says “Click” in bold italic.

 

<Page   

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 

    xmlns:sys="clr-namespace:System;assembly=mscorlib" >

 

  <Page.Resources>

    <DataTemplate DataType="{x:Type sys:String}">

      <!-- The Text property is bound to the Content property of

           whatever ContentControl with which this DataTemplate is used -->

      <TextBlock Text='{Binding}' FontStyle='Italic' FontWeight='Bold' />

    </DataTemplate>

  </Page.Resources>

 

  <Button>Click</Button>

 

</Page>

 

 

And here’s an ItemsControl example.  In this markup, we have a ListBox bound to an integer collection again (using the inherited DataContext as the source), but this time we have an item template, which is a  template to use when displaying the items in the ListBox.  And within that item template, the DataContext is again automatically set to be the item

 

<Page   

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 

    xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml >

 

  <Page.DataContext>

    <Int32Collection>1,2,3</Int32Collection>

  </Page.DataContext>

 

  <!-- ItemsSource is bound to the DataContext (Int32Collection) -->

  <ListBox ItemsSource='{Binding}' >

    <ListBox.ItemTemplate>

      <DataTemplate>

 

        <DataTemplate.Triggers>

          <!-- Within the DataTemplate, the DataContext is set to be the data item.

               So this DataTrigger.Binding property's DataContext is going to be

               the item (1, 2, or 3) -->

          <DataTrigger Binding='{Binding}' Value='2'>

            <Setter Property='TextBlock.FontStyle' Value='Italic' />

            <Setter Property='TextBlock.FontWeight' Value='Bold' />

          </DataTrigger>

        </DataTemplate.Triggers>

 

        <Border Padding='10'>

          <!-- Similarly this Text property is bound to the item (1, 2, or 3) -->

          <TextBlock Text='{Binding}' />

        </Border>

      </DataTemplate>

    </ListBox.ItemTemplate>

  </ListBox>

</Page>

Posted by gsi
:

RectAnimation anima = new RectAnimation();
anima .From =
new Rect(100, 100, 200, 200);
anima .To =
new Rect(0, 0, 400, 400);
anima .Duration =
new Duration(TimeSpan.FromSeconds(1));
anima .AutoReverse =
true;
anima .RepeatBehavior =
RepeatBehavior.Forever;
AnimationClock clock = anima .CreateClock();
dc.DrawRectangle(
Brushes.Blue, null, new Rect(0, 0, 0, 0), clock);

Posted by gsi
:

xaml 코드에서 Completed="OnCompleted" 를 사용해서 에니메이션이 완료 되었을때 처리코드를 추가 할 수 있다.

<
Window.Resources>
  <
Storyboard x:Key="sb1" Completed="OnCompleted"
>
     <
DoubleAnimation  Storyboard.TargetName="deactiveAnimationRectangle" Storyboard.TargetProperty="Width" From="20" To="400" Duration="0:0:5"
/>
     <
DoubleAnimation Storyboard.TargetName="holdEndAnimationRectangle" Storyboard.TargetProperty="Width" From="10" To="400" Duration="0:0:1.5" BeginTime="0:0:0.5"
/>
</
Storyboard
>
</
Window.Resources
>

Being able, when animation ended, to set rectangle Width using: holdEndAnimationRectangle.Width = 250;

Also tried:

void OnCompleted (object sender, EventArgs e)
{
  Storyboard sb = (Storyboard)this.FindResource("sb1"
);
  sb.FillBehavior = FillBehavior
.Stop;
  holdEndAnimationRectangle.Width = 250;
}

Posted by gsi
:

<Window x:Class="WpfApplication.MainWindow"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        Title="MainWindow">

    <Canvas>

        <Button x:Name="MyButton" Loaded="MyButton_Loaded">Button</Button>

    </Canvas>

</Window>

 

        private void MyButton_Loaded(object sender, RoutedEventArgs e)

        {

            const string TranslateTransformName = "MyAnimatedTranslateTransform";

 

            TranslateTransform tt = new TranslateTransform(50, 50);

            NameScope.SetNameScope(tt, new NameScope());

            this.RegisterName(TranslateTransformName, tt);

            this.MyButton.RenderTransform = tt;

 

            Storyboard sb = new Storyboard();

 

            DoubleAnimation daX = new DoubleAnimation(50, 200, new Duration(new TimeSpan(0, 0, 5)));

            daX.AutoReverse = true;

            daX.RepeatBehavior = RepeatBehavior.Forever;

            Storyboard.SetTargetName(daX, TranslateTransformName);

            Storyboard.SetTargetProperty(daX, new PropertyPath(TranslateTransform.XProperty));

            sb.Children.Add(daX);

 

            DoubleAnimation daY = new DoubleAnimation(50, 200, new Duration(new TimeSpan(0, 0, 5)));

            daY.AutoReverse = true;

            daY.RepeatBehavior = RepeatBehavior.Forever;

            Storyboard.SetTargetName(daY, TranslateTransformName);

            Storyboard.SetTargetProperty(daY, new PropertyPath(TranslateTransform.YProperty));

            sb.Children.Add(daY);

 

            DoubleAnimation daW = new DoubleAnimation(50, 200, new Duration(new TimeSpan(0, 0, 5)));

            daW.AutoReverse = true;

            daW.RepeatBehavior = RepeatBehavior.Forever;

            Storyboard.SetTargetName(daW, "MyButton");

            Storyboard.SetTargetProperty(daW, new PropertyPath(Button.WidthProperty));

            sb.Children.Add(daW);

 

            DoubleAnimation daH = new DoubleAnimation(50, 200, new Duration(new TimeSpan(0, 0, 5)));

            daH.AutoReverse = true;

            daH.RepeatBehavior = RepeatBehavior.Forever;

            Storyboard.SetTargetName(daH, "MyButton");

            Storyboard.SetTargetProperty(daH, new PropertyPath(Button.HeightProperty));

            sb.Children.Add(daH);

 

            sb.Begin(this.MyButton);

        }

Posted by gsi
:

세삼 느끼는 거지만 msdn의 예제는 너무 xaml 중심으로 되어 있다.
이런 코드의 예제가 절실하게 필요한 때인거 같다.

-- XAML CODE—

 

<Storyboard x:Key="OnCalendarLoaded">

 <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"

Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(SkewTransform.AngleX)"

Storyboard.TargetName="TargetShape">

                        <SplineDoubleKeyFrame   KeySpline="0.5,0.5,0.5,0.5" Value="0" KeyTime="00:00:00"/>

                        <SplineDoubleKeyFrame   KeySpline="0.5,0.5,0.5,0.5" Value="15" KeyTime="00:00:01"/>

            </DoubleAnimationUsingKeyFrames>

      </Storyboard>

….

          <Rectangle Stroke="White" Margin="0,20,0,0"

            Width="120" Height="100"

            x:Name="TargetShape"

            Fill="sc#0.400752217, 0.3677801, 0.3677801, 0.3677801">

              <Rectangle.RenderTransform>

                <TransformGroup>

                  <TranslateTransform X="0" Y="0"/>

                  <ScaleTransform ScaleX="0" ScaleY="0"/>

                  <SkewTransform AngleX="15" AngleY="0"/>

                  <RotateTransform Angle="0"/>

                  <TranslateTransform X="0" Y="0"/>

                  <TranslateTransform X="0" Y="0"/>

                </TransformGroup>

              </Rectangle.RenderTransform>

            </Rectangle>

 

Void StartAnimationsFunction()

{

      Storyboard story = (Storyboard)this.FindResource("OnCalendarLoaded");

      BeginStoryboard(story); // IT WORKS!

}

 


 

-- C# CODE --

 

<Storyboard x:Key="OnCalendarLoaded">

      </Storyboard>

 

 

Void StartAnimationsFunction ()

{

      Storyboard story = (Storyboard)this.FindResource("OnCalendarLoaded");

story.Children.Add(getAnimation1("TargetShape"));

      BeginStoryboard(story); // NOTHING HAPPENS!

}

       

        private DoubleAnimationUsingKeyFrames getAnimation1(string name)

        {

            DoubleAnimationUsingKeyFrames anim = new DoubleAnimationUsingKeyFrames();

            anim.BeginTime = new TimeSpan(0, 0, 0);

 

            Storyboard.SetTargetName(anim, name);

            Storyboard.SetTargetProperty(anim,

                new PropertyPath("0.1[2].2", new DependencyProperty[] {

                    UIElement.RenderTransformProperty,

                    TransformGroup.ChildrenProperty,

                    SkewTransform.AngleXProperty}));

 

            anim.KeyFrames.Add(new SplineDoubleKeyFrame(0, KeyTime.FromTimeSpan(new TimeSpan(0, 0, 0)), new KeySpline(.5, .5, .5, .5)));

            anim.KeyFrames.Add(new SplineDoubleKeyFrame(15, KeyTime.FromTimeSpan(new TimeSpan(0, 0, 1)), new KeySpline(.5, .5, .5, .5)));

 

            return anim;

        }

Posted by gsi
: