私はWindows Phone 10(C#UWP)アプリケーションを持っており、リストビューでscrollviewerを使用して画像のスライドを表示しています。スクロールビューアのビュー変更されたイベントでは、どのイメージコンテナがユーザーにとってより見えているかチェックし、ChangeViewメソッドを使用してそのイメージを表示された唯一のイメージに移動します。これはうまくいきますが、ChangeViewがアクティブな状態でタッチスクリーンを押し続けると、画像のサイズが変更され、「このオブジェクトは封印されているため、この変更は許可されなくなりました」というエラーが表示されます。ScrollViewer.ChangeViewがアクティブな状態で画面にタッチするUWP
XAML: (注、CurrentSizeConverterだけのパラメータに基づいて表示ページの境界を与える)
<Page.Resources>
<DataTemplate x:Key="dtPhotoView">
<Grid x:Name="grPhotoView" Width="{Binding Id, Converter={StaticResource CurrentSizeConverter}, ConverterParameter=Width}" Height="{Binding Id, Converter={StaticResource CurrentSizeConverter}, ConverterParameter=Height}">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<Image x:Name="imgFullSize" Source="{Binding ImageSource}" Stretch="Fill" Grid.RowSpan="2"/>
<Grid Grid.Row="1" x:Name="grDeleteFullImage" Background="#66000000">
<Button x:Name="btnDeletePhoto" Style="{StaticResource btnActionCommandButtonStyle}" Tag="{Binding Id}" Canvas.ZIndex="10" Margin="0" Click="btnDeletePhoto_Click" Background="#66000000" Padding="10">
<Button.Foreground>
<ImageBrush Stretch="Uniform" ImageSource="Assets/delete_icon.png"/>
</Button.Foreground>
</Button>
</Grid>
</Grid>
</DataTemplate>
</Page.Resources>
<Grid>
<ListView HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Visibility="Collapsed" SelectionMode="None" IsItemClickEnabled="False" x:Name="lvPhotoView" Grid.Row="0" DataContext="{Binding}" Background="Transparent" BorderThickness="0" ItemTemplate="{StaticResource dtPhotoView}" ScrollViewer.ZoomMode="Disabled" ScrollViewer.VerticalScrollBarVisibility="Hidden" ScrollViewer.HorizontalScrollBarVisibility="Hidden" ScrollViewer.HorizontalScrollMode="Enabled" ScrollViewer.VerticalScrollMode="Disabled" PointerEntered="lvPhotoView_PointerEntered">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="Margin" Value="2" />
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsStackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView> .........
プライベート変数:
private static bool _imagesShowing = false;
private ScrollViewer _imagesViewer;
イベント処理:
最後にprivate void lvPhotoView_PointerEntered(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{
try
{
if (!_imagesShowing)
{
_imagesShowing = true;
if (_imagesViewer == null)
{
_imagesViewer = GetScrollViewer(lvPhotoView);
}
if (_imagesViewer != null)
{
_imagesViewer.ViewChanged += ImagesScrollViewer_OnViewChanged;
}
}
}
catch (Exception ex)
{
return;
}
}
public static ScrollViewer GetScrollViewer(DependencyObject depObj)
{
try
{
if (depObj is ScrollViewer)
{
return depObj as ScrollViewer;
}
for (var i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
var child = VisualTreeHelper.GetChild(depObj, i);
var result = GetScrollViewer(child);
if (result != null)
{
return result;
}
}
return null;
}
catch
{
return null;
}
}
private async void ImagesScrollViewer_OnViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
{
if (!e.IsIntermediate)
{
var isDone = false;
try
{
_imagesViewer.ViewChanged -= ImagesScrollViewer_OnViewChanged;
_imagesViewer.HorizontalScrollMode = ScrollMode.Disabled;
_imagesViewer.IsScrollInertiaEnabled = false;
for (var i = 0; i < lvPhotoView.Items.Count; i++)
{
var item = lvPhotoView.Items[i];
var itemContainer = lvPhotoView.ContainerFromItem(item) as ListViewItem;
double firstVisValue;
var isVisible = itemContainer.IsVisibileToUserHorizontal(sender as ScrollViewer, out firstVisValue);
if (isVisible && lvPhotoView.Items.Count - 1 > i)
{
var nextItem = lvPhotoView.Items[i + 1];
var secondItemContainer = lvPhotoView.ContainerFromItem(nextItem) as ListViewItem;
double secondVisValue;
var isNextVisible = secondItemContainer.IsVisibileToUserHorizontal(sender as ScrollViewer, out secondVisValue);
if (isNextVisible)
{
_imagesViewer.ScrollToElement(firstVisValue < secondVisValue ? secondItemContainer : itemContainer);
}
await Task.Delay(800);
_imagesViewer.HorizontalScrollMode = ScrollMode.Enabled;
_imagesViewer.IsScrollInertiaEnabled = true;
_imagesShowing = false;
isDone = true;
}
}
}
finally
{
if (!isDone)
{
await Task.Delay(500);
_imagesViewer.HorizontalScrollMode = ScrollMode.Auto;
_imagesViewer.IsScrollInertiaEnabled = true;
_imagesShowing = false;
}
}
}
}
public static bool IsVisibileToUserHorizontal(this FrameworkElement element, FrameworkElement container, out double visValue)
{
visValue = 0;
if (element == null || container == null)
{
return false;
}
if (element.Visibility != Visibility.Visible)
{
return false;
}
var elementBounds = element.TransformToVisual(container).TransformBounds(new Rect(0.0, 0.0, element.ActualWidth, element.ActualHeight));
var containerBounds = new Rect(0.0, 0.0, container.ActualWidth, container.ActualHeight);
if (elementBounds.Left >= containerBounds.Left && elementBounds.Left < containerBounds.Right)
{
visValue = containerBounds.Right - elementBounds.Left;
return true;
}
if (elementBounds.Right >= containerBounds.Left && elementBounds.Right < containerBounds.Right)
{
visValue = elementBounds.Right - containerBounds.Left;
return true;
}
return false;
}
public static void ScrollToElement(this ScrollViewer scrollViewer, UIElement element, bool isHorizontalScrolling = true, bool smoothScrolling = true, float? zoomFactor = null)
{
var transform = element.TransformToVisual((UIElement)scrollViewer.Content);
var position = transform.TransformPoint(new Point(0, 0));
if (isHorizontalScrolling)
{
scrollViewer.ChangeView(position.X, null, zoomFactor, !smoothScrolling);
}
else
{
scrollViewer.ChangeView(null, position.Y, zoomFactor, !smoothScrolling);
}
}
、バインドxamlバインディングプロパティを持つ観察可能なコレクションリストImageSourceプロパティはImage StorageFileです(私の場合はすべて.jpgです)。
スムーススクロールがtrueの場合、スクロールが進行中です。項目をタップして保持するとアイテムがサイズ変更され、保持しながら移動できます。
アイデア?
はあなたの問題を再現するには何の十分なコードがありません。再現されたプロジェクトを提供するには、[ask]を参考にしてください。少なくともScrollToElementメソッドの呼び出し場所と方法 –
ヒントをお寄せいただきありがとうございます。コードスニペットが更新されました。すべてが再現可能になりました。したがって、スクロールして放すと、ScrollToElementが呼び出され、scrollviewが自動的にスクロールして、ユーザーが見やすいイメージになります。この自動スクロールが行われている間、画面をタップして上下にスワイプすると問題が発生します。 – user2081328