【问题标题】:Converting XAML to code for dynamic control将 XAML 转换为动态控制代码
【发布时间】:2012-01-05 16:20:52
【问题描述】:

设计者创建了一些 XAML VisualState 代码,这些代码在构建为 XAML 时可以正常工作。现在我的任务是将此 XAML 转换为 Code Behind,这是一个继承自 ChildWindow 的自定义模板控件,它将构建动画以在所有子 UserControl 到此 ChildWindow 的各种“窗口”之间转换。

我已经编写了所有代码,但是当我运行任何动画时,我收到一个错误,即 Silverlight “无法解析 targetproperty '(UIElement.Projection).(PlaneProjection.RotationY)'”

这是原始的 XAML

<VisualState x:Name="AtRegistration">
    <Storyboard>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="WindowContentPresenter" Storyboard.TargetProperty="(Content).Children[0].(UIElement.Visibility)">
            <DiscreteObjectKeyFrame KeyTime="00:00:00" Value="Collapsed" />
        </ObjectAnimationUsingKeyFrames>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="WindowContentPresenter" Storyboard.TargetProperty="(Content).Children[1].(UIElement.Visibility)">
            <DiscreteObjectKeyFrame KeyTime="00:00:00" Value="Visible" />
        </ObjectAnimationUsingKeyFrames>
    </Storyboard>
</VisualState>
<VisualState x:Name="AtLogin">
    <Storyboard>
        ... XAML omitted ...
    </Storyboard>
</VisualState>
<VisualStateGroup.Transitions>
    <VisualTransition From="AtRegistration" To="AtLogin">
        <Storyboard>
            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationY)">
                ... XAML OMITTED ...
            </DoubleAnimationUsingKeyFrames>
            ... XAML OMITTED ...
        </Storyboard>
    </VisualTransition>
    <VisualTransition From="AtLogin" To="AtRegistration">
        ... XAML OMITTED ...
    </VisualTransition>
</VisualStateGroup.Transitions>

... XAML 省略 ...

上面的 XAML 工作正常,但是当我编写代码时,却不行。我假设我在代码中做错了什么,但我找不到它。

public override void OnApplyTemplate()
{
base.OnApplyTemplate();

var content = (ContentPresenter)GetTemplateChild( "WindowContentPresenter" );
m_contentRoot = (Grid)GetTemplateChild( "ContentRoot" );

var grid = (Grid)GetTemplateChild( "Root" );

if( grid != null )
{
    // Create the state group
    var animGroup = new VisualStateGroup();
    animGroup.SetValue( NameProperty, "AnimationStates" );

    var grp = VisualStateManager.GetVisualStateGroups( grid );
    grp.Add( animGroup );

    for( int i = 0; i < MultiControls.Count; i++ )
    {
        var state = new VisualState();
        state.SetValue( NameProperty, GetControlName( i ) );
        animGroup.States.Add( state );

        state.Storyboard = new Storyboard();

        // create an animation for each of the multi controls
        for( int j = 0; j < MultiControls.Count; j ++ )
        {
            // Create the storyboard
            var anim = new ObjectAnimationUsingKeyFrames();
            Storyboard.SetTarget( state.Storyboard, content );
            anim.SetValue( Storyboard.TargetPropertyProperty, new PropertyPath( string.Format( "(Content).Children[{0}].(UIElement.Visibility)", j ) ) );
            anim.KeyFrames.Add( new DiscreteObjectKeyFrame
                                    {
                                        KeyTime = KeyTime.FromTimeSpan( new TimeSpan( 0, 0, 0 ) ),
                                        Value = j == i ? Visibility.Visible : Visibility.Collapsed
                                    } );

            state.Storyboard.Children.Add( anim );

            // Don't create a transition to and from the other states.
            if( i == j )
                continue;

            // Create the Transition
            var trans = new VisualTransition { From = GetControlName( j ), To = GetControlName( i ) };
            animGroup.Transitions.Add( trans );
            trans.Storyboard = new Storyboard();

            var dbl = new DoubleAnimationUsingKeyFrames { BeginTime = TimeSpan.FromSeconds( 0 ) };
            Storyboard.SetTarget( trans.Storyboard, m_contentRoot );
            dbl.SetValue( Storyboard.TargetPropertyProperty, new PropertyPath( "(UIElement.Projection).(PlaneProjection.RotationY)" ) );
            trans.Storyboard.Children.Add( dbl );

            ... CODE OMITTED ...
        }
    }
}
}

在我的模板 XAML 中,我有这个:

<Grid x:Name="Overlay" HorizontalAlignment="Stretch" VerticalAlignment="Top" Margin="0" Background="{TemplateBinding OverlayBrush}" Opacity="{TemplateBinding OverlayOpacity}"/>
<Grid x:Name="ContentRoot" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}" RenderTransformOrigin="0.5,0.5" Height="{TemplateBinding Height}" Width="{TemplateBinding Width}">
<Grid.Projection>
    <PlaneProjection/>
</Grid.Projection>

你们有什么想法吗?

谢谢。

【问题讨论】:

  • 您是否尝试过将 var dbl 添加到情节提要子项中,然后设置它的值?
  • 我试过了:var dbl = new DoubleAnim.....(); trans.Storyboard.Children.Add(dbl);然后设置它的所有属性并没有解决问题。
  • 尝试将 PropertyPath 字符串更改为“UIElement.Projection.(PlaneProjection.RotationY)” - 注意删除了第一个括号。基本上,您需要使用该路径,因为在 source 和 xaml 中定义此路径会有所不同。
  • 我尝试了很多变体,但仍然无法使其正常工作。我什至尝试用谷歌搜索 XAML 中的 PropertyPath 和后面的代码之间的差异,但这并没有得到太多回报。然后我尝试使用 XamlReader.Load 加载整个工作 VisualState XAML,但即使它明显存在,解决“WindowContentPresenter”也存在问题。我想知道它是否必须这样做,因为它在第一次解析/加载时无法解决它?
  • 你试过把它改成“UIElement.Projection.RotationY”吗?

标签: silverlight xaml


【解决方案1】:

Storyboard.SetTarget 的第二个参数应该是投影而不是 m_contentroot。那么您只需要在路径中指定“RotationY”即可。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-07
    • 1970-01-01
    相关资源
    最近更新 更多