2012-05-03 63 views
0

我在WP7中創建了一個滾動查看器,其中包含3個用戶控件,每個用戶控件都包含XAML創建UserControls的內容。這工作正常。這個滾動查看器應該能夠在這些項目之間滾動,但是不能讓用戶滾動。因此,當點擊其中一個內容中的項目時,滾動查看器將根據所選項目向左或向右滑動,並將其中一個其他用戶控件帶入其中。我用一箇中介來實現:如何防止滾動查看器在滾動條可見性設置爲禁用時向後滾動? WP7

<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設置爲可見。動畫完成後,我想授予返回hittestvisibility,並將horizo​​ntalscrollbarvisibility設置爲Disabled。後者是問題所在:當我將horizo​​ntalscrollbarvisibility設置爲Disabled時,scrollviewer會自動返回查看堆棧面板中三項中的第一項。我怎樣才能阻止呢?這是我用滾動調解代碼:

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; 
     } 
    } 

我已經問過這個問題,然後把它作爲回答,因爲我認爲這要回答,即使用ScrollbarVisibility.Hidden代替ScrollbarVisibility.Disabled,只有滾動條可見性以這種方式保持可見,用戶仍然可以滾動。有沒有一種原生的方式來解決這個問題?

任何幫助將不勝感激。 Greetz

回答

1

與其對抗本地控件的行爲,使用自定義控件(包裝您的其他控件)自己操縱項目自己的位置可能更容易,該自定義控件在不同的視覺狀態之間進行動畫調整(調整翻譯轉換),具體取決於「選定」項目。

+0

是的,我確實想到了(在等待答案時正在處理其他問題),但認爲可能存在原生的東西,這會爲我節省很多時間。 但據你所知,沒有辦法繞過scrollviewer的這個缺陷,我接下去呢? – GeekPeek

+0

這可以說並不是控制中的缺陷。你只是試圖用它來設計它的東西。 –

+0

是的,這是真的,我發現Scrollbarvisibility提供了兩種隱藏可見性的方法,其中一種不阻止滾動(我認爲它隱藏了指示器滾動條),另一種讓它滾動回到在將其設置爲隱形之後立即進行。無論如何,我現在只是使用你建議的方法。謝謝= 3 – GeekPeek