我正在开发一个WIN 8.1应用程序。在我的应用程序中,我有一个ListView,我从ViewModel绑定一个可观察的集合。到目前为止一切正常。问题是,在后台所有数据都将正确加载,但我的ListView显示大约40个元素后,从头开始...在背景中选择了右对象并加载了80个对象。
滚动出现问题吗?
有谁知道,如何解决这个问题?
从另一个页面,我导航到带有ListView的页面:
private void ShowReturnData()
{
ReturnViewModel retVM = new ReturnViewModel(_navigationService, SelectedTour);
_navigationService.NavigateTo(ViewModelLocator.ReturnPageKey, retVM);
}
在我的ViewModel构造函数中,我将数据添加到observable Collection:
我正在使用MVVMlight。
属性(ObservableCollection,SelectedItem):
- >可观察的收藏
/// <summary>
/// The <see cref="Data" /> property's name.
/// </summary>
public const string DataPropertyName = "Data";
private ObservableCollection<ReturnData> _myProperty = new ObservableCollection<ReturnData>();
/// <summary>
/// Sets and gets the Data property.
/// Changes to that property's value raise the PropertyChanged event.
/// </summary>
public ObservableCollection<ReturnData> Data
{
get
{
return _myProperty;
}
set
{
if (_myProperty == value)
{
return;
}
_myProperty = value;
RaisePropertyChanged(DataPropertyName);
}
}
- &GT; SelectedItem
/// <summary>
/// The <see cref="SelectedItem" /> property's name.
/// </summary>
public const string SelectedItemPropertyName = "SelectedItem";
private ReturnData _selectedItem = null;
/// <summary>
/// Sets and gets the SelectedTour property.
/// Changes to that property's value raise the PropertyChanged event.
/// </summary>
public ReturnData SelectedItem
{
get
{
return _selectedItem;
}
set
{
if (_selectedItem == value)
{
return;
}
if (_selectedItem != null)
{
_selectedItem.IsFirstItem = false;
_selectedItem.IsLastItem = false;
}
_selectedItem = value;
if (_selectedItem != null)
{
setIsFirstOrLastItem(Data.IndexOf(_selectedItem));
}
RaisePropertyChanged(SelectedItemPropertyName);
}
}
ViewModel构造函数:
public ReturnViewModel(INavigationService navigationService, TourDetailData tourDetails)
{
//Services
_navigationService = navigationService;
//Commands
PrevPageCommand = new RelayCommand(GoToPrevPage);
TourDetails = tourDetails;
TourCustomerName = "Tour " + tourDetails.Tour + " > " + tourDetails.AccountName;
Data = new ObservableCollection<ReturnData>(from i in TourDetails.ReturnData orderby Convert.ToInt32(i.ItemId) select i);
}
XAML:
<ListView x:Name="lvItems"
Grid.Row="2"
SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
ItemTemplate="{StaticResource ReturnDataTemplate}"
ItemContainerStyle="{StaticResource ReturnDataListViewItemStyle}"
ItemsSource="{Binding Data}"
Margin="0,5,0,0"
Loaded="lvItems_Loaded">
</ListView>
的DataTemplate:
<DataTemplate x:Key="ReturnDataTemplate">
<Grid x:Name="grid" d:DesignWidth="1344.53" d:DesignHeight="123.228">
<Grid.Resources>
<converter:SelectionConverter x:Key="SelectionConverter" Context="{Binding}" />
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="450*"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<Rectangle Grid.Row="0" Grid.ColumnSpan="5" Height="100" Fill="LightGray" Visibility="Collapsed"/>
<Rectangle Grid.Row="2" Grid.ColumnSpan="5" Height="100" Fill="LightGray" Visibility="Collapsed"/>
<!--<Rectangle Grid.Row="0" Grid.ColumnSpan="5" Height="100" Fill="LightGray" Visibility="{Binding IsFirstItem, Converter={StaticResource BoolToVisibilityConverter}}"/>
<Rectangle Grid.Row="2" Grid.ColumnSpan="5" Height="100" Fill="LightGray" Visibility="{Binding IsLastItem, Converter={StaticResource BoolToVisibilityConverter}}"/>-->
<Rectangle Grid.Row="1" Fill="{StaticResource OrangeHighlight}" Visibility="{Binding IsDirty, Converter={StaticResource BoolToVisibilityConverter}}"/>
<StackPanel Grid.Row="1" Grid.Column="1" VerticalAlignment="Center" Margin="15,0">
<TextBlock TextWrapping="Wrap" FontSize="42.667" FontFamily="Segoe UI" Text="{Binding ItemId}" FontWeight="SemiBold"/>
<TextBlock TextWrapping="Wrap" Text="{Binding ItemName}" FontSize="32" FontFamily="Segoe UI"/>
</StackPanel>
<!--<TextBox x:Name="tbxReturn" Grid.Row="1" TextWrapping="Wrap" Grid.Column="2" FontFamily="Segoe UI" FontSize="42.667" Text="{Binding Return}" HorizontalAlignment="Center" VerticalAlignment="Center" Style="{StaticResource TextBoxStyleValues}" PreventKeyboardDisplayOnProgrammaticFocus="True" DoubleTapped="tbxReturn_DoubleTapped" GotFocus="tbxReturn_GotFocus" />-->
<TextBox x:Name="tbxReturn" Grid.Row="1" TextWrapping="Wrap" Grid.Column="2" FontFamily="Segoe UI" FontSize="42.667" Text="{Binding Return}" HorizontalAlignment="Center" VerticalAlignment="Center" Style="{StaticResource TextBoxStyleValues}" DoubleTapped="tbxReturn_DoubleTapped" GotFocus="tbxReturn_GotFocus" InputScope="CurrencyAmountAndSymbol" Foreground="#FF520164" />
<TextBox x:Name="tbxMold" Grid.Row="1" TextWrapping="Wrap" Text="{Binding Mildew}" Grid.Column="3" FontFamily="Segoe UI" FontSize="42.667" HorizontalAlignment="Center" VerticalAlignment="Center" Style="{StaticResource TextBoxStyleValues}" DoubleTapped="tbxMold_DoubleTapped" Tapped="tbxMold_Tapped" GotFocus="tbxMold_GotFocus" InputScope="CurrencyAmountAndSymbol" Foreground="#FF019E90" />
<TextBox x:Name="tbxCredit" Grid.Row="1" TextWrapping="Wrap" Text="{Binding Credit}" Grid.Column="4" FontFamily="Segoe UI" FontSize="42.667" HorizontalAlignment="Center" VerticalAlignment="Center" Style="{StaticResource TextBoxStyleValues}" DoubleTapped="tbxCredit_DoubleTapped" Tapped="tbxCredit_Tapped" GotFocus="tbxCredit_GotFocus" InputScope="CurrencyAmountAndSymbol" Foreground="#FF005C9C" />
<!--<Button Grid.Row="1" Content="+" HorizontalAlignment="Stretch" VerticalAlignment="Top" Grid.Column="2" Height="100" Margin="0,-100,0,0" FontSize="48" Style="{StaticResource NumUpDownButtonStyle}" Visibility="{Binding ElementName=lvItems, Path=DataContext.SelectedItem, ConverterParameter=Selected, Converter={StaticResource SelectionConverter}}" Command="{Binding DataContext.IncreaseReturnCommand, ElementName=lvItems}" Opacity="0.9"/>
<Button Grid.Row="1" Content="-" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Grid.Column="2" Margin="0,0,0,-100" Height="100" FontSize="48" Style="{StaticResource NumUpDownButtonStyle}" Visibility="{Binding ElementName=lvItems, Path=DataContext.SelectedItem, ConverterParameter=Selected, Converter={StaticResource SelectionConverter}}" Command="{Binding DataContext.DecreaseReturnCommand, ElementName=lvItems}" Opacity="0.9"/>
<Button Grid.Row="1" Content="+" HorizontalAlignment="Stretch" VerticalAlignment="Top" Grid.Column="3" Height="100" Margin="0,-100,0,0" FontSize="48" Style="{StaticResource NumUpDownButtonStyle}" Visibility="{Binding ElementName=lvItems, Path=DataContext.SelectedItem, ConverterParameter=Selected, Converter={StaticResource SelectionConverter}}" Command="{Binding DataContext.IncreaseMildewCommand, ElementName=lvItems}" Opacity="0.9"/>
<Button Grid.Row="1" Content="-" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Grid.Column="3" Margin="0,0,0,-100" Height="100" FontSize="48" Style="{StaticResource NumUpDownButtonStyle}" Visibility="{Binding ElementName=lvItems, Path=DataContext.SelectedItem, ConverterParameter=Selected, Converter={StaticResource SelectionConverter}}" Command="{Binding DataContext.DecreaseMildewCommand, ElementName=lvItems}" Opacity="0.9"/>
<Button Grid.Row="1" Content="+" HorizontalAlignment="Stretch" VerticalAlignment="Top" Grid.Column="4" Height="100" Margin="0,-100,0,0" FontSize="48" Style="{StaticResource NumUpDownButtonStyle}" Visibility="{Binding ElementName=lvItems, Path=DataContext.SelectedItem, ConverterParameter=Selected, Converter={StaticResource SelectionConverter}}" Command="{Binding DataContext.IncreaseCreditCommand, ElementName=lvItems}" Opacity="0.9"/>
<Button Grid.Row="1" Content="-" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Grid.Column="4" Margin="0,0,0,-100" Height="100" FontSize="48" Style="{StaticResource NumUpDownButtonStyle}" Visibility="{Binding ElementName=lvItems, Path=DataContext.SelectedItem, ConverterParameter=Selected, Converter={StaticResource SelectionConverter}}" Command="{Binding DataContext.DecreaseCreditCommand, ElementName=lvItems}" Opacity="0.9"/>-->
</Grid>
</DataTemplate>
风格:
<Style x:Key="ReturnDataListViewItemStyle" TargetType="ListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<ListViewItemPresenter x:Name="listViewItemPresenter" d:DesignWidth="938.908" d:DesignHeight="103.083"
ContentMargin="0"
DragOpacity="{ThemeResource ListViewItemDragThemeOpacity}"
DisabledOpacity="{ThemeResource ListViewItemDisabledThemeOpacity}"
HorizontalContentAlignment="Stretch"
Padding="0"
PointerOverBackgroundMargin="1"
ReorderHintOffset="{ThemeResource ListViewItemReorderHintThemeOffset}"
SelectionCheckMarkVisualEnabled="False"
SelectedBorderThickness="0"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
Margin="15,0,0,0"
SelectedForeground="Black"
SelectedPointerOverBackground="{StaticResource OrangeBackground}"
SelectedPointerOverBorderBrush="{StaticResource OrangeBackground}"
SelectedBackground="{StaticResource OrangeBackground}"
DataContext="{Binding SelectedItem}"
Content="{Binding Mode=OneWay}"
ContentTransitions="{TemplateBinding ContentTransitions}"
PlaceholderBackground="{StaticResource BackgroundGray}">
</ListViewItemPresenter>
</ControlTemplate>
</Setter.Value>
</Setter>
<!--<Setter Property="ContentTemplate" Value="{StaticResource ReturnDataTemplate}"/>-->
</Style>
在XAML页面后面的代码中,我添加了ScrollViewer的行为:
private void lvItems_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
SetScrollViewer();
}
private async void SetScrollViewer()
{
if (lvItems.SelectedItem == null)
return;
var item = lvItems.SelectedItem;
var listViewItem = (FrameworkElement)lvItems.ContainerFromItem(item);
if (listViewItem == null)
{
lvItems.ScrollIntoView(item);
}
while (listViewItem == null)
{
await Task.Delay(1);
listViewItem = (FrameworkElement)lvItems.ContainerFromItem(item);
}
var topLeft =
listViewItem
.TransformToVisual(lvItems)
.TransformPoint(new Point()).Y;
var lvih = listViewItem.ActualHeight;
var lvh = lvItems.ActualHeight;
var desiredTopLeft = (lvh - lvih) / 2.0;
var desiredDelta = topLeft - desiredTopLeft;
// Calculations relative to the ScrollViewer within the ListView
var scrollViewer = lvItems.GetFirstDescendantOfType<ScrollViewer>();
var currentOffset = scrollViewer.VerticalOffset;
var desiredOffset = currentOffset + desiredDelta;
//scrollViewer.ScrollToVerticalOffset(desiredOffset);
// better yet if building for Windows 8.1 to make the scrolling smoother use:
scrollViewer.ChangeView(null, desiredOffset, null);
}