Pergunta

Eu estou construindo um aplicativo WPF usando MVVM. Eu tenho viewmodels a serviço carregamento lento como abaixo:

public class AssignmentsViewModel
{

    List<AssignmentViewModel> _Assignments;
    public List<AssignmentViewModel> Assignments
    {
        get
        {
            if (_Assignments == null)
                _Assignments = new List<AssignmentViewModel>(Data.GetAssignments());
            return _Assignments;
        }
        set { _Assignments = value; }
    }
}
public class AssignmentViewModel
{
    List<NoteViewModel> _Notes;
    public List<NoteViewModel> Notes
    {
        get
        {
            if (_Notes == null)
                _Notes = new List<NoteViewModel>(Data.GetNotes());
            return _Notes;
        }
        set { _Notes = value; }
    }
}

The View tem as AssignmentViewModels em um ListView e as Notas em uma caixa de listagem com uma datatemplate.

Quando eu exibir uma das AssignmentViewModels que tem 160 itens que leva 1000 ms a carga. Eu pensei que era por causa da propriedade Notes agarrando a partir de uma tabela de banco de dados com 1,5 milhões de linhas. Eu verifiquei e levou apenas 60ms para preencher a lista de notas. Então, eu estou supondo que é a ligação de dados de carregamento de 160 itens para a caixa de listagem. Mas isso não deve ser o caso porque ListBoxes virtualizar seu conteúdo (I snooped-lo e verificou-se que os itens estão em um StackPanel Virtualizing).

Então, eu estou em uma perda, eu não sei como descobrir o que está levando os extras 940 ms.

O que posso fazer para controlar isto? Desempenho é fundamental, e eu não sei como melhorá-lo.

Foi útil?

Solução

Sem saber o que a interface do usuário é como existe a possibilidade de que algo da UI está retardando-o como um grande uso de BitmapEffects.

Além disso, você pode querer mudar a sua lista ao longo de uma ObservableCollection, como ligação a que podem ser significativamente mais rápido, em seguida, uma lista .

Existem também algumas boas desempenho de perfil ferramentas que podem ajudar você.

Outras dicas

Podemos ver o seu XAML?

Se você tem sua caixa de listagem dentro de um StackPanel (ou controle similar) a caixa de listagem não vai virtualizar suas entradas.

Isso vai virtualizar:

<Grid>
  <Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
    <RowDefinition Height="*" />
  </Grid.RowDefinitions>

  <Label Grid.Row=0>Your label here</Label>
  <ListBox Grid.Row=1 Your properties here... />

</Grid>

Esta não:

<StackPanel>
  <Label>Your label here</Label>
  <ListBox Your properties here... />
</StackPanel>

Dentro do StackPanel a caixa de listagem retribuirá a sua altura máxima e dependem do StackPanel para rolagem. (Sem virtualizar)

Dentro da grade caixa de listagem irá prestar à altura da linha da grade e usar o seu próprio scrollviewer. (Virtualizing)

Você também pode apenas definir a altura ou propriedades MaxHeight na caixa de listagem em vez de colocá-lo dentro de uma grade, mas se o seu usando um StackPanel eu suspeito que você quer autosizing de algum tipo.

Note que você não pode enganar, colocando o interior StackPanel da grade; sua caixa de listagem tem de ser capaz de obter uma altura máxima de algum lugar.

Você já tentou perf-teste w / o carregamento lento?

Além disso, como complicada são as suas DataTemplates / Visualizações para seus itens? Tente executar um teste w / representações TextBlock simples para se certificar de que não é o quão complicado as vistas são.

Gostaria de ter um outro olhar para o SQL e certifique-se de que sua coleção está enchendo. L2S não vai realmente preencher até você enumerar o resultado.

private IEnumerable<Thing> Method1()
{
    return _db.Things.Where(t => t.ID > 500);
}
private void Method2()
{
    var things = Method1(); // here, 'things' doesn't really contain anything
                            // even though you've already done the db fetch
    foreach (var thing in things) // 'things' gets populated here.
    {
        // do something
    }
}

ex: .ToList() chamada imediatamente após os dados são retornados. Você vai ver muito mais atividade na camada de dados que podem não ter sido acontecendo até que seu negócio ou camada de interface do usuário.

Eu percebi isso. Eu tinha um textblock que precisava TextWrapping porque é muito grande, às vezes. I definir explicitamente a largura do mesmo (para que ele iria envolvê) dentro do datatemplate e por algum motivo que faz com que o VirtualizingStackPanel dentro da caixa de listagem para realizar todos os itens na lista. Eu reescrevi-lo para se encaixar em uma grade como assim ..

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="3*" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Grid Grid.Column="0">
       ....
    </Grid>
    <ListBox Grid.Column="1" ItemsSource="{Binding}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" >
       ...//DataTemplate
    </ListBox>
</Grid>

Isso fez com que a caixa de listagem para carregar rapidamente. Muito obrigada por suas respostas que me trouxe no caminho certo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top