0

WP7 で Scrollviewer を作成しました。これには 3 つのユーザー コントロールがあり、それぞれが XAML によって作成されたユーザー コントロールをコンテンツとして保持します。これはうまくいきます。このスクロールビューアは、これらのアイテム間をスクロールできるはずですが、ユーザーがスクロールできないようにします。したがって、これらのコンテンツのいずれかのアイテムをクリックすると、選択したアイテムに応じてスクロールビューアが左または右にスライドし、他のユーザー コントロールのいずれかが表示されます。これを達成するためにメディエーターを使用します。

<Grid.Resources>
        <Storyboard x:Name="ItemAnimation">
            <DoubleAnimation x:Name="ItemAnimationContent"
                             Storyboard.TargetName="Mediator"
                             Storyboard.TargetProperty="ScrollableWidthMultiplier"/>
        </Storyboard>
</Grid.Resources> 
<ScrollViewer Name="ScrollableItemPanel" 
                  Grid.Row="2" 
                  Grid.RowSpan="3" 
                  Grid.ColumnSpan="3"
                  VerticalScrollBarVisibility="Disabled"
                  HorizontalScrollBarVisibility="Disabled">

        <StackPanel Orientation="Horizontal">
            <UserControl    Name="NewsListBoxControl" Width="480" />
            <UserControl    Name="DetailedItemControl" Width="480"/>            
            <UserControl    Name="ExternalBrowserItemControl" Width="480"/>
        </StackPanel>
    </ScrollViewer>

    <local:ScrollableItemAnimationMediator x:Name="Mediator" 
                                           ScrollViewer="{Binding ElementName=ScrollableItemPanel}"/>

基本的に、これも問題なく動作します。アイテム間を移動して、コンテンツをユーザーコントロールとしてロードできます。しかし問題は、スクロールする能力をユーザーに与えることにあります。アイテムがスクロールする前に、hittestvisibilty を true に設定し、Horizo​​ntalscrollbarvisibility を visible に設定しました。アニメーションが完了したら、hittestvisibility を元に戻し、Horizo​​ntalscrollbarVisibility を再び Disabled に設定したいと思います。この後者が問題です。Horizo​​ntalscrollbarvisibility を Disabled に設定すると、スクロールビューアはスタックパネルの 3 つの項目のうち最初の項目を自動的に表示します。どうすればこれを止めることができますか? これは、メディエーターをスクロールするために使用するコードです。

private void CreateDetailedArticleItem( Dictionary<string, string> itemQuery )
    {
        _articleDetailPage.ItemQuery = itemQuery;
        DetailedItemControl.Content = _articleDetailPage as UserControl;
        Animate( _articleDetailPage, 0.0f, 0.5f, 250 );
    }

private void Animate( IContentControl control, float from, float to, double milliseconds )
    {                                                                                                                            
        //this eventhandler will fire when the animation has completed
        EventHandler handler = null;
        //we take away the User Input just for the moment, so that we can animate without the user interfering. Also, we make horizontalScroll Visible
        IsUserEnabled = false;

        //we then set the content of the animation. Where from will it move, towards where and in what duration?
        ItemAnimationContent.From = from;
        ItemAnimationContent.To = to;
        ItemAnimationContent.Duration = TimeSpan.FromMilliseconds( milliseconds );
        //we start the animation
        ItemAnimation.Begin( );

        //we tell the new control that it will appear soon, so it can load its main content
        control.ViewWillAppear( );
        //also, we tell the currentcontrol that it will disappear soon, so it can unload its content and eventhandlers and so on
        CurrentControl.ViewWillDisAppear( );

        //the handler is a delegate. This way, it becomes rather easy and clean to fire the completed event, without creating a strong reference ( well, actually,
        //we do create a strong reference, but as soon as it is fired, we remove it again, shhhh! ).
        handler = delegate( object sender, EventArgs e )
        {
            //as stated, we remove the eventlistener again, so it won't keep firing all the time
            ItemAnimation.Completed -= handler;

            //after the animation, we tell the new control that it is now in screen, and can start downloading its data
            control.ViewDidAppear( );
            //at the same time, the "current" control has fully moved out of view, so it can now fully unload all its content.
            CurrentControl.ViewDidDisAppear( );
            //now, all we have to do is to make sure that the next time an item is being loaded, the new content is spoken to, not the old one
            CurrentControl = control;

            //and finally, enable the users input again, and remove the horizontal scrollbarvisibility
            IsUserEnabled = true;                
        };            
        ItemAnimation.Completed += handler;
    }
 private bool IsUserEnabled
    {
        set
        {
            //when the user can control the scrollviewer, then the horizontal scrollvisibility is disabled, so that the user cannot move horizontally,
            //otherwise, so we only make it visible when the program needs to animate.
            ScrollableItemPanel.IsHitTestVisible = value;
            ScrollableItemPanel.HorizontalScrollBarVisibility = value ? ScrollBarVisibility.Disabled : ScrollBarVisibility.Visible;
        }
    }

私はすでにこの質問をしていましたが、答えられたと思ったので、答えられたと見なしました。この問題に対処するネイティブな方法はありますか?

どんな助けでも大歓迎です。グリーツ

4

1 に答える 1

1

ネイティブ コントロールの動作と戦うよりも、「選択した」アイテムに応じて異なる視覚状態間でアニメーション化する (変換変換を調整する) カスタム コントロールを使用して (他のコントロールをラップする)、アイテムの位置を自分で操作する方が簡単な場合があります。 .

于 2012-05-04T08:40:54.710 に答える