[英]Animate via Horizontal/Vertical offset of ScrollViewer
我需要控制其位置與 Windows Phone 8 SDK (silverlight/wpf) 中 ScrollViewer 的滾動偏移量直接相關的控件。 此外,我需要能夠知道各種委托中的滾動偏移量,以便我可以更改其他應用程序內屬性。 這甚至可能嗎?
我已經看遍了,但似乎找不到任何例子,我似乎也沒有足夠的 WPF/Silverlight 動畫概念來掌握它。
我能想到的最好的結果如下所示。 它起初似乎可以工作,但不幸的是只會在您的手指沒有按下並且 ScrollViewer 沒有動畫時才會更新,因此更新頻率太低。 我需要更新作為動畫循環的一部分,所以每一幀左右(每秒 60-100+),我都會得到新的滾動偏移值。 有什么辦法可以在動畫循環中安排 DispatchTimer 嗎? 或者是否有某種更好的方法來完全解決這個問題,使用諸如 DependentProperties 之類的東西?
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (!App.ViewModel.IsDataLoaded)
{
App.ViewModel.LoadData();
}
DispatcherTimer t = new DispatcherTimer();
t.Interval = TimeSpan.FromMilliseconds(16.6);
t.Tick += new EventHandler(
(object s, EventArgs ee) =>
{
// FunkBox is some ListBox
ScrollViewer sv = FindChildOfType<ScrollViewer>(FunkBox);
if (sv == null)
{
// TOffset is some TextBlock
TOffset.Text = "dur...";
}
else
{
TOffset.Text = String.Format("dur {0}", sv.HorizontalOffset);
}
});
t.Start();
}
static T FindChildOfType<T>(DependencyObject root) where T : class
{
var queue = new Queue<DependencyObject>();
queue.Enqueue(root);
while (queue.Count > 0)
{
DependencyObject current = queue.Dequeue();
for (int i = System.Windows.Media.VisualTreeHelper.GetChildrenCount(current) - 1; 0 <= i; i--)
{
var child = System.Windows.Media.VisualTreeHelper.GetChild(current, i);
var typedChild = child as T;
if (typedChild != null)
{
return typedChild;
}
queue.Enqueue(child);
}
}
return null;
}
這也花了我一段時間才弄明白。 這是你如何做到的:
因此,您的 XAML 將是:
<ScrollViewer x:Name="mainScrollViewer" ManipulationMode="Control">
....
</ScrollViewer>
而你背后的代碼:
public MainPage()
{
InitializeComponent();
this.Loaded += MainPage_Loaded;
}
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
ScrollBar verticalBar;
verticalBar = ((FrameworkElement)VisualTreeHelper.GetChild(mainScrollViewer, 0)).FindName("VerticalScrollBar") as ScrollBar;
verticalBar.ValueChanged += verticalBar_ValueChanged;
}
void verticalBar_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
double newVerticalOffset = e.NewValue;
// Set the offset of your other control here, using newVerticalOffset
}
或者,對於 ListBox,您需要使用以下代碼從 Listbox 內部獲取 ScrollViewer:
ScrollViewer mainScrollViewer = GetVisualChild<ScrollViewer>(yourListBoxControl);
// ...then use the code above
public T GetVisualChild<T>(UIElement parent) where T : UIElement
{
T child = null; // default(T);
int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < numVisuals; i++)
{
UIElement element = (UIElement)VisualTreeHelper.GetChild(parent, i);
child = element as T;
if (child == null)
child = GetVisualChild<T>(element);
if (child != null)
break;
}
return child;
}
您可能還需要在構造函數中設置 ScrollViewer 的操作模式:
ScrollViewer mainScrollViewer = GetVisualChild<ScrollViewer>(lstTest);
sv.ManipulationMode = ManipulationMode.Control;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.