Microsoft-ui-xaml: Discussão: WinUI DataGrid moderno - entrada necessária

Criado em 28 out. 2019  ·  81Comentários  ·  Fonte: microsoft/microsoft-ui-xaml

Discussão: Modern WinUI DataGrid

Olá, membros da comunidade! Vimos que o DataGrid tem sido uma peça valiosa do Windows Community Toolkit para muitos de vocês e estamos interessados ​​em transformá-lo em um controle WinUI nativo (!!). Preciso de sua ajuda para descobrir o que seria necessário para tornar um DataGrid em escala real o melhor possível.

Quero ouvir sua opinião sobre todas as coisas do DataGrid. Para começar, sinta-se encorajado a responder quantas perguntas você tiver tempo para:

  1. Quais são alguns itens da lista de desejos que você deseja para o DataGrid?
  2. Onde o DataGrid pode melhorar em termos de UI, UX e design geral?
  3. O que você gosta / não gosta no DataGrid?
  4. Quais são alguns cenários em que você usa DataGrid?
  5. Há algum cenário em que você gostaria que ele se encaixasse melhor?

Agradecemos antecipadamente a todos! Veja os links abaixo para algumas atualizações e contexto.

Links Relacionados


Leia sobre a documentação do DataGrid
Baixe e interaja com o DataGrid por meio do download do pacote DataGrid Nuget
Atualize seus conhecimentos verificando a implementação de DataGrid de código aberto existente

discussion

Comentários muito úteis

Minha lista de desejos: para mim, um bom datagrid inclui todos os seguintes recursos por padrão. Estou pegando emprestado algumas imagens do mundo html.

Filtre facilmente a página inteira com a contagem de linhas preferida.

1

Selecionar / Desmarcar Colunas Visíveis, Classificação de Colunas, Copiar, Imprimir

2

Exporte dados para um formato específico.

3

Reordenação de coluna arrastando coluna.

4

Filtro de coluna

5

Cabeçalho fixo - onde o cabeçalho permanece no topo, mesmo durante a rolagem

Detalhes de linha com modelo XAML para obter detalhes.

6

Agrupamento de linha

7

Arrastar e soltar a ordem das linhas

8

Os recursos acima, na minha opinião, devem ser padrão em todos os datagrids.

Se você quiser fazer com que o datagrid se destaque no mundo html, eu também incluiria o seguinte. Eu me pego muitas vezes olhando para um datagrid e, em seguida, estabelecendo um listview, pois o datagrid não tem esses recursos.

Deslize para o lado da linha para incluir recursos como editar, excluir, sinalizar, etc.

sideswipe

Os recursos acima lidam principalmente com a "apresentação de dados", o que ainda falta no WinUI é o que eu acredito que deveria ser um recurso nativo do WinUI (controle) como o Microsoft Pivot Control. para complementar o datagrid.

MS já tem o código-fonte para isso e era um controle absolutamente incrível naquela época.

pivot1

https://www.youtube.com/watch?v=ZJIkQ9nebKY

Agora você cobre a apresentação e visualização de dados que devem ser o mínimo para definir o WinUI além de todos os recursos básicos existentes.

Mais importante ainda, ele realmente exibe o poder dos "aplicativos nativos" que devem incluir animações incríveis e controles visualmente atraentes que são poderosos e têm uma aparência muito boa.

Posso dar um passo adiante e dizer que, depois dos recursos acima (visualizações), podemos incluir animações 2D / 3D que criam um conceito de profundidade nos dados e nos levam a uma estratosfera diferente, mas acho que fica para outro dia; ))

uwp2

Todos 81 comentários

Mais modos de visualização. Dê uma olhada no File Explorer e suas visualizações de ícones. O DataGrid deve ser capaz de mostrar ícones / itens em uma grade com agrupamento, bem como as linhas e colunas com cabeçalho.

Eu sei que isso pode não ser possível, ou fora do escopo - mas é um aspecto do WinUI vs Win32 que não é tão fácil quanto 1: 1 - e uma versão moderna do Explorador de Arquivos, ou Diálogos de Arquivos Comuns - pode precisar de tal controle. Pode ser esse controle, não um controle interno personalizado.

Minha lista de desejos: para mim, um bom datagrid inclui todos os seguintes recursos por padrão. Estou pegando emprestado algumas imagens do mundo html.

Filtre facilmente a página inteira com a contagem de linhas preferida.

1

Selecionar / Desmarcar Colunas Visíveis, Classificação de Colunas, Copiar, Imprimir

2

Exporte dados para um formato específico.

3

Reordenação de coluna arrastando coluna.

4

Filtro de coluna

5

Cabeçalho fixo - onde o cabeçalho permanece no topo, mesmo durante a rolagem

Detalhes de linha com modelo XAML para obter detalhes.

6

Agrupamento de linha

7

Arrastar e soltar a ordem das linhas

8

Os recursos acima, na minha opinião, devem ser padrão em todos os datagrids.

Se você quiser fazer com que o datagrid se destaque no mundo html, eu também incluiria o seguinte. Eu me pego muitas vezes olhando para um datagrid e, em seguida, estabelecendo um listview, pois o datagrid não tem esses recursos.

Deslize para o lado da linha para incluir recursos como editar, excluir, sinalizar, etc.

sideswipe

Os recursos acima lidam principalmente com a "apresentação de dados", o que ainda falta no WinUI é o que eu acredito que deveria ser um recurso nativo do WinUI (controle) como o Microsoft Pivot Control. para complementar o datagrid.

MS já tem o código-fonte para isso e era um controle absolutamente incrível naquela época.

pivot1

https://www.youtube.com/watch?v=ZJIkQ9nebKY

Agora você cobre a apresentação e visualização de dados que devem ser o mínimo para definir o WinUI além de todos os recursos básicos existentes.

Mais importante ainda, ele realmente exibe o poder dos "aplicativos nativos" que devem incluir animações incríveis e controles visualmente atraentes que são poderosos e têm uma aparência muito boa.

Posso dar um passo adiante e dizer que, depois dos recursos acima (visualizações), podemos incluir animações 2D / 3D que criam um conceito de profundidade nos dados e nos levam a uma estratosfera diferente, mas acho que fica para outro dia; ))

uwp2

Um bom ponto de partida é olhar para seu parceiro Telerik com seu RadDataGrid (UWP Open Source). Com um dos meus clientes, usei-o e realmente funciona bem. É hiper rápido e versátil. A única coisa que é difícil é o seu código, não há como modificar nada do seu motor sem uma boa compreensão da arquitetura.

Eu esperaria que o novo DataGrid tivesse o mesmo desempenho do Telerik.

Estou muito feliz em ver que a equipe WinUI está considerando um controle DataGrid.

As melhorias mais substanciais que gostaria de ver em um novo controle para substituir o Toolkit DataGrid:

  • A capacidade de recuperar um DataGridRow por índice
  • Eventos específicos para os próprios DataGridRows. Por exemplo, DoubleTapped e RightTapped.
  • Rolagem suave
  • Validação de entrada para renomeação de células
  • Um DataGridColumn projetado especificamente para ícones de linha
  • Fácil personalização de cores, etc.

A opção de ter um botão de edição que coloque ícones arrastáveis ​​ao lado de cada linha para mover a ordem seria um recurso útil. Também seria ótimo ver algumas sombras atrás da linha sendo levantadas e movidas (já que um dos principais atributos do Fluent é a profundidade). Pequenas setas para cima e para baixo podem ser boas ao lado do ícone de arrastar para mover as linhas mais facilmente com a entrada do mouse. Se uma linha for movida usando as setas, uma animação deslizante sutil seria um toque agradável. Com a entrada por toque, a opção de segurar uma linha e apenas movê-la sem precisar pressionar o botão de edição também pode funcionar bem. Não tenho certeza se isso já é suportado, mas pude ver as caixas de seleção, como no File Explorer, tornando óbvio quais DataGrids suportam a seleção de linha e apenas melhorar a UX geral. O aplicativo de lembretes do iOS contém algumas dessas idéias (exemplos ilustrados abaixo). O aplicativo iOS Stocks também tem um tipo de tratamento semelhante com as linhas móveis. A maioria dessas idéias também funcionaria muito bem para colunas.

123456

IMG_1820 (1)

@NoahFeller Esse tipo de ação faz mais sentido para uma visualização em lista. Com uma visualização em Grade, você não está reorganizando a ordem, deve haver opções de classificação, mas o usuário não está arrastando as coisas.

*Editar
Depois de pensar um pouco mais sobre isso, vejo como essa opção pode ser útil. No entanto, definitivamente não acho que esse deve ser o comportamento padrão.

@NoahFeller Esse tipo de ação faz mais sentido para uma visualização em lista. Com uma visualização em Grade, você não está reorganizando a ordem, deve haver opções de classificação, mas o usuário não está arrastando as coisas.

*Editar
Depois de pensar um pouco mais sobre isso, vejo como essa opção pode ser útil. No entanto, definitivamente não acho que esse deve ser o comportamento padrão.

Sim, você provavelmente está certo @yaichenbaum. Eu estava imaginando essas sugestões como a capacidade de fazer uma classificação personalizada e pensei que arrastar poderia ser útil para isso. Então, eu concordo, definitivamente não é o padrão, mas pode ser muito útil como uma opção. Obrigado pelo feedback!

A simplicidade da tabela de dados WPF para função de grade de dados. Na verdade, tenho lutado durante a última semana ou mais tentando fazer um datagrid UWP funcionar como eu tinha no WPF, onde eu poderia apenas vincular um Datagrid a um Dataview e, em seguida, preencher o Dataview do SQL com um datatable.defaultview. A grade então apenas exibiu a tabela de dados. Foi incrivelmente simples de fazer e a UWP até agora tornou isso ridiculamente complicado.

faça-o cruzar plataforma

Eu gostaria de solicitar um modo de seleção de célula única, estilo excel.
O objetivo final é um modo com o comportamento exato de um WinForms DataGridView.

Ter uma variedade de opções de virtualização que podem oferecer suporte a diferentes casos de uso (desde opções de virtualização de rolagem simples, como reciclagem, até outros conceitos, como paginação de dados)
Freqüentemente (em controles de área de trabalho semelhantes que suportam isso), algumas dessas opções começam a falhar quando usadas com modelos personalizados para colunas com dados exclusivos. Quanto mais eles puderem apoiar nesses casos, melhor.

Se possível, a proposta do Controle de Paginação nº 268 deve ser sincronizada e todos os ganchos necessários devem ser adicionados ao controle DataGrid.

Esta é uma boa notícia! Há algum tempo estou esperando por algo oficial no front do DataGrid, desde que ele apareceu no kit de ferramentas da comunidade. Este é realmente o último controle ausente do WinUI 3.0 para o qual o kit de ferramentas da comunidade não tem uma boa alternativa.

Em primeiro lugar, por favor, não reinvente a roda. Como base, comece com a implementação WPF do DataGrid (eu sei que você não pode usar o código, mas por favor, use 100% da API) - NÃO o Silverlight. O WPF DataGrid era muito mais completo em recursos e tinha menos bugs em meus testes.

Ao usar o kit de ferramentas da comunidade DataGrid, também solicitei as seguintes adições de API que surgiram para vários casos de uso. Discussão aqui :

  • RowPressed: Como discutido acima. Indica que uma linha foi pressionada para que o processamento posterior ou o menu de contexto possam ocorrer.
  • RowDoublePressed: mesmo que RowPressed, apenas a versão de duplo clique.
  • ColumnHeaderPressed: ocorre sempre que um cabeçalho de coluna é pressionado. Deve ter prioridade sobre qualquer atualização interna de direção de classificação. Isso permitirá menus de filtragem personalizados ou opções de clique com o botão direito para ligar / desligar as colunas.
  • ColumnHeaderDoublePressed: igual a ColumnHeaderPressed, apenas a versão de clique duplo.
  • ColumnHeaderWidthChanged: ocorre sempre que o usuário redimensiona a largura do cabeçalho de uma coluna. Isso permitirá salvar essas informações de forma limpa. Normalmente, isso é necessário ao restaurar o estado da IU.

Eu também continuo tendo muitos problemas com a comunidade que pegou o DataGrid redefinindo a posição de rolagem para o topo depois que ItemsSource é alterado. Isso precisa ser corrigido para que o deslocamento seja preservado como no WPF; no entanto, também precisamos ser capazes de controlar isso, por isso também sugiro a seguinte API:

  • FirstRowInView (): Retorna a primeira linha visível no DataGrid usado para restaurar o estado.
  • VerticalOffset: Get / Set novamente para restaurar o estado da barra de rolagem
  • HorizontalOffset: Get / Set para restaurar o estado da barra de rolagem

@RBrid Também ajudou com algumas análises aqui :

Novos eventos sugeridos e algumas melhorias para eventos preexistentes:

| Evento | Comentários |
| : --- | : --- |
| ContextRequestedForColumnHeader | Para suportar a exibição de um menu de contexto (ou outro menu desdobrável) quando um cabeçalho de coluna é clicado com o botão direito. O mesmo que Windows.UI.Xaml.UIElement.ContextRequested mas para cabeçalhos de coluna em vez de todo o DataGrid. |
| ContextCanceledForColumnHeader | O mesmo que Windows.UI.Xaml.UIElement.ContextCanceled mas para cabeçalhos de coluna em vez de todo o DataGrid. |
| ContextRequestedForRow | Para suportar a exibição de um menu de contexto (ou outro menu desdobrável) quando uma linha é clicada com o botão direito. O mesmo que Windows.UI.Xaml.UIElement.ContextRequested mas para linhas em vez de todo o DataGrid. |
| ContextCanceledForRow | O mesmo que Windows.UI.Xaml.UIElement.ContextCanceled mas para linhas em vez de todo o DataGrid. |
| RowTapped | Observe também o caso de tocar em uma linha que já está selecionada. |
| RowDoubleTapped | O mesmo que Windows.UI.Xaml.UIElement.DoubleTapped mas para linhas em vez de todo o DataGrid. |
| RowRightTapped | O mesmo que Windows.UI.Xaml.UIElement.RightTapped mas para linhas em vez de todo o DataGrid. Veja também ContextRequestedForRow . |
| PointerPressedInRow | O mesmo que Windows.UI.Xaml.UIElement.PointerPressed mas para linhas em vez de todo o DataGrid. |
| PointerReleasedInRow | O mesmo que Windows.UI.Xaml.UIElement.PointerReleased mas para linhas em vez de todo o DataGrid. |
| PointerMovedInRow | O mesmo que Windows.UI.Xaml.UIElement.PointerMoved mas para linhas em vez de todo o DataGrid. Possivelmente PointerMovedInRow só seria disparado enquanto o ponteiro for capturado. |
| ColumnHeaderTapped | Observe também o caso de tocar em um cabeçalho de coluna que já está selecionado. |
| ColumnHeaderDoubleTapped | O mesmo que Windows.UI.Xaml.UIElement.DoubleTapped mas para cabeçalhos de coluna em vez de todo o DataGrid. |
| ColumnHeaderRightTapped | O mesmo que Windows.UI.Xaml.UIElement.RightTapped mas para cabeçalhos de coluna em vez de todo o DataGrid. Veja também ContextRequestedForColumnHeader . |
| ColumnHeaderWidthChanged | Alternativamente, poderia ser denominado ColumnHeaderResized . No evento args, inclua uma propriedade booleana que especifica se foi alterado pelo usuário ou alterado programaticamente. Obviamente, os argumentos do evento também devem especificar qual cabeçalho da coluna foi redimensionado / alterado. |
| SortOrderChanged | Deve ser acionado quando a lista de cabeçalhos de coluna selecionados muda. Também acionado quando qualquer uma das colunas selecionadas é alternada entre a ordem crescente e decrescente. No evento args, inclua uma propriedade booleana que especifica se a ordem de classificação foi alterada pelo usuário ou alterada programaticamente. Veja também o evento pré-existente Sorting . Eu acho que um novo evento SortOrderChanged seria disparado depois que o evento Sorting fosse disparado, se a classificação não fosse cancelada. |
| Sorting | Já existe, mas considere adicionar uma propriedade booleana configurável em argumentos de evento que permite que a solicitação de classificação seja cancelada. Por exemplo, a classificação pode ser inválida ou impossível de ser realizada e precisa ser cancelada. Adicione também uma propriedade booleana para especificar se a classificação foi solicitada pelo usuário ou programaticamente. |
| ColumnSortDirectionChanged | Este evento pode ser criado, mas pode ser desnecessário se o evento SortOrderChanged acima mencionado for criado, se SortOrderChanged também for acionado quando a direção da classificação mudar. |
| ColumnDisplayIndexChanged | Já existe, mas considere adicionar uma propriedade booleana (em argumentos de evento) que especifica se foi alterado pelo usuário ou alterado programaticamente. Além disso, documente por que é necessário ter os eventos ColumnDisplayIndexChanged e ColumnReordered . Como alternativa, elimine um desses eventos. |
| ColumnReordered | Já existe, mas considere adicionar uma propriedade booleana que especifica se foi alterada pelo usuário ou alterada programaticamente. |
| SelectionChanged | Já existe, mas considere adicionar uma propriedade booleana (em argumentos de evento) que especifica se foi alterado pelo usuário ou alterado programaticamente. |
| CopyingRowClipboardContent | Já existe, mas considere adicionar uma propriedade booleana aos argumentos do evento que especifica se a operação é cortada em vez de copiar. Como alternativa, faça um evento separado para corte. |
| CuttingRowClipboardContent | Não existe. Considere fazer um evento que seja disparado quando o usuário tenta cortar linhas (via tecla de atalho control-X, menu de contexto ou outro). Como alternativa, crie a propriedade booleana mencionada anteriormente que permitiria que CopyingRowClipboardContent fosse acionado para ambas as operações de cópia e corte |
| PastingRowClipboardContent | Não existe. Considere criar um evento que seja disparado quando o usuário tenta colar (via tecla de atalho control-V, menu de contexto ou outro). |

Acho que o recurso mais importante para mim seria a capacidade de lidar facilmente com um milhão de linhas ou mais, sem ter que carregar um milhão de linhas na memória. A interface ISupportIncrementalLoading não é boa o suficiente para isso, porque a barra de rolagem apenas reflete quantas linhas você carregou até agora (não a contagem total), e para chegar à linha 1 milhão, você teria que continuar rolando até o fim e carregue mais e mais dados, e espero não ficar sem memória. Mas se eu sei que tenho 1 milhão de registros de dados, deixe-me dizer isso ao datagrid, e se eu rolar rápido ou pular para o final, pode ser solicitado que forneça apenas as últimas linhas.
Pense em rolar por uma lista de linhas em um banco de dados que puxarei dinamicamente.

Acho que o recurso mais importante para mim seria a capacidade de lidar facilmente com um milhão de linhas ou mais, sem ter que carregar um milhão de linhas na memória. A interface ISupportIncrementalLoading não é boa o suficiente para isso, porque a barra de rolagem apenas reflete quantas linhas você carregou até agora (não a contagem total), e para chegar à linha 1 milhão, você teria que continuar rolando até o fim e carregue mais e mais dados, e espero não ficar sem memória. Mas se eu sei que tenho 1 milhão de registros de dados, deixe-me dizer isso ao datagrid, e se eu rolar rápido ou pular para o final, pode ser solicitado que forneça apenas as últimas linhas.
Pense em rolar por uma lista de linhas em um banco de dados que puxarei dinamicamente.

Esse.

'Moderno' significa leve e rápido, e os aplicativos corporativos geralmente tratam de classificar toneladas de dados internos para encontrar e explorar os registros apropriados. Paginação, classificação, carregamento incremental assíncrono, rolagem sem fim - todos esses são itens básicos de aplicativos de desktop que alavancam grades de dados.

A MS deve produzir um aplicativo de amostra que destaca esses recursos na nova grade e coleta feedback de desenvolvedores corporativos ao longo do tempo para tornar essas experiências melhores. Faça com que seja executado em um grande conjunto de dados, como World Wide Importers, para demonstrar sua eficácia.

@dotMorten

Acho que o recurso mais importante para mim seria a capacidade de lidar facilmente com um milhão de linhas ou mais, sem ter que carregar um milhão de linhas na memória.

Eu desejo isso também. Para auxiliar no suporte de um milhão de linhas (e quero dizer auxiliar, não necessariamente a solução completa), sugiro que o DataGrid torne opcional sua técnica de vinculação de dados atual. Acredito que atualmente a vinculação de dados é obrigatória (a menos que meu conhecimento não esteja mais atualizado com a versão mais recente do DataGrid). O DataGrid não deve exigir o uso de Windows.UI.Xaml.Data.Binding como a única forma com suporte de recuperar os valores de cada célula / coluna em cada linha visível.

Sugiro que o DataGrid permita que os aplicativos forneçam ao DataGrid um delegado ou instância de interface que o DataGrid invocará sempre que o DataGrid precisar recuperar o valor de uma célula / coluna em uma linha (alternativamente, este delegado ou interface pode recuperar a linha inteira - todos os valores da coluna para uma linha especificada).

Idealmente (se possível), o DataGrid permitiria que esse delegado ou interface operasse de forma assíncrona . Por exemplo, o delegado ou interface pode retornar Task ou IAsyncOperation<TResult> vez de retornar imediatamente o valor solicitado.

Alternativamente, o suporte assíncrono também é possível sem Task e IAsyncOperation<TResult> , se DataGrid operar de forma semelhante ao seguinte procedimento:

  1. O DataGrid decide que precisa recuperar o valor da célula / coluna 5 na linha ID 50001. Alternativamente, o DataGrid decide recuperar todos os valores da coluna para a linha ID 50001.
  2. DataGrid invoca um delegado ou instância de interface ou manipulador de eventos que notifica o aplicativo de que DataGrid solicitou o carregamento dos valores de dados da coluna / linha especificada ou linha inteira.
  3. O aplicativo recupera os dados da linha solicitados de forma assíncrona. Por exemplo, ele pode executar de forma assíncrona uma consulta ao banco de dados SQL.
  4. O aplicativo termina de recuperar os dados de linha solicitados. O aplicativo invoca um método em DataGrid que fornece os dados de linha para DataGrid.
  5. DataGrid exibe os dados da linha ou faz tudo o que for necessário para fazer com os dados.

Em primeiro lugar, uau !! Muito obrigado a todos que estão contribuindo com suas idéias. Tenho algumas respostas específicas abaixo, mas no geral gostaria de dizer que estou salvando muitos desses comentários e estou gostando muito de ouvir como podemos construir um DataGrid moderno incrível. Deixe vir!

@Pinox muito obrigado por essa resposta detalhada e as capturas de tela. Sua lista de desejos é incrível (especialmente aquelas animações legais!) - Eu concordo que esses recursos encontrados em html são um bom ponto de inspiração e são simples, mas melhorariam muito a qualidade de vida. Definitivamente guardarei este comentário para referência futura!

@verelpode , @robloo , @ duke7553 SIM para eventos específicos do DataGrid! Obrigado a todos pelos detalhes que você colocou neles. Como projetamos para o toque primeiro e para uma variedade de entradas, eventos como esses definitivamente devem ser implementados!

@dotMorten , @jkewley , @verelpode Performance é definitivamente uma das principais motivações para este projeto e uma das principais melhorias que queremos implementar, através de uma nova história de virtualização de dados e do uso de controles modernos como o ItemsRepeater. Manteremos todos atualizados assim que tivermos mais detalhes - mas obrigado novamente por esses detalhes que você sugeriu.

@ Laz3rPanth3r , @robloo , @keeganatorr Ouvimos em alto e bom som sobre gostar de DataGrids que pertencem ao WPF e outras estruturas de IU - definitivamente estamos levando isso em consideração nesta atualização!

Obrigado pelo excelente trabalho no DataGrid e pelo pedido de feedback! Aqui estão mais algumas sugestões de melhorias.

Precisa de mais subclasses de DataGridColumn

As subclasses / implementações atuais de DataGridColumn são insuficientes. Eu sugiro fazer as seguintes novas subclasses de DataGridColumn :

| Subclasse proposta | Descrição
| : --- | : --- |
| DataGridIconColumn | Um requisito comum é exibir um ícone em cada linha de uma lista, portanto, sugiro fazer uma subclasse de DataGridColumn chamada DataGridIconColumn que tipifique o valor da célula recuperada para Windows.UI.Xaml.Controls.IconSource e renderize o IconSource instância (uma instância IconSource é renderizada em cada célula). |
| DataGridImageColumn | DataGridImageColumn deve operar da mesma forma que o proposto DataGridIconColumn exceto que deve renderizar Windows.UI.Xaml.Media.ImageSource vez de Windows.UI.Xaml.Controls.IconSource . |
| DataGridDateTimeColumn | Exibe a data e / ou hora, dependendo das configurações. Tipografa o valor da célula em System.DateTimeOffset ou System.DateTime (ambos com suporte) e o converte em texto a ser exibido na célula. A conversão em texto deve ser controlada por configurações / propriedades de formatação na classe DataGridDateTimeColumn . Obviamente, a classificação por data / hora também deve ser suportada. |
| DataGridTimeSpanColumn | Tipografa o valor da célula em System.TimeSpan e o converte em texto a ser exibido na célula. A conversão para texto deve ser controlada por configurações / propriedades de formatação na classe DataGridTimeSpanColumn . Obviamente, a classificação também deve ser suportada e deve classificar as instâncias de TimeSpan não o texto exibido. |
| DataGridDataSizeColumn | Tipografa o valor da célula em System.Int64 , UInt64 , Int32 ou UInt32 (todos com suporte) e o converte para um tamanho em bytes (como texto ) a ser exibido. Por exemplo, 1572864 seria exibido como "1,5 MB" porque 1572864/1024/1024 = 1,5. A conversão para texto deve ser controlada por configurações / propriedades na classe DataGridDataSizeColumn . A classificação deve ser realizada usando o valor inteiro original, não o texto exibido. |
| DataGridCustomColumn | Ele deve operar de forma semelhante ao DataGridTemplateColumn preexistente, exceto sem o Windows.UI.Xaml.DataTemplate . Ele deve invocar um delegado / retorno de chamada ou evento para gerar e / ou atualizar a subárvore do elemento GUI exibido. |
| DataGridTextColumn | Já existe, mas considere adicionar propriedades ou eventos que permitem que os aplicativos substituam a conversão de objeto em texto e a função de comparação para classificação. Explico isso com mais detalhes posteriormente em minha mensagem. |

DataGridCustomColumn seria assim:

public class DataGridCustomColumn : DataGridColumn
{
    public event EventHandler<DataGridDisplayingCellEventArgs> DisplayingCell;
}

public class DataGridDisplayingCellEventArgs : EventArgs
{
    public DataGridColumn Column { get; }
    public object CellValue { get; }
    public Windows.UI.Xaml.UIElement CellUIElement { get; set; } // settable
}

Quando o evento DataGridCustomColumn.DisplayingCell é disparado, o manipulador de eventos deve gerar ou atualizar sua própria subárvore UIElement para exibir DataGridDisplayingCellEventArgs.CellValue e definir a propriedade DataGridDisplayingCellEventArgs.CellUIElement para isso UIElement subárvore e, em seguida, DataGrid irá exibi-la.

Na próxima vez que DataGrid acionar este evento, DataGrid deve definir a propriedade DataGridDisplayingCellEventArgs.CellUIElement para a instância UIElement que foi gerada anteriormente pelo manipulador de eventos, a fim de permitir que o manipulador de eventos reutilize / recicle e atualize a mesma subárvore UIElement (potencialmente com um valor diferente em DataGridDisplayingCellEventArgs.CellValue ). O manipulador de eventos pode reciclar a mesma UIElement subárvore OU definir a propriedade DataGridDisplayingCellEventArgs.CellUIElement para uma UIElement subárvore recém-criada.

Considere também a possibilidade de fazer o novo evento DisplayingCell diretamente na classe base DataGridColumn , ao invés de fazer a subclasse DataGridCustomColumn . Assim, o evento DataGridColumn.DisplayingCell poderia permitir a personalização ou sobrescrever o UIElement gerado para cada subclasse de DataGridColumn .

No DataGridTextColumn preexistente, atualmente o valor / objeto da célula é convertido em texto para exibição invocando System.Object.ToString . Considere fazer um delegado / retorno de chamada ou evento que permite que os aplicativos substituam essa conversão de valor em texto. Considere também uma propriedade que permite que os aplicativos especifiquem uma instância System.Collections.IComparer para substituir o comportamento de classificação.

public class DataGridTextColumn : DataGridColumn
{
    public System.Collections.IComparer Comparer { get; set; }
    public DataGridCellValueToToStringConverter CellValueToToStringConverter { get; set; }
}

public delegate string DataGridCellValueToToStringConverter(object sourceObject);

Alternativamente, em vez de fazer a propriedade Comparer em DataGridTextColumn , considere a possibilidade de fazer a propriedade Comparer diretamente na classe base DataGridColumn , a fim de permitir aplicativos para controlar o comportamento de classificação para todas as subclasses de DataGridColumn .

Da mesma forma, a propriedade CellValueToToStringConverter também poderia ser feita na classe base DataGridColumn porque seria útil ter a capacidade de converter qualquer valor de célula em texto, independentemente de qual subclasse de DataGridColumn é usado. Por exemplo, ao copiar uma linha para a área de transferência, cada valor de célula pode ser convertido em texto. (Os formatos de texto e não-texto podem ser colocados simultaneamente na área de transferência - os aplicativos geralmente fazem isso para aumentar a compatibilidade com outros aplicativos.)

Reordenando quando um DataGridIconColumn ou DataGridImageColumn é selecionado: Obviamente, o DataGrid não pode classificar ícones ou imagens, portanto, ele pode usar qualquer uma destas soluções:

  • Simplesmente não permita que os usuários finais selecionem (classifiquem por) um cabeçalho de coluna do tipo DataGridIconColumn ou DataGridImageColumn .
  • Faça uma propriedade AlternativeText na classe IconSource . Quando DataGridIconColumn classifica as linhas ou quando converte a célula em texto para a área de transferência / cópia, ele usa a propriedade AlternativeText .
  • Faça uma propriedade Comparer configurável (do tipo System.Collections.IComparer ) em DataGridColumn ou DataGridIconColumn .

Acesso a linhas / itens selecionados

Considere melhorar a funcionalidade para obter e definir as linhas / itens selecionados, porque a funcionalidade atual é insuficiente. Atualmente essas propriedades existem:

public int SelectedIndex { get; set; }
public object SelectedItem { get; set; }
public System.Collections.IList SelectedItems { get; }

Descobri que às vezes precisava de acesso às instâncias DataGridRow das linhas selecionadas, portanto, espero que as seguintes propriedades possam ser adicionadas ao DataGrid:

public DataGridRow SelectedRow { get; set; }
public IList<DataGridRow> SelectedRows { get; }

Alternativamente, se o acima for muito difícil de implementar, a seguinte variação somente leitura é menos poderosa, mas ainda útil:

public DataGridRow SelectedRow { get; }
public IReadOnlyCollection<DataGridRow> SelectedRows { get; }

Se as instâncias de DataGridRow puderem ser recicladas , a documentação para as propriedades acima deve alertar que as informações retornadas são apenas temporariamente válidas, portanto, devem ser lidas / usadas imediatamente e não retidas por um longo período de tempo.

Além disso, a propriedade SelectedIndex preexistente dá acesso a um índice selecionado, mas que tal obter acesso a todos os itens selecionados? Portanto, sugiro fazer a seguinte propriedade SelectedIndexes :

public IList<int> SelectedIndexes { get; } // Suggestion.
public int SelectedIndex { get; set; } // Already exists.

Pessoalmente, acho o nome "SelectedIndex" confuso porque DataGrid é frequentemente usado em conjunto com um banco de dados e o termo "índice" tem um significado completamente diferente em um banco de dados, portanto, sugiro renomear as propriedades como segue, mas espero que minha sugestão de nomenclatura será rejeitado:

public IList<int> SelectedOrdinals { get; }
public int SelectedOrdinal { get; set; }

Também desejo a capacidade de rolar a DataGridRow e / ou DataGridColumn especificada para a exibição. Atualmente este método existe:

public void ScrollIntoView(object item, DataGridColumn column);

Eu sugiro substituir o método ScrollIntoView preexistente por estes 2 métodos:

public void ScrollIntoView(DataGridRow row, DataGridColumn column);
public void ScrollItemIntoView(object item, DataGridColumn column);

Obtenha e defina a ordem de classificação em um hit

Quando os aplicativos são abertos e fechados, eles precisam da capacidade de salvar e restaurar a configuração do usuário final do DataGrid, incluindo a ordem de classificação e outras configurações. A ordem de classificação significa a lista de colunas que foram selecionadas pelo usuário. Observe que esta é uma lista, não uma única coluna. Mais de uma coluna pode ser selecionada simultaneamente, o que significa a coluna primária para classificação e a coluna secundária para classificação e a coluna terciária para classificação, etc.

Portanto, a seguinte propriedade poderia ser feita em DataGrid, mas na verdade esta é apenas a primeira ideia e não é a ideal:

public IReadOnlyList<DataGridColumn> SortOrder { get; set; }

O acima não é ideal porque não suporta o salvamento e restauração de DataGridColumn.SortDirection de cada coluna em um acerto . Sei que os aplicativos podem fazer isso em várias etapas:

  1. Defina a propriedade SortOrder proposta para a lista de colunas selecionadas.
  2. Defina a propriedade SortDirection de cada uma das colunas selecionadas (repita esta etapa para cada coluna).

Isso ainda é problemático porque são vários acessos, o que significa que causa vários recursos demorados do DataGrid. Os usuários finais podem perceber e sofrer um atraso significativo em um DataGrid que contém um grande número de linhas, quando o DataGrid é reclassificado várias vezes desnecessariamente. Para eliminar esse problema, sugiro a seguinte solução que permite que os aplicativos restaurem a ordem de classificação completa em um acerto e causem não mais do que um único recurso.

public class DataGrid
{
    public IReadOnlyList<DataGridColumnAndDirection> SortOrder { get; set; }
    ...
}

public struct DataGridColumnAndDirection
{
    public readonly DataGridColumn Column;
    public readonly DataGridSortDirection SortDirection;
    public DataGridColumnAndDirection(DataGridColumn, DataGridSortDirection) { ... }
}

Nota Eu deliberadamente escrevi IReadOnlyList<DataGridColumnAndDirection> not IList<DataGridColumnAndDirection> acima porque os aplicativos não devem ser capazes de modificar a lista retornada pela propriedade SortOrder . Em vez de modificar a lista, os aplicativos devem definir a propriedade SortOrder como uma lista que o DataGrid copiará e usará para substituir completamente a lista de ordem de classificação inteira. Assim, ele operaria com um único sucesso e evitaria vários resorts caros.

Quando DataGrid.SortOrder é definido como uma nova lista, DataGrid também definiria a propriedade DataGridColumn.SortDirection em cada coluna na nova lista SortOrder , mas sem causar vários resorts. Assim, DataGrid.SortOrder[i].SortDirection é equivalente a DataGridColumn.SortDirection .

Obtenha e defina a ordem das colunas exibidas em um hit

Quando os aplicativos são abertos e fechados, eles precisam ser capazes de salvar e restaurar a ordem das colunas do usuário final, de preferência com um único acerto. Eu sei que a propriedade preexistente DataGridColumn.DisplayIndex é configurável, portanto, teoricamente, os aplicativos poderiam restaurar a configuração do usuário final iterando por todas as colunas em DataGrid.Columns e definir DisplayIndex de cada um, mas isso pode causar bugs. Por exemplo, DisplayIndex pode falhar ou se comportar de maneira inesperada quando um aplicativo precisa definir temporariamente DisplayIndex de uma coluna para o mesmo DisplayIndex de outra coluna. Além disso, se não for executado em um acerto, pode desencadear vários redesenhos e / ou recálculos caros.

Portanto, sugiro fazer uma propriedade ColumnDisplayOrder no DataGrid:

public IReadOnlyList<DataGridColumn> ColumnDisplayOrder { get; set; }

O mesmo que mencionei anteriormente para SortOrder , ColumnDisplayOrder é deliberadamente IReadOnlyList<DataGridColumn> não IList<DataGridColumn> porque deve operar em um único golpe.
Quando DataGrid.ColumnDisplayOrder é definido para uma nova lista, DataGrid atualizaria o DataGridColumn.DisplayIndex de cada coluna para corresponder.

Permitir que os usuários finais ocultem / mostrem colunas

Consistente com as propriedades preexistentes DataGridColumn.CanUserReorder etc, sugiro fazer uma CanUserChangeVisibility propriedade em DataGridColumn . Quando DataGridColumn.CanUserChangeVisibility for verdadeiro, o usuário final poderá causar alterações na propriedade DataGridColumn.Visibility .

Suporte a elementos GUI gerados dinamicamente em tempo de execução

Permita que a GUI de detalhes da linha seja gerada sem exigir o uso de DataGrid.RowDetailsTemplate ( Windows.UI.Xaml.DataTemplate ). Para conseguir isso, algum pensamento precisa ser colocado na API, mas aqui está minha primeira ideia de como fazê-lo: talvez faça isso por meio do evento preexistente DataGrid.LoadingRow alterando a propriedade DataGridRowDetailsEventArgs.DetailsElement para ser configurável de forma que o tratador de evento possa gerar (ou atualizar) o UIElement por si mesmo e fornecê-lo ao DataGrid definindo a propriedade DetailsElement .

O motivo pelo qual o uso obrigatório de Windows.UI.Xaml.DataTemplate é um problema: embora os modelos sejam um bom recurso, o conceito de modelo espera um fragmento / documento XAML pré-criado e imutável que foi escrito pelo desenvolvedor com antecedência. Portanto, os modelos são um problema quando o aplicativo precisa gerar dinamicamente a GUI no tempo de execução. Portanto, desejo as alternativas mencionadas acima para DataTemplate .

Arrastar e soltar linhas, para dentro e para fora

Eu sugiro fazer a capacidade de ativar opcionalmente arrastar e soltar linhas de saída. O DataGrid implementaria o arrastar, mas não soltar. Quando a queda ocorre, o DataGrid aciona um evento e o aplicativo responde ao evento para realizar a ação desejada quando a linha é descartada fora do DataGrid.

Além disso, a capacidade de ativar opcionalmente o recurso arrastar e soltar de linhas ou itens / objetos. DataGrid aceitaria arrastar e soltar de entrada, mas não implementa o soltar. O DataGrid acionaria um evento quando a linha / item / objeto fosse descartado e o aplicativo respondesse ao evento para realizar a ação desejada quando a linha fosse descartada dentro do DataGrid.

Planos de fundo de células individuais

Temos uma solicitação de recurso de um cliente que deseja que células individuais sejam ativadas (alterando a cor / pincel de fundo da célula) em determinados momentos (como quando nosso aplicativo detecta alterações ou valores importantes ou perigosos que excedem os limites de segurança, etc.).

Portanto, eu poderia propor uma propriedade DataGridCell.Background (do tipo Brush ), mas acho que essa maneira de fazer isso provavelmente está com defeito porque o DataGrid recicla DataGridCell instâncias, não é? Portanto, acho que eliminar células individuais definindo uma propriedade DataGridCell.Background não seria uma solução confiável.

A melhor maneira seria por meio do evento DataGridColumn.DisplayingCell que propus na minha mensagem anterior. O manipulador de eventos pode definir uma propriedade CellBackgroundBrush em DataGridDisplayingCellEventArgs .

Recuperação de dados do Dumb-down DataGrid (valores de células)

Eu sei que "idiota" soa muito mal, mas na realidade eu adoraria se o DataGrid se tornasse idiota na área de recuperação de dados (recuperação dos valores das células a serem exibidos pelo DataGrid).

Atualmente o DataGrid tenta realizar a recuperação de dados de uma maneira automática conveniente por meio de sua propriedade DataGrid.ItemsSource mais técnicas de vinculação de dados (a propriedade DataGridBoundColumn.Binding ) e interfaces como System.ComponentModel.INotifyPropertyChanged .

Sim, a vinculação de dados é um recurso conveniente, mas na verdade eu prefiro muito mais que o DataGrid faça _menos_ nesse departamento! Vários componentes da Microsoft realmente me causam grandes dificuldades por meio de seu comportamento de tentar ser inteligente, mas na verdade acabar sendo muito inteligente . No geral, eu realmente teria menos dificuldades e menos trabalho se esses componentes parassem de ser tão inteligentes / automáticos / convenientes. Ao projetar um comportamento automático, acho que vale a pena ter em mente que automático parece ótimo, mas tem potencial para sair pela culatra.

_ "Simplesmente deixe-me fazer isso sozinho." _
Às vezes, a melhor solução é simplesmente permitir que os aplicativos executem a tarefa por si próprios, em vez de tentar e falhar para fazê-lo "automaticamente" dentro de um componente como o DataGrid. Eu gostaria que o DataGrid me permitisse realizar completamente a recuperação de dados sozinho, em vez de tentar recuperar automaticamente os dados por meio das propriedades DataGridBoundColumn.Binding e DataGrid.ItemsSource .

Idealmente, gostaria de eliminar a necessidade de usar a propriedade DataGrid.ItemsSource para fornecer os itens. @dotMorten mencionou um milhão de linhas. Atualmente o DataGrid torna obrigatório para os aplicativos definir DataGrid.ItemsSource , mas é impraticável criar um objeto de lista que contenha um milhão de itens. Portanto, gostaria que o DataGrid parasse de ser inteligente no departamento de recuperação de dados e, em vez disso, me permitisse realizar a recuperação de dados sozinho, sem usar DataGridBoundColumn.Binding e DataGrid.ItemsSource .

@anawishnoff escreveu:

O desempenho é definitivamente uma das principais motivações deste projeto e uma das principais melhorias que queremos implementar, através de uma nova história de virtualização de dados e do uso de controles modernos como o ItemsRepeater.

Vejo que você disse que a nova história de virtualização de dados melhorará o desempenho, e isso é uma boa notícia, mas também eliminará a necessidade de usar a propriedade DataGridBoundColumn.Binding para fornecer os valores de célula que o DataGrid exibe?

Se todo o trabalho de recuperação de dados for terceirizado para o aplicativo que usa DataGrid, o aplicativo terá total flexibilidade para realizar a recuperação de dados de qualquer maneira que for necessária. Isso permitiria muitos cenários diferentes de recuperação de dados, incluindo os milhões de linhas que @dotMorten mencionou. Mudo, por favor: sorria:

Alguns recursos desnecessários no WPF DataGrid?

A versão WPF do DataGrid tem alguns recursos que parecem desnecessários ou impraticáveis ​​e esses recursos podem ser ignorados no WinUI DataGrid, mas espero que algumas pessoas provavelmente tenham uma opinião diferente sobre esses recursos.

Quantas pessoas levantariam uma objeção se o WinUI DataGrid abandonasse o recurso em que os usuários finais são capazes de editar os valores das células inline / diretamente dentro do DataGrid? Em nosso caso, em cada lugar onde usamos DataGrid, sempre definimos DataGrid.IsReadOnly como true para desabilitar o recurso de edição direta / inline. Nós permitimos que os usuários editem a linha selecionada em um painel ou painel separado, ou em RowDetails ( DataGrid.RowDetailsTemplate ), mas não diretamente dentro do próprio DataGrid.

Parece que o WinUI DataGrid já se moveu na direção de descartar o suporte para edição inline / direta porque o WPF DataGrid tinha CanUserAddRows e CanUserDeleteRows mas essas propriedades não existem mais no WinUI DataGrid. Por que não abandonar totalmente o recurso de edição direta / embutida? Quantas pessoas têm objeções a essa ideia?

Seleção de célula individual: WPF DataGrid tem uma propriedade SelectionUnit que você pode definir como Cell , FullRow ou CellOrRowHeader . Em nosso caso, sempre o definimos como FullRow e nunca encontramos a necessidade de defini-lo como Cell . No entanto, vejo que uma pessoa aqui já solicitou o modo de seleção de célula única. Minha pergunta é se o modo de seleção de células é um pedido comum ou raro.

Por outro lado, a seleção de células individuais pode ser útil quando o usuário copia linhas / células para a área de transferência. Isso permitiria aos usuários copiar uma célula individual (ou várias células contíguas) para a área de transferência em vez de copiar a linha inteira. No entanto, não tenho certeza se esse recurso é realmente valioso ou não.

| Recurso duvidoso no WPF | Comentários |
| : --- | : --- |
| DataGrid.IsReadOnly | Talvez nenhuma necessidade real de definir IsReadOnly como false? |
| DataGrid.CanUserAddRows | Não existe no WinUI DataGrid. Já abandonado, ou talvez ainda não implementado (não sei o plano). |
| DataGrid.CanUserDeleteRows | Não existe no WinUI DataGrid. Já abandonado, ou talvez ainda não implementado (não sei o plano). |
| DataGrid.SelectionUnit | Não existe no WinUI DataGrid. |

Uau, discussão incrível aqui. ❤️

Também concordo com a API WPF DataGrid. O WPF DataGrid é realmente o DataGrid que desejo para o WinUI 3.0.

Mas mesmo o DataGrid WPF carece de alguns recursos. No passado, a maioria dos meus clientes usava um DataGrid de terceiros mais poderoso para obter estes recursos:

  • Filtros nos cabeçalhos das colunas
  • Uma linha de filtro completa no topo do DataGrid
  • Exibição poderosa de dados hierárquicos. Alguns DataGrids de terceiros realmente funcionam como um poderoso TreeView com DataGrids aninhados. Embora o WPF DataGrid permita construir algo assim, ele não oferece suporte pronto para uso
  • Suporte para diferentes tipos de dados. Como, por exemplo, uma coluna DateTime. No DataGrid do WPF você deve usar o DataGridTemplateColumn

Mas de qualquer maneira, o que quer que você faça, acho que construir um DataGrid é uma declaração poderosa e um compromisso com o WinUI 3.0. Para aplicativos LOB, você não pode levar a sério uma estrutura de IU que não contenha um DataGrid integrado. E é ótimo ver esse investimento feito para WinUI!

@thomasclaudiushuber

Para aplicativos LOB, você não pode levar a sério uma estrutura de IU que não contenha um DataGrid integrado. E é ótimo ver esse investimento feito para WinUI!

Concordou! Em nosso caso, DataGrid é um componente essencial que usamos em vários lugares e não podemos viver sem.

Exibição poderosa de dados hierárquicos. Alguns DataGrids de terceiros realmente funcionam como um poderoso TreeView com DataGrids aninhados.

Estou indeciso sobre esse assunto porque - como você - eu acharia um DataGrid hierárquico útil em algumas situações, mas minha preocupação é que se o DataGrid implementar funcionalidade hierárquica, então ele pode se tornar excessivamente complexo e difícil, e o lançamento de O DataGrid provavelmente sofrerá um atraso substancial. Seria difícil adicionar novos recursos devido à complexidade de tornar os novos recursos compatíveis com a funcionalidade hierárquica e não hierárquica.

Para eliminar o problema de complexidade / atrasos mencionado acima, sugiro esta solução: Faça uma classe separada chamada HierarchicalDataGrid que usa / envolve internamente uma instância de DataGrid . Alternativamente HierarchicalDataGrid poderia herdar publicamente DataGrid mas suspeito que essa herança seja impraticável, portanto, prefiro sugerir que HierarchicalDataGrid herde Control e internamente tenha um campo privado de digite DataGrid . Assim, a funcionalidade hierárquica seria implementada na camada HierarchicalDataGrid que dirige uma instância interna não hierárquica DataGrid .

A principal vantagem da solução acima é que forneceria os recursos hierárquicos desejados _sem_ sobrecarregar DataGrid , sem tornar DataGrid tão complexo que se tornaria incontrolável e lento para desenvolver.

Suporte para diferentes tipos de dados. Como, por exemplo, uma coluna DateTime.

Eu concordo. Verifique DataGridDateTimeColumn e DataGridTimeSpanColumn que propus em uma mensagem anterior.

@Pinox

Filtre facilmente toda a página

@thomasclaudiushuber

Filtros nos cabeçalhos das colunas; Uma linha de filtro completa na parte superior do DataGrid;

Os filtros seriam ótimos para ajudar os usuários finais a encontrar rapidamente uma linha ou linhas, em vez da situação atual de ser forçado a examinar manualmente um grande número de linhas para encontrar o que estão procurando.

Mas e quanto ao problema de combinar o texto do filtro do usuário com as colunas que não são de texto? Significa colunas diferentes de DataGridTextColumn , como filtragem com DataGridTemplateColumn etc? Sugiro resolver isso com algo aproximadamente como a solução a seguir, que dá a DataGridColumn (e subclasses) a capacidade de converter um valor de célula em palavras-chave para uso com pesquisa / filtragem / correspondência.

public delegate void DataGridCellValueToKeywordsConverter(object cellValue, ICollection<string> outputKeywords);

public class DataGridColumn
{
    ...
    public DataGridCellValueToKeywordsConverter CellValueToKeywordsConverter { get; set; }

    /// <param name="cellValue">The input/source value of the cell, to be converted to keywords.</param>
    /// <param name="outputKeywords">A collection that the method will add the keywords to.  The method invokes ICollection.Add for each keyword.</param>
    public virtual void ConvertCellValueToKeywords(object cellValue, ICollection<string> outputKeywords)
    {
        // Subclasses can override this method.  The default behavior is to invoke the delegate to do the job.
        DataGridCellValueToKeywordsConverter d = this.CellValueToKeywordsConverter;
        if (!(d is null)) d(cellValue, outputKeywords);
    }
}

Aqui está um exemplo de como usar o método ConvertCellValueToKeywords :

void TestKeywords(DataGridColumn column)
{
    var keywords = new System.Collections.Generic.HashSet<string>();
    foreach (object cellValue in someCellValueList)
    {
        keywords.Clear();
        column.ConvertCellValueToKeywords(cellValue, keywords);
        CheckIfFilterTextMatchesAnyKeyword(keywords);
    }
}

Como alternativa, o valor da célula pode ser convertido em uma única string em vez de uma coleção de palavras-chave, mas a razão pela qual sugeri uma coleção de palavras-chave é que as palavras-chave possibilitam o uso de algoritmos de pesquisa que funcionam em alta velocidade, mesmo quando a quantidade de linhas é muito grande.

Cópia fácil do Excel
Agora não há como usar ctrl + v para copiar o conteúdo das células do Excel para o datagrid. Agora ele copia todo o conteúdo das células para uma célula na grade de dados.

Forneça um suporte adequado de vários itens selecionados, tornando SelectedItems como uma propriedade de dependência para permitir o uso de vinculação de dados ao gerenciar linhas selecionadas.

@verelpode Eu posso ver a seleção de células individuais sendo útil para qualquer tipo de aplicativo de planilha, não? Acho que importa mais em cenários de edição do que em cenários de exibição. Ao visualizar dados em um datagrid sem edição, concordo que não veria um uso para a seleção de células individuais e sempre terei a seleção completa de linhas.

@anawishnoff Eu acho que @ Laz3rPanth3r concordaria e algumas das questões aqui e aqui do kit de ferramentas que ser capaz de ingerir dados fácil e simplesmente no DataGrid é um recurso importante. Você deve ser capaz de inicializar a grade ligando-se a uma coleção de objetos ou expando objetos em uma lista. Se ele pode selecionar colunas de forma inteligente para números e strings e tipos de dados básicos, isso seria ótimo. O desenvolvedor sempre pode fazer mais trabalho depois de personalizar colunas individuais além disso.

Posso ver a seleção de células individuais sendo útil para qualquer tipo de aplicativo de planilha, não?

Em uma planilha, os cabeçalhos das colunas são nomeados com letras ascendentes do alfabeto, A, B, C, D, ... e o tipo de cada coluna é o mesmo, como se cada coluna usasse DataGridTextColumn e nenhuma outra coluna type é necessário e os nomes das colunas também não são realmente necessários porque são gerados automaticamente a partir do alfabeto.
Outra diferença entre DataGrid e uma planilha é que uma planilha não classifica as linhas quando você clica em qualquer um dos cabeçalhos das colunas.

Meu ponto é, apenas uma semelhança superficial (principalmente uma semelhança visual) existe entre DataGrid e uma planilha. O DataGrid realmente não funciona como uma planilha. A técnica de recuperação de dados de células do DataGrid também é pouco adequada para uma planilha.

Eu amo DataGrid, mas funcionaria mal se eu tentasse usá-lo para implementar uma planilha. Não acho que DataGrid seja a escolha certa para quem deseja implementar uma planilha.

O design existente do DataGrid se alinha muito melhor com um banco de dados SQL do que com uma planilha, e os desenvolvedores de banco de dados SQL gritariam alto se alguém tentasse alegar que um banco de dados é "apenas uma planilha".

@verelpode Suas contribuições são tão detalhadas e bem pensadas, muito obrigado por tudo isso! Quero falar sobre a ideia de vincular uma fonte de dados / propriedade ItemsSource do DataGrid, como você mencionou e @ michael-hawker também.

Atualmente DataGrid torna obrigatório para aplicativos definir DataGrid.ItemsSource, mas é impraticável criar um objeto de lista que contenha um milhão de itens. Portanto, gostaria que o DataGrid parasse de ser inteligente no departamento de recuperação de dados e, em vez disso, me permitisse realizar a recuperação de dados sozinho, sem usar DataGridBoundColumn.Binding e DataGrid.ItemsSource.

Isso é interessante e gostaria de examinar mais a fundo, pois estamos realmente interessados ​​em performance. Que tipo de situação / cenário de dados você está procurando, especificamente? Você gostaria de conectar o DataGrid diretamente a um resultado de consulta SQL, ou a um banco de dados, ou algo parecido?

@khoshroomahdi Por copiar e colar, você quer dizer que deseja copiar células do Excel em um DataGrid em um aplicativo em execução e preencher dessa forma? Esse é um caso de uso interessante, gostaria de ouvir mais.

@alexyak , você poderia expandir um pouco mais? A propriedade SelectedItems atualmente permite que você obtenha todos os itens selecionados em um DataGrid (por meio do modo de seleção estendida, não precisamente do modo de seleção múltipla). Vejo em alguns outros comentários aqui que a seleção em um DataGrid definitivamente precisa ser melhorada, mas quero entender melhor sua solicitação.

@anawishnoff sim exatamente.
Tenho alguns dados em células excelentes e desejo copiá-los no aplicativo em execução.

Para cenários não vinculados a dados, devemos observar como o controle WinForms DataGridView, que escrevi muitos anos atrás, suportava um modo virtual: https://docs.microsoft.com/en-us/dotnet/api/system. windows.forms.datagridview.virtualmode

Atualmente DataGrid torna obrigatório para aplicativos definir DataGrid.ItemsSource, mas é impraticável criar um objeto de lista que contenha um milhão de itens. Portanto, gostaria que o DataGrid parasse de ser inteligente no departamento de recuperação de dados e, em vez disso, me permitisse realizar a recuperação de dados sozinho, sem usar DataGridBoundColumn.Binding e DataGrid.ItemsSource.

Eu concordo que seria bom também. Estou pensando em algo como ListBox, onde você pode adicionar itens manualmente ou definir o ItemsSource. Dito isso, no passado, eu apenas gerava uma nova DataTable representando uma visão parcial do banco de dados completo para implementar a paginação (que é um bom caso de uso para isso). Uma visão dessa DataTable pode então ser definida como ItemsSource. Portanto, embora eu definitivamente ache que é bom ter, não parece obrigatório para alto desempenho.

Com relação a todos os comentários que transformam o controle em mais ou menos um subconjunto do Excel (r), acho que fora da caixa o DataGrid deve oferecer suporte à seleção de células e edição por célula. No entanto, coisas como copiar / colar entre aplicativos externos devem ser tratadas pelo desenvolvedor.

@alexyak Com relação à sua solicitação para tornar SelectedItems um DependencyProperty real e vinculável, seria ótimo restaurar o estado também (a maioria das minhas solicitações de recursos até agora são para restaurar o estado de exibição). Acho que esse é um problema de toda a estrutura, pois não é compatível com nenhum dos controles WinUI / UWP que eu conheça. Esta provavelmente deve ser uma solicitação de recurso geral. Veja a discussão aqui

@anawishnoff escreveu:

Suas contribuições são tão detalhadas e bem pensadas, muito obrigado por tudo isso!

Obrigado, fico feliz em saber que minhas contribuições são úteis para tornar o DataGrid ainda melhor :)

Que tipo de situação / cenário de dados você está procurando, especificamente? Você gostaria de conectar o DataGrid diretamente a um resultado de consulta SQL, ou a um banco de dados, ou algo parecido?

Isso ainda é muito inteligente. Esse comportamento inteligente evita que aplicativos diferentes executem a recuperação de dados de maneiras diferentes. Aplicativos diferentes têm circunstâncias muito diferentes, portanto, o "melhor" sistema de recuperação de dados é diferente para aplicativos diferentes - não existe um "melhor" único. Por exemplo, alguns aplicativos nunca exibem mais do que algumas centenas de linhas, enquanto alguns outros aplicativos podem funcionar com um milhão de linhas como @dotMorten mencionado, portanto, um tamanho de sapato não serve para todos.

Eu sugiro realmente emburrecê-lo a este nível:

  1. DataGrid decide que precisa exibir (ou usar de outra forma) o valor que existe na coluna 5 da linha 9001 no sistema de armazenamento de dados externo.
  2. O DataGrid notifica o aplicativo de que precisa do valor da coluna 5 da linha 9001.
  3. O aplicativo recupera o valor da coluna 5 da linha 9001. Isso pode envolver uma consulta SQL assíncrona, uma tarefa C # assíncrona ou qualquer outro sistema de dados. Idealmente, o DataGrid deve permitir que esta etapa seja assíncrona.
  4. O aplicativo notifica DataGrid que terminou de recuperar o valor para a coluna 5 da linha 9001. O aplicativo fornece esse valor para DataGrid.
  5. DataGrid usa o valor de qualquer maneira necessária, como exibindo o valor conforme mencionado na etapa 1.

@RBrid escreveu:

Para cenários não vinculados a dados, devemos olhar como o controle WinForms DataGridView, que escrevi muitos anos atrás, suportava um modo virtual:

Sim Sim Sim! Nunca usei WinForms DataGridView, mas acabei de ler a documentação agora e acredito que você acertou em cheio. A página da web que você vinculou diz:
_ "O modo virtual é projetado para uso com armazenamentos de dados muito grandes." _

Vejo que o WinForms DataGridViewCellValueEventArgs contém estas propriedades:

public int RowIndex { get; }      // DataGrid sets RowIndex.
public int ColumnIndex { get; }   // DataGrid sets ColumnIndex.
public object Value { get; set; } // The app sets Value.

Isso é excelente, exceto que idealmente deve ser atualizado para suportar as palavras-chave modernas C # async e await , ou o equivalente UWP ( IAsyncOperation<TResult> ), ou melhor, qualquer tipo de atraso entre o DataGrid que solicita o valor da célula e o aplicativo que entrega o valor da célula ao DataGrid. Portanto, para atualizá-lo para suportar assíncrono, faça o seguinte:

  1. Mantenha o evento CellValueNeeded .
  2. Remova a propriedade DataGridViewCellValueEventArgs.Value .
  3. Crie um método no DataGrid denominado algo como SupplyCellValue que o aplicativo irá invocar, em vez de ser solicitado a definir imediatamente / de forma síncrona a propriedade DataGridViewCellValueEventArgs.Value .

O método SupplyCellValue pode ser definido assim:

class DataGrid
{
    public void SupplyCellValue(int rowIndex, int columnIndex, object value);
    // Alternatively:
    public void SupplyCellValue(int rowIndex, DataGridColumn column, object value);
}

Assim, em tempo de execução, o procedimento é:

  1. DataGrid decide que precisa exibir (ou usar de outra forma) o valor que existe na coluna 5 da linha 9001 no sistema de armazenamento de dados externo.
  2. O DataGrid aciona o evento CellValueNeeded e define DataGridViewCellValueEventArgs.RowIndex como 9001 e DataGridViewCellValueEventArgs.ColumnIndex como 5.
  3. O manipulador de eventos (o aplicativo) começa a executar uma tarefa assíncrona que recuperará o valor da coluna 5 da linha 9001.
  4. Quando a tarefa assíncrona termina a execução, ou seja, quando o aplicativo recupera o valor, o aplicativo invoca o método DataGrid.SupplyCellValue .

Esta técnica simplificada é mais poderosa e flexível do que a técnica automatizada inteligente de DataGridBoundColumn.Binding e DataGrid.ItemsSource .

@alexyak , você poderia expandir um pouco mais? A propriedade SelectedItems atualmente permite que você obtenha todos os itens selecionados em um DataGrid (por meio do modo de seleção estendida, não precisamente do modo de seleção múltipla). Vejo em alguns outros comentários aqui que a seleção em um DataGrid definitivamente precisa ser melhorada, mas quero entender melhor sua solicitação.

Precisamos de uma ligação de dados bidirecional adequada para viewmodels para gerenciar várias seleções

@verelpode , modelamos o modelo WinForms DataGridView após os controles Win32 ComCtl32 ainda mais antigos. Em particular, estou pensando em como o controle de exibição de lista usou a mensagem LVN_GETDISPINFO no modo virtual (consulte https://docs.microsoft.com/en-us/windows/win32/controls/list-view-controls-overview # Handling-virtual-list-view-control-notification-codes e https://docs.microsoft.com/en-us/windows/win32/controls/lvn-getdispinfo). Coisas antigas de '90.

De qualquer forma, acredito que a forma como o aspecto de recuperação de dados assíncronos deve ser tratado é por meio de 'eventos adiados'.
Os controles WinUI já usam eventos adiados duas vezes:

runtimeclass RefreshRequestedEventArgs
{
    Windows.Foundation.Deferral GetDeferral();
}

runtimeclass TeachingTipClosingEventArgs
{
    TeachingTipCloseReason Reason{ get; };
    Boolean Cancel;
    Windows.Foundation.Deferral GetDeferral();
}

É o padrão que o evento CellValueNeeded do novo DataGrid gostaria de adotar. Ele permite que o manipulador de eventos forneça dados de forma assíncrona e diga ao controle quando terminar de fazer isso. Consulte https://docs.microsoft.com/en-us/uwp/api/windows.foundation.deferral.

@RBrid
Boa observação sobre GetDeferral() ser o novo padrão padrão. Neste caso particular de CellValueNeeded , parece muito mais difícil usar Deferral que em outros casos / eventos. Corrija-me se estiver errado, mas acho que o problema de usar GetDeferral() neste caso particular é que GetDeferral() cria um novo objeto toda vez que é invocado, e isso levaria a um erro excessivo grande quantidade de criação e limpeza de objetos sendo repetida para cada célula de cada linha de um número potencialmente grande de linhas. Eu não vi o código-fonte de várias implementações de GetDeferral() portanto, posso estar enganado sobre isso.

Em outras palavras, a menos que Deferral apoie a reciclagem ou de outra forma tenha uma maneira de tornar GetDeferral() muito mais eficiente, então ainda é muito inteligente. Minha proposta simplificada com o método SupplyCellValue evita incorrer na sobrecarga de criar, completar e descartar uma nova instância Deferral para cada célula de cada linha aplicável.

  1. GetDeferral()
  2. Deferral.Complete
  3. Deferral.Dispose
  4. Repita as etapas acima várias vezes.

A tarefa de recuperar um valor de célula não é a única tarefa de gerenciamento de dados que pode ser terceirizada para o aplicativo. A classificação também pode ser terceirizada. Portanto, pode valer a pena pensar em uma interface em vez de um único evento CellValueNeeded . Um aplicativo daria ao DataGrid um módulo de gerenciamento de dados na forma de um objeto que implementa uma determinada interface. O DataGrid invocaria essa interface para recuperar os valores das células, mas também potencialmente outras tarefas, como classificação.

Para suportar os milhões de linhas que @dotMorten mencionou, CellValueNeeded sozinho não resolveria o outro problema que ocorre quando o usuário clica no cabeçalho de uma coluna e o DataGrid tenta classificar um milhão de linhas. Assim, a recuperação E a classificação de células podem ser terceirizadas para o aplicativo por meio do módulo / interface mencionado anteriormente.

Se o aplicativo não fornecer nenhum módulo / objeto de gerenciamento de dados para o DataGrid, o ideal é que o DataGrid use um módulo de gerenciamento de dados padrão. Assim, todo o código de vinculação de dados existente no DataGrid seria movido para fora do DataGrid e para uma nova classe separada - a classe que implementa o módulo de gerenciamento de dados padrão trabalhando com DataGridBoundColumn.Binding etc.

ou seja, quando a classificação também é terceirizada para o aplicativo ou seu módulo de gerenciamento de dados, isso abre a porta para várias soluções que suportam um milhão de linhas, como escrever um módulo de gerenciamento de dados que instrui o servidor SQL a realizar a classificação, em vez de tentar- e não fazer a classificação de um milhão de linhas dentro do DataGrid em menos de 10 ou 20 horas após o usuário clicar no cabeçalho da coluna para iniciar a classificação.

@verelpode , sim, é uma preocupação válida. Eu esperaria que o DataGrid possuísse um pool de objetos Windows.Foundation.Deferral recicláveis. Precisamos confirmar a viabilidade e o desempenho com certeza.

Tendo assumido uma dependência do DataGrid do Windows Community Toolkit que tem Row Details como um recurso (embora com um bug de desempenho sério, mas com uma solução alternativa), nós realmente gostaríamos que este novo datagrid tivesse isso como um recurso também - com a mesma opção para ter vários detalhes de linha simultaneamente. Usando-o para um cenário de dados de streaming de servidor para cliente.

Em relação a um milhão de linhas versus uma GUI de paginação , @robloo escreveu:

Eu concordo que [suportar um milhão de linhas] também seria bom. .... Dito isso, no passado eu apenas gerava uma nova DataTable representando uma visão parcial do banco de dados completo para implementar a paginação (que é um bom caso de uso para isso). Uma visão dessa DataTable pode então ser definida como ItemsSource. Portanto, embora eu definitivamente ache que é bom ter, não parece obrigatório para alto desempenho.

A paginação é uma técnica útil e vale a pena mencionar, mas tem desvantagens substanciais: ela torna o recurso de classificação do DataGrid praticamente inútil. Da mesma forma, para um recurso de filtragem na próxima versão do DataGrid. A paginação torna a classificação e a filtragem inúteis ou, pelo menos, muito menos úteis.

Por exemplo, imagine que 2 ou 3 colunas são colunas de data e o usuário deseja visualizar as linhas que possuem a data mais recente (ou mais antiga) na segunda coluna de data. Assim, o usuário clica no segundo cabeçalho da coluna de data para classificar o DataGrid por essa coluna e também clica para alterar a direção de classificação de decrescente para crescente ou vice-versa. Isso funciona muito bem se nenhuma paginação estiver em uso ou se a quantidade total de linhas for pequena o suficiente para não exceder uma única página, mas quebra se houver várias páginas.

O usuário precisa encontrar a data mais recente (ou mais antiga) em todas as linhas, mas uma GUI DataGrid paginada mostra apenas a data mais recente (ou mais antiga) na página atual, não em todas as linhas, portanto, a paginação torna a classificação (e filtragem) praticamente inútil.

Isso levanta a questão de quais linhas chegam a cada página. A resposta é que cada página normalmente contém um subconjunto praticamente aleatório de linhas, quando as páginas / linhas são obtidas por meio de uma consulta SQL SELECT que não usa ORDER BY . (Quero dizer aleatório do ponto de vista do usuário, não verdadeiramente aleatório.)

Pseudo-aleatório não ajuda os usuários finais. Para eliminar essa aleatoriedade problemática, poderíamos pensar em usar SQL ORDER BY (junto com a palavra-chave ASC ou DESC para controlar a direção da classificação) e, em seguida, sim, as páginas são não mais aleatório, mas ainda está quebrado porque este uso de ORDER BY sempre classifica pela mesma coluna e mesma direção de classificação, o que significa que a ordem de classificação é frequentemente diferente da ordem de classificação escolhida pelo usuário final clicando em uma coluna cabeçalho no DataGrid.

Para corrigir isso, você precisaria usar uma consulta SQL diferente cada vez que o usuário clicar em um cabeçalho de coluna diferente. O SQL ORDER BY ... ASC/DESC precisaria ser mantido igual a qualquer ordem de classificação escolhida pelo usuário final do DataGrid. DataGrid não suporta isso atualmente.

Uma solução sugerida está em minha mensagem anterior : Sugeri que o DataGrid deve permitir que a classificação seja terceirizada para o aplicativo (ou para um "módulo de gerenciamento de dados"). Essa ideia tornaria possível para o aplicativo (ou "módulo de gerenciamento de dados") alterar o SQL ORDER BY ... ASC/DESC sempre que o usuário final alterar a ordem de classificação do DataGrid clicando nos cabeçalhos das colunas etc.

Também pode valer a pena dar ao evento preexistente DataGrid.Sorting uma propriedade configurável nos argumentos do evento que permite aos aplicativos (o manipulador de eventos) cancelar a classificação e assumir o controle. Idealmente, os argumentos do evento também especificariam se a mudança na ordem de classificação foi solicitada de forma programática ou solicitada pelo usuário final clicando nos cabeçalhos das colunas etc. Nesse caso, também pode ajudar renomear o evento DataGrid.Sorting para algo menos ambíguo porque atualmente a intenção e o propósito do evento Sorting não são claros. Veja também o evento proposto

Tendo assumido uma dependência do Windows Community Toolkit DataGrid que possui Row
Detalhes como um recurso (embora com um bug de desempenho sério, mas com uma solução alternativa), nós
realmente gosto deste novo datagrid para ter isso como um recurso também - com a mesma opção de ter
vários detalhes de linha simultaneamente. Usando-o para um cenário de dados de streaming de servidor para cliente.

Link para o problema de desempenho de Detalhes de linha: https://github.com/windows-toolkit/WindowsCommunityToolkit/issues/2842
Repro: https://github.com/observito/DataGridRowDetailsPerfTest

Um bom ponto de partida é olhar para seu parceiro Telerik com seu RadDataGrid (UWP Open Source). Com um dos meus clientes, usei-o e realmente funciona bem. É hiper rápido e versátil. A única coisa que é difícil é o seu código, não há como modificar nada do seu motor sem uma boa compreensão da arquitetura.

Eu esperaria que o novo DataGrid tivesse o mesmo desempenho do Telerik.

Os recursos da grade de sincronização são excelentes, mas não são compatíveis com o mvvm. Então você pode fazer melhor.

Ei de novo tudo! Vamos continuar essa conversa. O que você acha da documentação do DataGrid que existe atualmente?

Aqui está um link para a página de documentação principal com links para todas as outras páginas relevantes.

Se criarmos um novo DataGrid, queremos ter certeza de que a documentação que o acompanha será de alto nível, fácil de entender e abordará todos os problemas e cenários que são importantes para nossos desenvolvedores.

_Quais são alguns tópicos que você gostaria que tivéssemos? Quais são alguns tópicos que podem ser esclarecidos? _

Ei de novo tudo! Vamos continuar essa conversa. O que você acha da documentação do DataGrid que existe atualmente?

Aqui está um link para a página de documentação principal com links para todas as outras páginas relevantes.

Se criarmos um novo DataGrid, queremos ter certeza de que a documentação que o acompanha será de alto nível, fácil de entender e abordará todos os problemas e cenários que são importantes para nossos desenvolvedores.

_Quais são alguns tópicos que você gostaria que tivéssemos? Quais são alguns tópicos que podem ser esclarecidos? _

Imagens mostrando configurações típicas de DataGrid, junto com o xaml e o código para criá-las, seriam úteis.

Imagens mostrando configurações típicas de DataGrid, junto com o xaml e o código para criá-las, seriam úteis.

@mdtauk Há alguma configuração específica do DataGrid que você considera "típica" ou casos de uso em que considera o DataGrid como a melhor escolha?

Imagens mostrando configurações típicas de DataGrid, junto com o xaml e o código para criá-las, seriam úteis.

@mdtauk Há alguma configuração específica do DataGrid que você considera "típica" ou casos de uso em que considera o DataGrid como a melhor escolha?

Acho que para o período de tempo do WinUI 3.0, mostrando cenários comuns de exibição de ícones / grade de dados WPF e Win32. Bem como o que a Microsoft considera designs de IU de DataGrid Fluentes / Modernos.

Isso se a ideia por trás do controle é encorajar a mudança de interfaces de usuário antigas para WinUI 3

@anawishnoff Acho que algumas das perguntas que tivemos com o kit de ferramentas em termos de coisas que as pessoas estavam procurando por documentação sobre onde mais desses cenários também:

  • Tematização / Re-modelagem / Alinhamento
  • Data Binding (em geral e em XAML)
  • Evento / Manuseio de Seleção / Revestimento
  • Editando comportamentos (especialmente editar no clique)
  • Multi-paging (que deve combinar bem com # 60 e # 268)

    • Carregando coordenação de animação enquanto os dados são carregados

  • Copiar / colar / formatação
  • Tipos de dados de coluna diferentes (e personalizados) (por exemplo, enums)
  • Menus de Contexto
  • Acessibilidade

Percebi que o Toolkit DataGrid existente requer um IEnumerable para sua propriedade ItemsSource. Embora pareça uma decisão lógica, torna impossível definir o objeto retornado por Windows.Storage.BulkAccess.FileInformationFactory.GetVirtualizedItemsVector () como esta propriedade. (A menos que haja uma maneira de converter o objeto retornado) Além disso, outros controles, como ListView e GridView, oferecem suporte à configuração de sua propriedade ItemsSource para um valor do tipo de objeto. Não tenho certeza, mas o suporte a isso provavelmente permitiria uma interface de usuário mais responsiva durante as operações de armazenamento.

@mdtauk Há alguma configuração específica do DataGrid que você considera "típica" ou casos de uso em que considera o DataGrid como a melhor escolha?

Acho que para o período de tempo do WinUI 3.0, mostrando cenários comuns de exibição de ícones / grade de dados WPF e Win32. Bem como o que a Microsoft considera designs de IU de DataGrid Fluentes / Modernos.

Isso se a ideia por trás do controle é encorajar a mudança de interfaces de usuário antigas para WinUI 3

Exemplo Win32 (File Explorer)
image

Exemplo WPF
image

Exemplo do Fabric Web
image

Exemplo UWP
image

@mdtauk Obrigado por essas imagens! Definitivamente, acho importante destacar os elementos-chave que funcionaram nas versões anteriores do controle e documentar como eles podem ser alcançados com o novo controle.

@Michael-hawker Incrível. Já estou vendo alguns tópicos que foram levantados várias vezes neste tópico, então esses são definitivamente um bom lugar para começar.

@ duke7553 Não estou 100% certo sobre uma solução para isso, ou se seria sensato suportar um tipo de objeto. Talvez @RBrid possa

@anawishnoff & @ duke7553 , gostaria de construir o novo controle DataGrid sobre o novo controle WinUI ItemsRepeater. E esse controle expõe seu ItemsSource como um objeto:
Object ItemsSource { get; set; };

Espero que suporte CellDecorationStyleSelector como em Telerik.

@anawishnoff

estamos interessados ​​em transformá-lo em um controle WinUI nativo

hmmmm quando você diz "graduação", isso incluiria fazer o downgrade para C ++? Atualmente o DataGrid do WinUI é escrito em C #. Espero que "graduar" não signifique "rebaixar". É importante ressaltar que o WinUI precisa chegar a um ponto em que a equipe do WinUI possa dizer que o WinUI é melhor do que o WPF em todos os aspectos importantes, mas esse objetivo está terrivelmente atrasado. Essa meta ficará ainda mais atrasada se tempo / recursos forem desperdiçados em downgrades desnecessários de código, como DataGrid de C # para C ++.

Embora tenha existido originalmente um motivo para escrever WinRT / UWP / WinUI em C ++, infelizmente esse motivo não se concretizou, e o Google / Android tomou a maior parte do mercado de smartphones, portanto, o motivo original para usar C ++ não é mais aplicável (facilmente dito em retrospectiva, mas não tão fácil de dizer antes). Se WinUI fosse escrito em C # desde o início, então a meta melhor que o WPF teria sido alcançada 3 anos atrás, mas agora são 8 anos e ainda não foram alcançados, e ninguém é capaz de dizer com precisão quando a meta será alcançada. Esperançosamente, o objetivo melhor que o WPF e os objetivos de "graduação" do WinUI DataGrid não serão atrasados ​​por uma conversão desnecessária para uma linguagem de programação mais antiga e menos produtiva.

Sou tendencioso a favor do C ++ porque comecei a programar em C ++ antes mesmo de o C # existir, e as pessoas preferem ficar com o que aprenderam originalmente e lembram-se com carinho dos _ "bons velhos tempos" _. Apesar de meu preconceito em favor de C ++, parei de escrever C ++ e acho que DataGrid não deve ser rebaixado para C ++ e atrasado. Deixe como C # e concentre-se em coisas mais importantes, como fazer as várias melhorias sugeridas por pessoas nesta edição e alcançar a meta melhor que o WPF antes de atingir 1 década.

Eu amo muitos aspectos do WinUI e agradeço as muitas melhorias inteligentes nele, e escrevo o código do aplicativo para WinUI, mas você quer saber a verdade? A verdade é que, infelizmente, ainda não lancei nenhum aplicativo WinUI para os usuários. O software lançado para os usuários é escrito com WPF, e os usuários não se importam porque o software funciona bem e inclui modernizações de GUI. Embora eu tenha escrito um monte de código de aplicativo para WinUI, é tudo preparação, planejamento, teste, espera, não está realmente em uso pelos usuários. Espero que no próximo ano o primeiro componente WinUI seja lançado para os usuários, mas vou apreciar essa mudança muito mais do que eles. Os usuários dificilmente perceberão a mudança, se tudo correr conforme o planejado.

Do ponto de vista da Microsoft, WinRT / UWP é um software com qualidade de lançamento, publicado para usuários desde o ano de 2012, mas do meu ponto de vista, UWP ainda é um grande experimento. Para mim, UWP (incluindo WinUI) é uma grande versão de teste beta com a qual tenho

Durante os primeiros anos de UWP, todos os anos eu pensava: _ "errr ... Vou esperar até o próximo ano. Ainda há muitas coisas no WPF que estão faltando na UWP. Com certeza no próximo ano será melhor." _
Então, o próximo ano veio e eu repeti o mesmo pensamento. Então, o próximo ano veio e eu repeti o mesmo pensamento. Espero que este seja o último ano em que digo isso, ou pelo menos essa é minha intenção.

WinUI não pode permitir mais atrasos. Deixe o DataGrid do WinUI como código C #. Comece a escrever mais código WinUI em C # para aumentar a produtividade. Já se passaram 8 anos e o Android conquistou grande participação no mercado. Essa é uma situação grave.

A propósito, eu estava sendo legal / generoso quando disse que o UWP ainda é uma versão beta, porque tecnicamente o UWP corresponde à definição de uma versão alfa, não beta. Para ser uma verdadeira versão beta, ela precisa ter o recurso completo, mas o UWP ainda não atingiu o status de recurso completo, portanto, o UWP ainda é alfa. Por exemplo, o artigo "Ciclo de vida de lançamento de software" da Wikipedia diz:

"A fase beta geralmente começa quando os recursos do software estão completos, mas provavelmente contém uma série de bugs conhecidos ou desconhecidos."
"O software Alpha pode não conter todos os recursos planejados para a versão final."

A Wikipedia define "recurso completo" da seguinte forma:

"Uma versão completa de recursos de um pedaço de software tem todos os seus recursos planejados ou primários implementados, mas ainda não é final devido a bugs, desempenho ou problemas de estabilidade. Isso ocorre no final do teste alfa de desenvolvimento."

Não seria razoável descrever o UWP como completo de recursos, porque se for realmente completo, então o UWP deve ter todos os recursos do Windows '95 e mais, mas não tem - o UWP ainda não excede o Windows 95 em todas as áreas . O Windows 95 foi lançado há 25 anos. Quando o UWP / WinRT foi lançado há 7 a 8 anos, a Microsoft sofreu uma perda de US $ 900 milhões e uma falta paralisante de aplicativos na Windows Store. Era uma versão alfa rotulada como uma versão de lançamento, portanto, os desenvolvedores de aplicativos esperaram e assistiram. Hoje, quase 8 anos depois, ainda é uma versão alfa e muito atrasada, e ainda estou esperando e assistindo e esperando.

Seria muito benéfico para a Microsoft e os desenvolvedores se a Microsoft tomasse uma decisão séria / se comprometesse a priorizar a produção de uma verdadeira versão beta do UWP, a ser rapidamente seguida por uma verdadeira versão Release Candidate. Isso seria altamente recomendado e um curso de ação muito sensato. Seria excelente para todos.

UWP ainda está alfa / incompleto por vários motivos, por exemplo: 25 anos atrás, era fácil usar a função "MoveFile" no Windows 95 para mover um arquivo ou pasta (embora a função fosse chamada de "MoveFile", ela suportava ambos os arquivos e pastas). O UWP pode mover pastas? Não, ainda não. Obviamente, a capacidade de mover pastas é um dos recursos essenciais básicos fundamentais, mas a UWP ainda não possui esse recurso essencial e outros, portanto, não seria razoável descrever a UWP como completa, pois a UWP ainda não atingiu o status beta, apesar de sendo lançado 7-8 anos atrás. A Microsoft precisa priorizar uma verdadeira versão beta do UWP.

Um repositório GitHub público para rastrear problemas de UWP (além de problemas de interface do usuário) ainda não existe, pelo que eu sei (ou se houver um repositório UWP, não consegui encontrá-lo). Novamente, isso corresponde à definição de uma versão alfa porque um repositório de rastreamento de problemas público é frequentemente indesejado durante um estágio alfa. Se fosse um verdadeiro beta ou uma versão de lançamento, um repositório público de rastreamento de problemas já teria sido aberto e o UWP incluiria todos os recursos do Windows 95 e Windows 7 e muito mais.

Como essa situação afeta o DataGrid ? Considerando que uma versão beta com recursos completos de UWP está terrivelmente atrasada e considerando a gravidade desta situação e a perda de bilhões de dólares que a Microsoft sofreu como resultado, não seria justificável e razoável perder ainda mais tempo convertendo WinUI DataGrid em código não gerenciado e em uma linguagem de programação mais antiga. A Microsoft disse repetidamente que uma grande vantagem do C # e do "código gerenciado" é o aumento da produtividade, e posso dizer que as afirmações da Microsoft sobre "código gerenciado" foram definitivamente verdadeiras em minhas experiências com C ++ e C #. O UWP teria atingido o verdadeiro status beta há vários anos se tivesse sido escrito principalmente com o código gerenciado a partir da versão 1.0. Portanto, espero que a situação não piore ainda mais com a realização de ainda mais desses downgrades desnecessários de código gerenciado para código não gerenciado.

Para efeito de comparação, a maior parte do WPF foi concluída com êxito nos 4 anos de 2006 a 2010. O WPF é principalmente código gerenciado, ao contrário do UWP. UWP é um código não gerenciado e após 8 anos de desenvolvimento, o Windows 95 ainda bate UWP em algumas áreas, então a Microsoft estava claramente correta quando afirmou que o código gerenciado aumenta a produtividade. Este problema precisa ser resolvido o mais rápido possível. O WinUI deveria ter sido muito mais fácil / rápido de criar do que o WPF porque ambos os projetos têm o mesmo proprietário (Microsoft), portanto, o WinUI tem permissão para copiar o código do WPF livremente. Portanto, o WinUI deve ter exigido cerca de metade do tempo de desenvolvimento do WPF. Na verdade, o WinUI nunca deveria ter sido iniciado, em vez disso, a Microsoft deveria ter desenvolvido os recursos do WinUI em novas versões do WPF - o WinUI deveria ser o WPF 5.0. Então, a situação estava uma grande bagunça e seria muito benéfico para a Microsoft priorizar a limpeza restante dessa bagunça e parar de fazer coisas que tornam o erro de bilhões de dólares ainda pior do que já era (e ainda é quando você olha na situação atual de participação no mercado de smartphones).

Isso significa que, para evitar ainda mais perdas, a Microsoft se beneficiaria ao lembrar o que a Microsoft já disse / sabia no passado:

  • O código gerenciado aumenta a produtividade, de acordo com as próprias afirmações da Microsoft. Quando você olha os 8 anos do UWP em comparação com os 4 anos do WPF, a conclusão deve ser que a Microsoft estava correta com relação aos benefícios do código gerenciado.
  • Linguagens de script são para script e linguagens de programação são para programação. JavaScript e PowerShell são bons para os fins pretendidos (scripts), mas são obviamente escolhas inadequadas para a programação de aplicativos.
  • Para ter sucesso, a Microsoft deve progredir de alfa para beta e lançar, e isso só terá sucesso se for uma versão de lançamento real, não um alfa incompleto rotulado como "lançamento". Portanto, a Microsoft Store ficou praticamente vazia por um tempo excessivamente longo.
  • Engenheiros de software e outros funcionários trabalham melhor quando trabalham em troca de uma remuneração razoável e um número razoável de horas de trabalho e um ambiente de trabalho saudável. Obviamente, a perda de bilhões de dólares da Microsoft nunca será revertida pelo uso de fanáticos / fanáticos não pagos e seus chamados "empregos diurnos" e "empregos noturnos" e suas condições de trabalho insustentáveis ​​/ insalubres.
  • O enorme ganho de market share do Android não foi graças a fanáticos não pagos. Se fanáticos não pagos fossem a razão da vitória, o Linux não teria falhado. A explicação é muito mais simples: o preço dos tablets e smartphones Android é MUITO inferior ao dos tablets e smartphones Windows. Obviamente, os usuários finais não se importam com religiões / ideologias de "código aberto" (os usuários nem mesmo sabem o que é isso), mas simplesmente amam os preços baratos dos dispositivos Android.
  • Win16 é extremamente obsoleto. É tecnologia de 20-30 anos atrás, dos primeiros dias de programação do "Velho Oeste". Portanto, pare de escrever novos códigos baseados no Win16. Chamá-lo de "Win32" não muda realmente o fato de que ainda é fundamentalmente Win16. Win32 é a mesma coisa que Win16, exceto com os ponteiros expandidos em tamanho de 16 bits para 32 bits. Muitos grupos na Microsoft continuam a escrever novos códigos baseados no Win16 / 32. Isso é muito ineficiente e um grande desperdício de recursos.

@anawishnoff

estamos interessados ​​em transformá-lo em um controle WinUI nativo

Veja também o artigo da Wikipedia "Custo irrecuperável" :

O efeito do custo irrecuperável (ou efeito Concorde) é o fato de que o comportamento geralmente segue a falácia do custo irrecuperável; as pessoas demonstram "uma tendência maior de continuar um empreendimento depois que um investimento em dinheiro, esforço ou tempo é feito". Esse comportamento pode ser descrito como "jogar dinheiro bom atrás do ruim" e recusar-se a sucumbir a ele pode ser descrito como "cortar as próprias perdas".

E, da mesma forma, "Tendência de continuação do plano" :

Tendência de continuação do plano, get-there-itis ou press-on-itis é uma tendência imprudente de persistir com um plano que está falhando. Este é um perigo perigoso para os capitães de navios ou pilotos de aeronaves que podem seguir um curso planejado mesmo quando está levando a um desastre fatal e, em vez disso, devem abortar. ..... Projetos freqüentemente sofrem estouros de custos e atrasos devido à falácia de planejamento e fatores relacionados, incluindo otimismo excessivo, uma falta de vontade de admitir o fracasso, pensamento de grupo e aversão à perda de custos irrecuperáveis.

O WinRT / UWP fez com que a Microsoft sofresse uma perda de $ 900 milhões no primeiro ou segundo ano e uma app store vazia por muito tempo. O WinRT / UWP foi uma falha catastrófica, portanto deveria ter sido abortado no segundo ano, mas foi continuado por causa do "viés de continuação do plano" e da aversão à perda de custos irrecuperáveis. Esse material é ensinado em cursos de administração. A continuação do plano acabou apagando ou revertendo a falha catastrófica do WinRT / UWP? Não, ainda é uma falha catastrófica hoje, se você olhar em termos de participação no mercado de smartphones. Essas descrições na Wikipedia descrevem com precisão a situação da UWP.

Agora, todos nós temos que concordar que no momento atual, 7 a 8 anos após o lançamento do WinRT / UWP, agora é tarde demais para cancelar o UWP, mas isso significa que estamos novamente sendo vítimas do "viés de continuação do plano "e aversão à perda de custos irrecuperáveis.

Então, o que pode ser feito razoavelmente para resgatar a situação? Não podemos resgatar a situação cancelando o UWP, embora ele definitivamente devesse ter sido cancelado anos atrás. O que podemos fazer é o seguinte: Aceitar o dano gigantesco que foi feito pelo WinRT, mas não causar mais nenhum dano, e fazer alterações nos procedimentos / políticas do projeto. Isso significa que pare de repetir / continuar os mesmos erros catastróficos do WinRT. Por exemplo, pare de fazer o downgrade de tais grandes quantidades de código gerenciado para código "nativo" antigo e improdutivo não gerenciado. O atraso em atingir o verdadeiro status beta já é muito grande - por que tornar o atraso ainda pior?

O erro "Plan continuation bias" / sunk cost continua se o DataGrid for rebaixado para código "nativo" não gerenciado. Quando um erro catastrófico como WinRT / UWP é cometido, fica muito pior quando esse mesmo erro é repetido várias vezes. Para limitar o dano, é necessário parar de repetir o mesmo erro. É realmente hora de aprender com a falha catastrófica do WinRT e começar a aplicar bandagens para interromper a perda de sangue em curso.

Converter DataGrid em código não gerenciado é o mesmo que ir a uma biblioteca e pegar emprestados todos os melhores livros de gerenciamento de projetos dos melhores autores com o maior conhecimento / experiência e, em seguida, jogar todos esses excelentes livros de gerenciamento em uma fogueira e vê-los queimar.

@verelpode Estou curioso para

@dotMorten - a razão pela qual escrevi detalhes extras nessas mensagens é porque, se eu não explicar o problema adequadamente, as pessoas não vão entender. Mas, infelizmente, agora vejo que o detalhe extra falhou e ainda não foi entendido de qualquer maneira. Isso é muito frustrante. Esta é a razão pela qual muitas pessoas nem se importam em escrever nenhum feedback, porque acreditam que é inútil tentar explicar esses tipos de questões às pessoas, e mesmo que a mensagem seja compreendida com sucesso, então é da natureza humana atirar no pessoa que dá as más notícias, então é melhor não dizer nada, ou apenas sorrir "educadamente" enquanto pensa o contrário.

já que está ficando completamente livre disso com a v3.

Esta desvinculação v3 não impede a repetição dos mesmos erros. O "viés de continuação do plano" ainda existe.

Vá para a página inicial da Microsoft:
https://www.microsoft.com/en-us/
Agora role para baixo na página inicial até ver o Windows Phone. Oh! Olhe para isso! Chegamos ao fim da página inicial e o Windows Phone não é mencionado EM QUALQUER LUGAR na página inicial da Microsoft! O que isto significa? Significa, acorde. Isso significa que o UWP foi uma falha catastrófica, como eu disse. Isso significa que é importante parar de repetir os mesmos erros que levaram ao fracasso do UWP. Significa mudar o plano para resgatar e se recuperar do desastre.
Seria um erro de gerenciamento se o WinUI e o DataGrid continuassem a repetir os mesmos erros da falha do UWP.

"Em maio de 2016, a Microsoft destruiu seus negócios móveis, .... Em 2017, o executivo da Microsoft Joe Belfiore revelou que a Microsoft havia encerrado o desenvolvimento de novos telefones Windows e novos recursos para o Windows 10 Mobile, citando as perdas na participação de mercado e a falta de desenvolvimento de aplicativos. "
- https://en.wikipedia.org/wiki/Microsoft_Mobile

Ana lista 5 pontos para fornecer feedback sobre o Wrt DataGrid. Sobre quais desses pontos você está comentando? Acho que é a parte que não entendi do que você está escrevendo. O UWP não atende às necessidades de todos, mas o WinUI3 não exige o uso do modelo de aplicativo UWP e você parece ser mais contra o UWP? Então você deve ficar bem lá.

Você mencionou que o DataGrid não deve continuar a cometer os mesmos erros que cometeu. Então, quais são esses erros especificamente escritos no DataGrid existente e como você sugere que eles devem ser corrigidos? (além de você não querer implementá-lo em C ++ por algum motivo)

@dotMorten

Ana lista 5 pontos para fornecer feedback sobre o Wrt DataGrid. Sobre quais desses pontos você está comentando?

A parte em que citei Ana no início da minha mensagem. Estou comentando a parte da mensagem da Ana que citei no início da minha mensagem.

WinUI3 não dita o uso do modelo de aplicativo UWP

Isso não está relacionado à minha mensagem. O fato do WinUI 3 ser desvinculado e estar disponível através do pacote nuget é irrelevante para a questão de saber se o WinUI 3 continua os mesmos erros de gerenciamento que levaram ao fracasso do UWP e do Windows Phone e à perda de bilhões de dólares da Microsoft.

como você sugere que eles devem ser corrigidos?

Os 6 pontos no final da minha mensagem anterior . O segundo ponto (script) está relacionado ao WinUI e UWP em geral, mas não ao DataGrid. O primeiro ponto é o mais importante se você estiver perguntando especificamente sobre DataGrid.
Eu também escrevi: pare de fazer o downgrade de tais grandes quantidades de código gerenciado para código "nativo" antigo e improdutivo não gerenciado. O atraso em atingir o verdadeiro status beta já é muito grande - por que tornar o atraso ainda pior?

@anawishnoff escreveu:

estamos interessados ​​em transformá-lo em um controle WinUI nativo

"graduá-lo para um controle WinUI nativo" constitui praticamente uma continuação / repetição de alguns dos mesmos erros que levaram às "perdas de participação no mercado e falta de desenvolvimento de aplicativos" mencionados na Wikipedia:

"Em maio de 2016, a Microsoft destruiu seus negócios móveis, .... Em 2017, o executivo da Microsoft Joe Belfiore revelou que a Microsoft havia encerrado o desenvolvimento de novos telefones Windows e novos recursos para o Windows 10 Mobile, citando as perdas na participação de mercado e a falta de desenvolvimento de aplicativos. "
- https://en.wikipedia.org/wiki/Microsoft_Mobile

Por que o DataGrid deve continuar no mesmo caminho que destruiu os negócios móveis da Microsoft?

@verelpode

O WinUI 3 continua os mesmos erros de gerenciamento que levaram ao fracasso do UWP e do Windows Phone e ao prejuízo multibilionário da Microsoft.

Não trabalho para a Microsoft, mas estou curioso para saber por que você diz que o WinUI está cometendo erros de gerenciamento.
Pelo que vejo, o próprio fato de que o WinUI está sendo de código aberto e todos contribuem para as conversas e decisões está ajudando a definir o que é o WinUI e deve evitar que erros aconteçam.
Você mencionou que o DataGrid está continuando no mesmo caminho que o móvel, embora em nenhum lugar do campo eu tenha mencionado o dispositivo móvel. Talvez você possa enviar feedback diretamente sobre o que está sendo discutido neste assunto.
Se você acha que há etapas de gerenciamento incorreto com o WinUI, talvez possa criar um problema separado com suas preocupações, mas realmente não acho que seus comentários tenham algo a ver com o controle DataGrid.

@verelpode , mantenha seus comentários sobre o assunto. Se você tiver dúvidas sobre WinUI ou UWP em geral, inicie um novo tópico de discussão ou entre em contato comigo diretamente (e-mail ou DM no Twitter). Ou você pode considerar discutir um tópico existente como # 717 ou # 1531.

Você compartilhou preocupações sobre o DataGrid ser reescrito em C ++, mas na verdade a proposta original não mencionou nada sobre isso. @anawishnoff está tentando coletar feedback sobre o conjunto de recursos DataGrid. Em termos de implementação, se fizer mais sentido mantê-lo em C #, faríamos isso (e ainda poderia ser chamado de C ++ se o fizéssemos como um componente WinRT).

@jevansaks - Meu feedback foi sobre o assunto, mas é da natureza humana atirar no mensageiro que dá as más notícias. Sua resposta me deixa triste e desapontado. Ok, vou parar de tentar ajudar, porque minha ajuda é indesejada porque é muito honesta e direta e toca em questões dolorosas que são dolorosas demais para serem reconhecidas e resolvidas (a falha catastrófica do WinRT levanta muitas emoções e é mais fácil de apagar de memória e continue o mesmo plano original do WinRT, como se o desastre nunca tivesse acontecido). Sairei desta discussão e não participarei mais do desenvolvimento do DataGrid porque continuar a falar honesta e diretamente sobre os problemas reais apenas incomodará as pessoas.

@verelpode Ninguém "atirou no mensageiro que dá as más notícias" aqui. @jevansaks convidou você a abrir uma nova edição para compartilhar suas amplas preocupações sobre UWP / WinUI / WinRT neste repositório. Esse problema realmente é apenas sobre o DataGrid e, embora de fato uma de suas preocupações fosse sobre o DataGrid, a grande maioria era sobre UWP / WinUI / WinRT em geral. Tenho certeza que se você olhar para esta discussão novamente, você verá que a equipe WinUI está apenas pedindo que você mantenha este problema focado exclusivamente na proposta do DataGrid e abra um novo / use um problema existente para suas preocupações mais amplas sobre o plataforma.

As preocupações que você mencionou podem ser a base para uma discussão interessante envolvendo a equipe WinUI e a comunidade, mas esse problema específico não é adequado para tal discussão.

@anawishnoff
Tenho certeza de que o controle do Microsoft Pivot Viewer não era html. Por favor, olhe para trás. A capacidade de visualizar grandes conjuntos de dados usando algo assim era algo que sempre quisemos fazer. Estava disponível no Silverlight, eu acho. https://www.microsoft.com/silverlight/pivotviewer/default# Usou Deep Zoom para sua funcionalidade. Adicionar o recurso Deep Zoom ao WinUI 3.0 seria fabuloso! Não é realmente o DataGrid, mas um controle Data Display. Existem muitas ideias "abandonadas" desde os primeiros dias do WPF, como Deep Zoom, que nunca se tornaram um controle WPF de produção que seria maravilhoso trazer de volta à vida no WinUI 3.0 com o tempo. Vá tirar o Dr. WPF do porão e faça-o postar novamente !!! Precisamos dele de volta. Precisamos iniciar um movimento. TRAGA DE VOLTA Dr. WPF !!!!! Onde você foi? Dr. WinUI !!!

@PaulMontgomerySP parece que você deve abrir um novo problema para discutir o controle Pivot. Sinta-se à vontade para consultar a discussão anterior sobre isso no Windows Community Toolkit aqui: https://github.com/windows-toolkit/WindowsCommunityToolkit/issues/770

A seleção alterou os disparos de evento para cada linha para a qual movo com o teclado.
Seria bom ter um evento apenas para um clique do mouse ou toque na célula, em vez de apenas o evento de seleção alterada.

A seleção mudou disparos de evento para clique e teclado. Seria muito benéfico ter um evento exclusivamente para clicar.

@ Going-Gone Estou curioso para saber qual é o caso de uso para isso? Por que você precisa saber a diferença? Você também não pode usar o evento tocado?

Uma limitação que acabei de atingir com o DataGrid do UWP Toolkit é que DataGridTemplateColumn tem um CellTemplate, mas não tem um CellTemplateSelector (e o mesmo faltando para CellEditingTemplate ). Isso simplificaria a adaptação da IU em cada célula aos dados usando a abordagem do seletor, em vez de ter que fazer isso com um nível extra de controles da IU abaixo dele para lidar com isso.

Além disso, torne possível selecionar linhas não apenas em uma ordem consecutiva, como expliquei em detalhes aqui:
https://github.com/duke7553/files-uwp/issues/276#issue -520060100

Em nenhuma ordem particular de coisas que são frequentemente solicitadas pelos clientes que uma grade deve apoiar

1. Capacidade de salvar, carregar e construir filtros. Ex: filtro para expressão linq, filtro para consulta SQL, filtro para árvore de expressão e vice-versa. Exemplo - https://querybuilder.js.org/demo.html

  1. Capacidades de dados em tempo real de alta velocidade, desempenho é importante. Taxas de atualização abaixo de 1 ms para aplicativos de negociação vs> 1 milhão de linhas têm diferentes considerações de desempenho.
  2. Capacidade de especificar a ordem de classificação, por exemplo, i. classificar alto / baixo, ii. classificar baixo / alto e iii. nenhum tipo ou eu. classificar baixo / alto, ii. classificar alto / baixo e iii. nenhum tipo
  3. Filtragem tipo Excel
  4. Capacidade de aplicar a formatação css às ​​células, formatação condicional
  5. Capacidade de salvar / carregar configurações de grade facilmente, por exemplo, filtros, larguras de coluna, classificação, etc.
  6. A rolagem que funciona, por exemplo, não redefine após a atualização dos dados, é suave.
  7. Os eventos de coleta de dados devem ter opções para disparar eventos após intervalos de carregamento, em vez de objetos individuais. Por exemplo, acredito que ObservableCollection requer uma subclasse para evitar o disparo de INotifyPropertyChange para cada objeto individual adicionado.
  8. Melhores eventos para quando os dados são carregados / carregados, carregamento de dados iniciado, carregamento de dados, carregamento de dados, especialmente se estiver usando carregamento assíncrono.
  9. As grades são frequentemente vinculadas a outros controles, como filtros de dados, seleção de intervalo, filtro cruzado (por exemplo, https://github.com/dc-js/dc.js), gráficos, tabelas dinâmicas etc.
  10. Classificação inteligente que lida com dados alfanuméricos, por exemplo, ordem de classificação ABC11, ABC12, ABC111 em vez de ABC11, ABC111, ABC12
  11. Níveis ilimitados de grades hierárquicas, por exemplo, https://docs.telerik.com/devtools/wpf/controls/radgridview/hierarchical-gridview/hierachy-overview

Recursos úteis: - Projete melhores tabelas de dados
https://news.ycombinator.com/item?id=21460966
https://uxdesign.cc/design-better-data-tables-4ecc99d23356

Não serei capaz de vincular à largura de coluna do cabeçalho diretamente. No WPF, devo usar um objeto BindingProxy nesse caso.

Redimensionamento dinâmico conveniente da linha ativa para edição mais fácil.
Controle total dos menus de contexto no modo de edição.

Espero que suporte CellDecorationStyleSelector como em Telerik.

Acessibilidade!
Mencionar isso para que seja documentado, mas esse controle precisa estar totalmente acessível.
A versão atual do kit de ferramentas tem algumas limitações nesta área: https://github.com/windows-toolkit/WindowsCommunityToolkit/issues/3400 & https://github.com/windows-toolkit/WindowsCommunityToolkit/issues/3079
Além disso, embora o Telerik RadDataGrid tenha alguns recursos excelentes, ele parece não oferecer suporte à acessibilidade .

Com o grande impulso da Microsoft para D&I, estou surpreso que a necessidade de todos os controles estarem totalmente acessíveis não seja especificada como um requisito em todos os lugares.

Talvez isso já seja possível, e eu só não sei como fazer ainda ... mas que tal: estilo de linha ou célula customizado?

A capacidade de direcionar uma linha específica, alterar o plano de fundo e a cor do texto seria ótimo.

Em comparação com o WCT UWP DataGrid:
1) Desempenho
2) Mais tipos de coluna integrados (presumo que tenham melhor desempenho do que colunas de modelo)
3) Capacidade de enganchar eventos do mouse por célula, ou seja, tocar, tocar com o botão direito e passar o mouse (ou apontar para baixo ou qualquer outra coisa)
4) Eventos de teclado por célula
5) Se (3) não for viável, poderíamos emular se tivéssemos a funcionalidade de teste de clique
6) Desempenho

Quantas pessoas levantariam uma objeção se o WinUI DataGrid abandonasse o recurso em que os usuários finais são capazes de editar os valores das células inline / diretamente dentro do DataGrid?

Alguém se lembra do VB6? O VB6 DataGrid suporta Edit, Delete e AddNew fora da caixa. Adicionar estava disponível como uma linha em branco adicionada automaticamente ao final da lista. Complete a linha e outra linha em branco aparecerá.

Um DataGrid deve ter a opção de suportar a entrada de dados, mesmo se a maioria dos desenvolvedores preferir que esse recurso seja desativado por padrão.

Ao portar um aplicativo VB6 para UWP, tivemos que escrever nossa própria grade de dados para oferecer suporte a adicionar / editar / excluir.

Parece que a maioria dos que contribuem aqui são pessoas do WPF / Xaml, isso vale dois centavos de alguém que não é xaml.

Eu uso muito os controles DataGrid no meu software. A edição no local é importante! Alguns dos meus desejos / pontos de dor são:

  1. Capacidade de personalizar o menu de contexto quando estiver no modo de edição.
  2. Melhor desempenho e mais controle ao dimensionar colunas automaticamente. Desejo que o usuário seja capaz de controlar os tamanhos, se necessário, mas na maioria das vezes não é necessário. Não quero que os tamanhos das colunas mudem constantemente, mas quero que de alguma forma se baseiem nos dados, sem ter que medir um milhão de linhas de dados.
  3. Ao editar, quero poder clicar em um controle / botão diferente que faça algo para (ou com) os dados sendo editados sem terminar a edição. (Isso seria menos necessário se o nº 1 fosse implementado - embora ainda seja útil.)
  4. a maneira atual como as exceções são tratadas usando o evento DataError é aproximada. (Desculpe, estou tendo problemas para ser específico sobre isso, mas sei que isso me causou dor várias vezes no passado.)
  5. Capacidade de rolagem automática integrada seria bom: http://stackoverflow.com/questions/2567809/how-to-autoscroll-a-datagridview-during-drag-and-drop
  6. Capacidade de exibir uma "marca d'água" indicando quando os dados estão "sujos" (consulte BetterGrid para obter algumas melhorias adicionais úteis para DataGridView.
  7. Capacidade de abandonar uma linha (sem um erro de validação) quando a célula "chave" necessária é deixada em branco.
  8. Capacidade integrada de não exibir nenhuma imagem (em vez de um X vermelho) para uma linha adicionada pelo usuário. Veja: https://stackoverflow.com/questions/937919/datagridviewimagecolumn-red-x
  9. Permita que uma coluna de caixa de seleção seja confirmada imediatamente quando alterada: https://stackoverflow.com/questions/11843488/how-to-detect-datagridview-checkbox-event-change

Quando o alfa deve ser lançado? Estará aberto a contribuições? Tentando livrar-se de uma grade de dados desatualizada e realmente ansioso por isso, especialmente o recurso de virtualização.

Desculpe por colocar uma entrada muito tardia neste tópico, mas para mim é "novo";)
_editado após saber um pouco mais sobre como o controle se comporta_

Ao trabalhar com DataGrid para criar uma interface semelhante a um explorador para drives em nuvem, descobri que determinar a linha e a célula que são tocadas pode ser um pouco mais complexo do que "deveria" ser (IMHO)

No design do meu aplicativo, as linhas representam arquivos ou pastas (DriveItems). A visualização de detalhes mostra mais detalhes sobre o item.

Eu queria criar a capacidade de clicar em um item da pasta e fazer a interface saltar e criar uma lista desses itens, permitindo a navegação por toda a unidade.

image

Por exemplo, se eu tocasse na entrada da coluna "Pai" do item, /drive/root:/Documents/Vital%20Documents aqui, a interface seria redefinida para essa pasta e listaria os arquivos lá.

Embora seja possível obter um evento clicado para a célula, esse evento não parece ter o contexto para o manipulador determinar a célula que foi tocada (linha, sim, mas não coluna), e não tenho certeza de que atualmente o controle me permitiria ter o comportamento da célula tocada E o comportamento de detalhes abertos automaticamente (ainda investigando o que eu poderia chamar de "hacks" que permitiriam isso, mas temos que nos lembrar que quando os designers começam a substituir o funcionamento normal do controle, especialmente não sendo comportamentos documentados, eles correm o risco de ter o design interrompido por mudanças no comportamento do controle.

Dito isso, o DataGrid parece apoiar meu cenário por ter o evento que atualmente retorna o DriveItem como CurrentItem, também deve incluir um CurrentColumn que seria todo o objeto DataGridColumn que foi clicado, através qual seria possível extrair o nome da coluna. Eu percebo agora que temos o objeto CurrentColumn que podemos investigar a partir do evento, então, embora eu prefira que seja o argumento do evento, isso deve funcionar.

Além disso, um controle mais rigoroso do comportamento dos detalhes pode significar que os detalhes só seriam expandidos automaticamente com base no clique em uma coluna específica, em vez de expandir sempre que alguém clicasse em qualquer lugar da linha.

Talvez a classe base do objeto DataGridColumn pudesse ter uma propriedade ExpandDetails que pode ser definida como verdadeira por padrão para cada coluna, o que significaria que a coluna clicada em particular faz com que a linha se expanda. Outros em que a propriedade é falsa não o seriam.

Em meu projeto, por exemplo, a primeira coluna é o tipo de item, como em Arquivo ou Pasta, ou Imagem ou Foto, Áudio, etc. Posso imaginar configurar essa coluna para ser a única a causar o comportamento de expansão automática, e, em seguida, um clique na coluna Caminho pode causar o comportamento "obter uma lista desse caminho" que descrevi acima.

Quanto à classificação, parece logicamente importante implementar controle suficiente para permitir que os designers obtenham classificação em vários níveis. Eu não fiz uma investigação para determinar como o controle atual pode suportar isso por meio de eventos de enganchar / substituir e retornos de chamada, mas não parece simples.

Finalmente, eu sei que você está ciente disso, mas (embora eu esteja pedindo mais funcionalidade), vamos POR FAVOR, evitar tentar adicionar um monte de comportamentos complexos que os usuários podem implementar por conta própria no DataGrid. Entre esses que eu não implementaria no DataGrid estão os que têm a ver com o armazenamento externo de filtros ou classificações, etc. Eu também evitaria transformar esse controle em um clone do Excel.

-Obrigado, ótimo trabalho!
-e

Grupos fixos: ao navegar em conjuntos de dados com grandes grupos, deve haver contexto sobre qual grupo (ou grupos, por exemplo, breadcrumb) está sendo visualizado. Este parece ser um recurso de usabilidade essencial para todas as visualizações hierárquicas baseadas em listas: visualizações de listas agrupadas, datagrids e visualizações em árvore.

Gostaria de construir o novo controle DataGrid sobre o novo controle WinUI ItemsRepeater. E esse controle expõe seu ItemsSource como um objeto:
Object ItemsSource { get; set; };

@RBrid Voltando a isso ~ 1 ano depois. Percebi que o ItemsRepeater, embora tenha um objeto ItemsSource, não tem suporte integrado para as seguintes interfaces necessárias para trabalhar com fontes de dados virtualizadas:

  • ISupportIncrementalLoading
  • IItemsRangeInfo
  • ISelectionInfo

- Que tal colocar um MVP lá agora para que possamos usar um Datagrid de c ++.

Esta página foi útil?
0 / 5 - 0 avaliações