[英]ScrollViewer ChangeView on SizeChanged
我DataTemplate
我在HubSection使用:
<DataTemplate x:Name="dataTemplate2">
<Grid x:Name="greedy">
<ScrollViewer x:Name="scroller" SizeChanged="ScrollViewer_SizeChanged" Height="{Binding Height,ElementName=greedy}" >
<ItemsControl x:Name="itemsControl"
ItemsSource="{Binding}"
ItemTemplate="{StaticResource dataTemplateDetails}">
<ItemsControl.ItemContainerTransitions>
<TransitionCollection>
<ReorderThemeTransition />
<NavigationThemeTransition />
</TransitionCollection>
</ItemsControl.ItemContainerTransitions>
</ItemsControl>
</ScrollViewer>
</Grid>
</DataTemplate>
在我的ItemsControl
我有一些可以擴展的項目。 我要實現的是,當該項目將展開以查看有關該項目的更多詳細信息時。 我希望Scrollviewer
向下滾動(以獲取ScrollViewer
的更改大小)。
SizeChanged
事件的代碼后面:
private void ScrollViewer_SizeChanged(object sender, SizeChangedEventArgs e)
{
ScrollViewer myScroll = (ScrollViewer)sender;
myScroll.ChangeView(null, myScroll.ScrollableHeight, null, false);
}
我現在所做的工作沒有達到我的期望。 我現在向下滾動到結尾。 但問題是,只有當項目擴展了可用視圖的大小時,它才會滾動(顯示ScrollBar)。 然后,如果我展開另一個項目,它將不起作用。 如果我隱藏有關項目的詳細信息(ScrollBar也隱藏)並再次展開它,它將再次起作用。 就像SizeChanged
事件僅在ScrollViewer
付諸行動時發生,但是具有無限的高度不會改變。
我試過將行設置為“ *”的網格,它什么都不會改變。 現在,我嘗試通過將其綁定到ItemsControl
高度來設置高度-仍然是相同的行為。
您能為我提供解決方案,顯示思路或通過一些變通方法啟發我嗎?
編輯:
我准備了一些可使用的代碼,以查看發生了什么。
1)創建新項目->商店應用(c#)-> Windows Phone 8.1(空白應用)並將其命名為“滾動”
2)將此代碼粘貼到MainPage.xaml中
<Page
x:Class="scroll.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:scroll"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="DarkOliveGreen">
<Page.Resources>
<DataTemplate x:Name="dataTemplateDetails">
<Grid Name="grido" Grid.Row="1" Margin="10,10,10,10">
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="Auto" />
<RowDefinition Height="50" />
<RowDefinition Height="50" />
</Grid.RowDefinitions>
<Border Grid.Row="0" Background="Black" CornerRadius="10" Opacity="0.4" />
<Border Grid.Row="1" Background="Black" CornerRadius="10" Opacity="0.3" />
<Border Grid.Row="2" Background="Black" CornerRadius="10" Opacity="0.2" />
<Border Grid.Row="3" Background="Black" CornerRadius="10" Opacity="0.1" />
<TextBlock Grid.Row="0" Text="{Binding Name}" Style="{StaticResource BaseTextBlockStyle}" HorizontalAlignment="Center"/>
<Grid Grid.Row="1" HorizontalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Margin="5,0,5,0" Text="Description:" Style="{StaticResource BaseTextBlockStyle}"/>
<TextBlock Grid.Column="1" Text="{Binding Description}" Style="{StaticResource BaseTextBlockStyle}"/>
</Grid>
<TextBlock Grid.Row="2" Text="Next row" Style="{StaticResource BaseTextBlockStyle}" HorizontalAlignment="Center"/>
<TextBlock Grid.Row="3" Text="Next row" Style="{StaticResource BaseTextBlockStyle}" HorizontalAlignment="Center"/>
</Grid>
</DataTemplate>
<DataTemplate x:Name="dataTemplate2">
<Grid x:Name="greedy" >
<ScrollViewer x:Name="scroller" SizeChanged="ScrollViewer_SizeChanged" VerticalAlignment="Top">
<ItemsControl x:Name="itemsControl"
ItemsSource="{Binding}"
ItemTemplate="{StaticResource dataTemplateDetails}">
<ItemsControl.ItemContainerTransitions>
<TransitionCollection>
<ReorderThemeTransition />
<NavigationThemeTransition />
</TransitionCollection>
</ItemsControl.ItemContainerTransitions>
</ItemsControl>
</ScrollViewer>
</Grid>
</DataTemplate>
</Page.Resources>
<Page.BottomAppBar>
<CommandBar Background="Black" Opacity="0.6" x:Name="myCommandBar">
<AppBarButton Icon="Add" Label="Add" x:Name="AddItem" Click="Add_Click"/>
<AppBarButton Icon="Delete" Label="Delete" x:Name="RemoveItem" Click="Delete_Click"/>
</CommandBar>
</Page.BottomAppBar>
<Grid>
<Hub x:Name="myHub" Header="Test">
<HubSection x:Uid="myDetailsHubsection" x:Name="myDetailsHubsection" Header="Details" DataContext="{Binding Items}" ContentTemplate="{StaticResource dataTemplate2}" />
</Hub>
</Grid>
3)將此代碼粘貼到MainPage.xaml.cs中
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
namespace scroll
{
public sealed partial class MainPage : Page
{
public static Details dataContextItems;
public MainPage()
{
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Required;
dataContextItems = new Details();
}
public class TestItem
{
public string Name { get; set; }
public string Description { get; set; }
public TestItem(string n, string d)
{
Name = n;
Description = d;
}
}
public class Details : INotifyPropertyChanged
{
private ObservableCollection<TestItem> _items;
public ObservableCollection<TestItem> Items
{
set
{
_items = value;
NotifyPropertyChanged("Items");
}
get
{
return _items;
}
}
public Details()
{
_items = new ObservableCollection<TestItem>();
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
this.DataContext = dataContextItems;
}
private void Add_Click(object sender, RoutedEventArgs e)
{
TestItem iAmAnItem = new TestItem("Name of an item", "Long and detailed description of an item");
dataContextItems.Items.Add(iAmAnItem);
}
private void Delete_Click(object sender, RoutedEventArgs e)
{
if (dataContextItems.Items.Count > 0)
dataContextItems.Items.RemoveAt(0);
}
private void ScrollViewer_SizeChanged(object sender, SizeChangedEventArgs e)
{
ScrollViewer myScroll = (ScrollViewer)sender;
myScroll.ChangeView(null, myScroll.ScrollableHeight, null, false);
}
}
}
4)運行應用
5)當您添加前兩個項目時,您無法滾動它們,但是當您添加更多項目時,您會看到,一旦顯示項目“需要更多空間”並且出現滾動條,它就會向下滾動。 但是添加更多項目將無法正常工作。 如果刪除項目並再次添加“第三”項目,它將向下滾動。
我希望它每次滾動查看器大小更改時都向下滾動(在這種情況下,當新項目出現時,但請記住,當我的原始解決方案中的項目“擴展”並且同時可以有很少的擴展項目時,它應該工作)。
我一直在研究解決方案,終於找到了一種解決方案。 我認為問題是我不了解ScrollViewer
工作方式。 我將滾動高度作為UIElement高度,希望觸發SizeChanged這不是事實。 ScrollViewer
不會更改其大小,因為它只占用了可能的全部空間,然后僅顯示其中的內容(就像ScrollViewer
幾乎總是無限高,除非它小於實際可用的視圖空間)。 通過添加前兩個項目, SizeChanged
事件也與第三個事件一起觸發,然后什么也沒有發生。 證明了這一點。
每當ScrollViewer
(或本例中為Grid
)的大小更改時,我都需要SizeChanged
。 解決方案非常簡單,但是仍然需要了解ScrollViewer
工作原理-現在看來如此明顯,以至於它永遠不會超過可用空間。
為使其正常運行而進行的更改:
<DataTemplate x:Name="dataTemplate2">
<ScrollViewer x:Name="scroller" VerticalAlignment="Top" HorizontalAlignment="Stretch" IsEnabled="True" >
<Grid VerticalAlignment="Top" x:Name="greedo" SizeChanged="greedo_SizeChanged">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ItemsControl x:Name="itemsControl"
ItemsSource="{Binding}"
ItemTemplate="{StaticResource dataTemplateDetails}">
<ItemsControl.ItemContainerTransitions>
<TransitionCollection>
<ReorderThemeTransition />
<NavigationThemeTransition />
</TransitionCollection>
</ItemsControl.ItemContainerTransitions>
</ItemsControl>
</Grid>
</ScrollViewer>
</DataTemplate>
和后面的代碼:
private void greedo_SizeChanged(object sender, SizeChangedEventArgs e)
{
Grid takingScroll = (Grid)sender;
ScrollViewer myScroll = (ScrollViewer)takingScroll.Parent;
myScroll.ChangeView(null, myScroll.ScrollableHeight, null, false);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.