dados WPF grade de ligao
-
06-07-2019 - |
Pergunta
Eu tenho uma grade com apenas 1 linha. Gostaria que a quantidade de colunas a ser determinado pelo contexto de dados da grade.
Por exemplo, se eu tenho uma lista de nomes expostos em uma propriedade ObservableCollection chamados 'nomes' que o retorno "Fred", "Joe" e "Anne", gostaria três colunas na grade, cada um com uma caixa de texto obrigado a cada nome.
Os meus pensamentos até agora:
1) Construir a grade com a mão no código-behind e reconstruí-lo quando as mudanças de ObservableCollection. Eu não ir com isso, pois parecia um cludgy pouco e não a forma WPF de fazer as coisas.
2) Criar uma ligação com a propriedade ColumnDefinitions do Grid. Isso parecia mais correto, mas não há uma propriedade de dependência sobre a grade para ColumnDefinition.
Solução
Eu não acho que a modificação de uma grade na mosca é sua melhor aposta. Aqui está outra solução. Você pode usar caixa de listagem, mas substitua o ItemsPanel com um outro painel de sua escolha. ItemsPanel padrão do ListBox é VirtualizingStackPanel com o conjunto de Orientação para Vertical. Desde que você quer que seus itens a serem exibidos na horizontal, você pode substituí-lo com VirtualizingStackPanel com o conjunto de Orientação para Horizontal . Claro, você pode modificar o ItemsTemplate ou qualquer outra coisa, como você vê o ajuste.
<ListBox ItemsSource="{Binding MyCollection}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
Eu também usei esse método antes de criar uma caixa de listagem que exibe os itens na horizontal, mas passará para a próxima linha quando ele é executado fora da sala na linha, usando um WrapPanel. Você também pode criar seus próprios painéis personalizados e substituí-los. Uma vez fiz um painel que colocou para fora é itens de forma aleatória, e usou isso para uma caixa de listagem. Cada item na minha coleção ligada foi apresentado numa posição aleatória dentro da caixa de listagem. Cada vez que o layout atualizado, os itens tem uma nova posição.
Outras dicas
Se é um DataGrid , a AutoGenerateColumns propriedade faria isso. Ao utilizar o DataGridTemplateColumn , você pode colocar controles de caixa de texto em vez de apenas texto lá. Você precisará fornecer um evento ligado à AutoGeneratingColumn e na AutoGeneratingColumnEventArgs (oi, Microsoft, este é do túnel do carpo chamando), defina a propriedade de coluna a uma coluna de modelo com caixa de texto.
Eu diria que o seu caminho ObservableCollection é mais simples ;-P.
Se você pode aceitar ter os nomes em cada linha, em vez de cada coluna, você deve usar o ListView com uma propriedade GridView View, e uma CellTemplate personalizado que é apenas uma caixa de texto vinculado. Algo parecido com isto:
<ListView ItemsSource="{Binding Names}">
<ListView.View>
<GridView>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<!-- Your textbox goes in a DataTemplate here -->
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
Solução # 2 não é, infelizmente, possível em XAML. Solução # 1 é a sua melhor aposta se você deve ter cada nome em sua própria coluna.