ScrollIntoView 不适用于 Touch
ScrollIntoView doesn't work with Touch
所以我有一张地图,上面有许多 PushPins
,右边的列表列出了所有 PushPins
(使用相同的视图模型)
当我单击地图上的图钉时,我想将该项目滚动到列表中的视图中。
我目前在 Click 和 OnTouch 上使用此代码:
private void ScrollPushPin(Pushpin pushpin)
{
ScrollViewer scrollViewer = GetScrollViewer(MyList) as ScrollViewer;
scrollViewer.ScrollToBottom();
var index = this.MyList.Items.IndexOf(pushpin);
//index is never -1 so I would expect it to work?
this.MyList.ScrollIntoView(pushpin);
}
点击时:
void pp_MouseDown(object sender, MouseButtonEventArgs e)
{
ScrollPushPin(sender as PushPin);
}
触摸时:
void pp_TouchDown(object sender, TouchEventArgs e)
{
var pushpin = (Pushpin)sender;
pushpin.CaptureTouch(e.TouchDevice);
}
void pp_TouchUp(object sender, TouchEventArgs e)
{
var pushpin = (Pushpin)sender;
if (pushpin != null && e.TouchDevice.Captured == pushpin)
{
pushpin.ReleaseTouchCapture(e.TouchDevice);
ScrollPushPin(pushpin);
}
}
虽然此代码在我用鼠标单击图钉时工作正常,但触摸事件不会将我的图钉滚动到视图中,我不明白为什么?
我也试过了:
this.MyList.Dispatcher.Invoke((Action)(() => this.MyList.ScrollIntoView(pushpin)));
和
this.MyList.ScrollIntoView(this.MyList.Items[val]);
所以不要问我为什么这样做,但在我的事件末尾添加 e.Handled = true
解决了问题:
void pp_TouchDown(object sender, TouchEventArgs e)
{
var pushpin = (Pushpin)sender;
pushpin.CaptureTouch(e.TouchDevice);
e.Handled = true
}
void pp_TouchUp(object sender, TouchEventArgs e)
{
var pushpin = (Pushpin)sender;
if (pushpin != null && e.TouchDevice.Captured == pushpin)
{
pushpin.ReleaseTouchCapture(e.TouchDevice);
ScrollPushPin(pushpin);
}
e.Handled = true
}
编辑
添加 e.Handled = true
导致了更多问题,所以我决定自己编写 ScrollIntoView
var val = this.MyList.Items.IndexOf(myObj);
if (val != -1)
{
ScrollViewer scrollViewer = GetScrollViewer(MyList) as ScrollViewer;
var itemHeight = scrollViewer.ExtentHeight / this.MyList.Items.Count;
scrollViewer.ScrollToVerticalOffset(itemHeight * val);
}
//where
public static DependencyObject GetScrollViewer(DependencyObject o)
{
if (o is ScrollViewer)
{ return o; }
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(o); i++)
{
var child = VisualTreeHelper.GetChild(o, i);
var result = GetScrollViewer(child);
if (result == null)
{
continue;
}
else
{
return result;
}
}
return null;
}
所以我有一张地图,上面有许多 PushPins
,右边的列表列出了所有 PushPins
(使用相同的视图模型)
当我单击地图上的图钉时,我想将该项目滚动到列表中的视图中。
我目前在 Click 和 OnTouch 上使用此代码:
private void ScrollPushPin(Pushpin pushpin)
{
ScrollViewer scrollViewer = GetScrollViewer(MyList) as ScrollViewer;
scrollViewer.ScrollToBottom();
var index = this.MyList.Items.IndexOf(pushpin);
//index is never -1 so I would expect it to work?
this.MyList.ScrollIntoView(pushpin);
}
点击时:
void pp_MouseDown(object sender, MouseButtonEventArgs e)
{
ScrollPushPin(sender as PushPin);
}
触摸时:
void pp_TouchDown(object sender, TouchEventArgs e)
{
var pushpin = (Pushpin)sender;
pushpin.CaptureTouch(e.TouchDevice);
}
void pp_TouchUp(object sender, TouchEventArgs e)
{
var pushpin = (Pushpin)sender;
if (pushpin != null && e.TouchDevice.Captured == pushpin)
{
pushpin.ReleaseTouchCapture(e.TouchDevice);
ScrollPushPin(pushpin);
}
}
虽然此代码在我用鼠标单击图钉时工作正常,但触摸事件不会将我的图钉滚动到视图中,我不明白为什么?
我也试过了:
this.MyList.Dispatcher.Invoke((Action)(() => this.MyList.ScrollIntoView(pushpin)));
和
this.MyList.ScrollIntoView(this.MyList.Items[val]);
所以不要问我为什么这样做,但在我的事件末尾添加 e.Handled = true
解决了问题:
void pp_TouchDown(object sender, TouchEventArgs e)
{
var pushpin = (Pushpin)sender;
pushpin.CaptureTouch(e.TouchDevice);
e.Handled = true
}
void pp_TouchUp(object sender, TouchEventArgs e)
{
var pushpin = (Pushpin)sender;
if (pushpin != null && e.TouchDevice.Captured == pushpin)
{
pushpin.ReleaseTouchCapture(e.TouchDevice);
ScrollPushPin(pushpin);
}
e.Handled = true
}
编辑
添加 e.Handled = true
导致了更多问题,所以我决定自己编写 ScrollIntoView
var val = this.MyList.Items.IndexOf(myObj);
if (val != -1)
{
ScrollViewer scrollViewer = GetScrollViewer(MyList) as ScrollViewer;
var itemHeight = scrollViewer.ExtentHeight / this.MyList.Items.Count;
scrollViewer.ScrollToVerticalOffset(itemHeight * val);
}
//where
public static DependencyObject GetScrollViewer(DependencyObject o)
{
if (o is ScrollViewer)
{ return o; }
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(o); i++)
{
var child = VisualTreeHelper.GetChild(o, i);
var result = GetScrollViewer(child);
if (result == null)
{
continue;
}
else
{
return result;
}
}
return null;
}