2013-11-04 67 views
1

我正在使用Windows Phone 8應用程序,我正在嘗試創建一個UserControl,它在選擇時更改其自己的大小。 Selected/NotSelected之間的變化是使用VisualStateManager完成的。爲了保持下面的例子簡單,我忽略它並直接點擊UserControl。UserControl如何使用Storyboard更改其自己的大小?

的問題是,我無法找到任何方式改變用故事板的用戶控件的大小,因爲我不知道如何引用用戶控件本身在Storyboard.TargetName屬性:

<UserControl 
    x:Class="Namespace.MyUserControl" 
    ... 
    Tap="UserControl_Tap"> 

    <UserControl.Resources> 
     <Storyboard x:Key="Expand"> 
      <DoubleAnimation To="400" Storyboard.TargetName="????" Storyboard.TargetProperty="Width"> 
       <DoubleAnimation.EasingFunction> 
        <CubicEase EasingMode="EaseInOut"/> 
       </DoubleAnimation.EasingFunction> 
      </DoubleAnimation> 
     </Storyboard> 

     <Storyboard x:Key="Collaps"> 
      ... 
     </Storyboard> 
    </UserControl.Resources> 

    <Grid x:Name="LayoutRoot"> 
     <Rectangle x:Name="TestRect" Fill="Red" Width="10" Height="10"/> 
    </Grid> 
</UserControl> 

private void UserControl_Tap(object sender, System.Windows.Input.GestureEventArgs e) { 
    if (Width < 400) { 
     Storyboard storyBoard = (Storyboard)this.Resources["Expand"]; 
     storyBoard.Begin(); 

     Width = 400; 
     Height = 400; 
    } else { 
     Storyboard storyBoard = (Storyboard)this.Resources["Collaps"]; 
     storyBoard.Begin(); 

     Width = 200; 
     Height = 200; 
    } 
} 

的故事板需要指定Storyboard.TargetName。應該用什麼來代替來引用UserControl本身?使用「」不起作用,並引發InvalidOperationException「無法解析TargetName this」。使用「Namespace.MyUserControl」時會發生同樣的情況。

使用「LayoutRoot」作爲TargetName不會引發任何異常,但它不起作用:沒有任何反應。

動畫用戶控件內的任何分控制(例如使用TestRect = Storyboard.TargetName TestRect「)工作而沒有任何問題。另外設定的寬度和高度的情況下直接任何情節串連圖板工作沒有任何問題。

任何想法如何解決這個?

+0

爲什麼不在你的目標頁面中創建故事板,這種方式用戶控件是由它的屬性定義的 –

+0

UserControl應該用在許多不同的頁面上,並且行爲應該總是相同的。一次(UserControl內部)實現一次行爲,而不是在使用UserControl的每一頁上執行此操作都不會更好嗎? –

回答

1

問題是,我不知道「UserControl」裏面的Storybard是如何引用控件本身的。據我瞭解發現,答案很簡單:用戶控件內的任何元素將通過其名稱爲目標,所以只給用戶控件的名稱,它可以有針對性,以及:

<UserControl 
    x:Class="Namespace.MyUserControl" 
    x:Name="_this"  <-- NAME GIVEN HERE CAN BE USED AS TAGETNAME FOR STORYBOARD 
    ... 
    Tap="UserControl_Tap"> 

    <UserControl.Resources> 
     <Storyboard x:Key="Expand"> 
      <DoubleAnimation To="400" Storyboard.TargetName="_this" Storyboard.TargetProperty="Width"> 
       <DoubleAnimation.EasingFunction> 
        <CubicEase EasingMode="EaseInOut"/> 
       </DoubleAnimation.EasingFunction> 
      </DoubleAnimation> 
     </Storyboard> 

     <Storyboard x:Key="Collaps"> 
      ... 
     </Storyboard> 
    </UserControl.Resources> 

    <Grid x:Name="LayoutRoot"> 
     <Rectangle x:Name="TestRect" Fill="Red" Width="10" Height="10"/> 
    </Grid> 
</UserControl> 

編輯11/15/2013

請謹慎使用此解決方案。我在電話頁面上使用它來讓它引用它,並在這個頁面上放置一個UserControl,它使用了相同的解決方案。因此,頁面和用戶控件的名稱都是x:Name = _this

此應用程序不時與系統崩潰。InvalidCastException表示「MyPageType」無法被轉換爲「MyUserControlType」。我花了一段時間才弄清楚是什麼導致了這個問題。 元素不應該共享相同的x:Name。

使用x:Name = thisMyPage和x:Name = thisMyControl來解決問題。

1

好吧,這只是一個想法,但你可以嘗試請

當目標發生事件從控制變量投動畫,什麼纔是我的意思是說:

private void SomeEventOccured(object sender, RoutedEventArgs e) 
{ 
    var sb = _customUserControl.Expand; 
    sb.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath(CustomUserControl.WidthProperty)); 
    sb.SetValue(Storyboard.TargetNameProperty, _customUserControl.Name); 
    sb.Begin(); 
} 

或者你可以設置你的動畫作爲Application.Resources

Storyboard sb = (Application.Current as App).Resources["Expand"] as Storyboard; 

,然後設置TargetNamePropertyTargetPropertyProperty;

P.S.我已經用我的CustomUserControl嘗試了TargetProperty是Opacity。我希望這可以幫助你MSDN, stackoverflow question

+1

非常感謝您的回答!我認爲你的解決方案可能工作。同時我找到了更簡單的解決方案。我會將其添加爲答案,以防其他人遇到同樣的問題 –

相關問題