我正在开发一个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);
        }
    }
  • 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);
    }