2013-04-19 3 views
0

Если у вас есть время, создайте новый шаблон Blank App (XAML) и напишите следующий код XAML.Как вы можете отключить переработку контейнеров в приложении Windows 8?

Я думаю, что создание Приложение WPF бесполезно, потому что похоже, что переработка контейнера не работает. Кроме того, GridView необходимо заменить на ListView.

<Page.Resources> 
    <vm:MainViewModel x:Key="Main" /> 
</Page.Resources> 

<Page.DataContext> 
    <Binding Source="{StaticResource Main}" /> 
</Page.DataContext> 

<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}" 
     VerticalAlignment="Center"> 
    <Grid.Resources> 
    <Style x:Key="GridViewStyle1" 
      TargetType="GridView"> 
     <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="GridView"> 
      <ScrollViewer HorizontalSnapPointsAlignment="Near" 
          HorizontalSnapPointsType="MandatorySingle"> 
       <ItemsPresenter VirtualizingStackPanel.VirtualizationMode="Standard" /> 
      </ScrollViewer> 
      </ControlTemplate> 
     </Setter.Value> 
     </Setter> 
    </Style> 
    </Grid.Resources> 
    <GridView Style="{StaticResource GridViewStyle1}" 
      ItemsSource="{Binding Items}" 
      SelectionMode="None"> 
    <GridView.ItemTemplate> 
     <DataTemplate> 
     <StackPanel Orientation="Horizontal" 
        Loaded="StackPanel_Loaded"> 
      <Grid Width="800" 
       Height="400"> 
      <ScrollViewer HorizontalScrollBarVisibility="Hidden" 
          VerticalScrollBarVisibility="Visible"> 
       <Border Background="#b7d84b"> 
       <TextBlock Foreground="Black" 
          Text="{Binding Message}" /> 
       </Border> 
      </ScrollViewer> 
      </Grid> 
     </StackPanel> 
     </DataTemplate> 
    </GridView.ItemTemplate> 
    </GridView> 
</Grid> 

Создать представление-модель и Item класс:

public class MainViewModel 
{ 
    private const int NumberOfItems = 10000; 

    public ObservableCollection<Item> Items 
    { 
     get; 
     private set; 
    } 

    public MainViewModel() 
    { 
     var tempCollection = new ObservableCollection<Item>(); 

     for (var index = 0; index < NumberOfItems; ++index) 
     { 
      var item = new Item 
      { 
       Id = index, 
       Message = GetMessage(index) 
      }; 

      tempCollection.Add(item); 
     } 

     Items = tempCollection; 
    } 

    private string GetMessage(int index) 
    { 
     var sb = new StringBuilder(); 

     for(var i = 0; i < 100; ++i) 
     { 
      sb.Append("...\n"); 
     } 

     sb.Append("This is item #"); 
     sb.Append(index); 

     return sb.ToString(); 
    } 
} 

public class Item 
{ 
    public string Message { get; set; } 
    public int Id { get; set; } 
} 

При запуске приложения, вы можете прокрутить через ряд элементов. Я заметил, что когда вы прокручиваете определенный элемент по вертикали, чтобы вы могли видеть сообщение «Это сообщение« # x », после прокрутки вправо вы увидите еще одно сообщение« Это элемент #x »(хотя вы не прокручивали элемент вертикально.)

Это потому, что элементы виртуализированы. И когда предмет становится понятным, контейнер используется из пула. И если у вас есть невезение, контейнер уже прокручивается ...

Есть 10 пунктов в бассейне:

program output in code behind file

код позади файла:

private readonly DateTime _start; 

public MainPage() 
{ 
    this.InitializeComponent(); 
    _start = DateTime.Now; 
} 

[Conditional("DEBUG")] 
public void WriteDebugMessage(string message) 
{ 
    var span = DateTime.Now - _start; 
    Debug.WriteLine(
     "{0:D2}:{1:D2}:{2:D3} - {3}", 
     span.Minutes, 
     span.Seconds, 
     span.Milliseconds, 
     message); 
} 

private void StackPanel_Loaded(object sender, RoutedEventArgs e) 
{ 
    WriteDebugMessage("StackPanel loaded."); 
} 

Далее Я обновляю объект ItemsPresenter:

<ItemsPresenter VirtualizingStackPanel.VirtualizationMode="Standard"/> 

Если это сработало, повысить производительность.

Кто-нибудь знает элегантное решение проблемы? Я не хочу быть уволен из-за слишком большого числа открытых полей;) Я также думал о написании вложенное свойство ...

ответ

0

Обновлено:

Я до сих пор не знаю, почему

<ItemsPresenter VirtualizingStackPanel.VirtualizationMode="Standard"/> 

не работает. Поэтому мое последнее решение - это взломать. Кроме того, прокрутка влево может отображать элемент, который возвращается, хотя вы уже прокручивали его по вертикали. Я использую вложенное свойство в MainPage.xaml.cs определить смещение по вертикали для каждого вертикального ScrollViewer:

public static double GetVerticalOffset(DependencyObject obj) 
{ 
    return (double)obj.GetValue(VerticalOffsetProperty); 
} 

public static void SetVerticalOffset(DependencyObject obj, double value) 
{ 
    obj.SetValue(VerticalOffsetProperty, value); 
} 

public static readonly DependencyProperty VerticalOffsetProperty = 
    DependencyProperty.RegisterAttached("VerticalOffset", typeof(double), typeof(MainPage), new PropertyMetadata(-1.0, OnVerticalOffsetPropertyChanged)); 

private static void OnVerticalOffsetPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
{ 
    var sv = d as ScrollViewer; 
    if (sv != null) 
    { 
     sv.ScrollToVerticalOffset((double) e.NewValue); 
    } 
} 

Каждый раз, когда данные для конкретного объекта запрошенных в решении для виртуализации данных, элемент в VerticalOffset свойство равно 0. Это вызывает делегат из-за значения по умолчанию -1.

Смежные вопросы