none
DataField fora do DataForm não alinha o conteúdo? RRS feed

  • Pergunta

  • Opa, blz..

    Estou fazendo um layout diferenciado na aplicação SL que tenho, para isso gostaria de utilizar o recurso do DataField do SL Toolkit mas sem utilizar o DataForm. Isto porque o DataField traz a validação do metadata no próprio campo (deixa ele vermelho e tals..). Quero coloca-lo em um Grid layout simples. Até ai tranquilo, funciona, traz o binding e faz a validação. O problema é que quando uso os mesmos DataFields em um template do DataForm ele automaticamente alinha os labels e os conteudos para ficarem alinhados horizontalmente. Quer dizer labels a esquerda e o conteudo a direita alinhado pelo label mas largo.
    Isto não é possivel de ser feito automaticamente fora do DataForm? Gostaria de deixa-los no Grid layout ou StackPanel e alinha-los igual ao DataForm.
    segunda-feira, 1 de fevereiro de 2010 19:14

Respostas

  • Olá

    Dei uma olhada no código fonte do DataField (voce pode baixá-lo no Codeplex http://silverlight.codeplex.com). Ao que me parece, os objetos DataField e DataForm interagem quando juntos, fazendo que os Labels dos DataFields fiquem alinhados a direita e todos com tamanho igual ao do maior Label.

    Se os labels na sua aplicação forem sempre texto, voce pode imitar esse comportamento de maneira até bem simples. Basta percorrer todos os DataFields em um Panel (grid, stackpanel, etc...) e procurar o label (que será um TextBlock) que tiver a propriedade ActualWidth com maior valor. Depois disso é só setar a propriedade MinWidth de todos os Labels dos DataFields com esse valor, e botar um Padding para alinhá-los a direita.

    Por exemplo:

    MainPage.xaml
            <StackPanel x:Name="dataFieldsContainer">
                <my:DataField x:Name="df1" >
                    <my:DataField.Label>
                        <TextBlock Text="Nome" HorizontalAlignment="Right" />
                    </my:DataField.Label>
                    <TextBox />
                </my:DataField>
                <my:DataField x:Name="df2" >
                    <my:DataField.Label>
                        <TextBlock Text="Data de nascimento:" HorizontalAlignment="Right" />
                    </my:DataField.Label>
                    <my1:DatePicker></my1:DatePicker>
                </my:DataField>
            </StackPanel>

    MainPage.xaml.cs
            private void UserControl_Loaded(object sender, RoutedEventArgs e)
            {
                var dataFields = dataFieldsContainer.Children.Where(element => element is DataField).Select(element => element as DataField);
                double maxWidth = 0;
                foreach (var dataField in dataFields)
                {
                    var elementWidth = (double)(dataField.Label as TextBlock).GetValue(TextBlock.ActualWidthProperty);

                    if(elementWidth > 0 && !double.IsInfinity(elementWidth))
                        maxWidth = elementWidth;
                }

                if(maxWidth > 0)
                    foreach (var dataField in dataFields)
                    {
                        var actualWidth = (double)(dataField.Label as TextBlock).GetValue(TextBlock.ActualWidthProperty);
                        (dataField.Label as TextBlock).SetValue(TextBlock.PaddingProperty, new Thickness(maxWidth - actualWidth, 0, 0, 0));
                        (dataField.Label as TextBlock).SetValue(TextBlock.MinWidthProperty, maxWidth);
                       
                    }
            }

    Pelo que eu olhei no código do DataField, eles fizeram algo parecido com isso.

    Breno Ferreira

    Site: http://brsilverlight.com
    Blog: http://brenocferreira.spaces.live.com
    Twitter : http://twitter.com/breno_ferreira

    Se a resposta foi útil, por favor, marque como resposta

    • Marcado como Resposta LTres terça-feira, 2 de fevereiro de 2010 17:40
    terça-feira, 2 de fevereiro de 2010 16:30
  • Irei concordar com o colega.. afinal andei pesquisando bastante tb e não encontrei outra alternativa. Mas como no meu prob em particular eu tenho esses DataFields dentro de um Grid em um AccordionItem que é gerado conforme um DataSource, acabei optando por organizar os controles manualmente. Defino em cada um uma margem no TextBox interno. É trabalhoso mas por se tratar de um componente dinamico e afim de evitar probs fiz assim, mas a solução proposta cai bem tb.
    • Marcado como Resposta LTres terça-feira, 2 de fevereiro de 2010 17:43
    terça-feira, 2 de fevereiro de 2010 17:43

Todas as Respostas

  • Olá

    Dei uma olhada no código fonte do DataField (voce pode baixá-lo no Codeplex http://silverlight.codeplex.com). Ao que me parece, os objetos DataField e DataForm interagem quando juntos, fazendo que os Labels dos DataFields fiquem alinhados a direita e todos com tamanho igual ao do maior Label.

    Se os labels na sua aplicação forem sempre texto, voce pode imitar esse comportamento de maneira até bem simples. Basta percorrer todos os DataFields em um Panel (grid, stackpanel, etc...) e procurar o label (que será um TextBlock) que tiver a propriedade ActualWidth com maior valor. Depois disso é só setar a propriedade MinWidth de todos os Labels dos DataFields com esse valor, e botar um Padding para alinhá-los a direita.

    Por exemplo:

    MainPage.xaml
            <StackPanel x:Name="dataFieldsContainer">
                <my:DataField x:Name="df1" >
                    <my:DataField.Label>
                        <TextBlock Text="Nome" HorizontalAlignment="Right" />
                    </my:DataField.Label>
                    <TextBox />
                </my:DataField>
                <my:DataField x:Name="df2" >
                    <my:DataField.Label>
                        <TextBlock Text="Data de nascimento:" HorizontalAlignment="Right" />
                    </my:DataField.Label>
                    <my1:DatePicker></my1:DatePicker>
                </my:DataField>
            </StackPanel>

    MainPage.xaml.cs
            private void UserControl_Loaded(object sender, RoutedEventArgs e)
            {
                var dataFields = dataFieldsContainer.Children.Where(element => element is DataField).Select(element => element as DataField);
                double maxWidth = 0;
                foreach (var dataField in dataFields)
                {
                    var elementWidth = (double)(dataField.Label as TextBlock).GetValue(TextBlock.ActualWidthProperty);

                    if(elementWidth > 0 && !double.IsInfinity(elementWidth))
                        maxWidth = elementWidth;
                }

                if(maxWidth > 0)
                    foreach (var dataField in dataFields)
                    {
                        var actualWidth = (double)(dataField.Label as TextBlock).GetValue(TextBlock.ActualWidthProperty);
                        (dataField.Label as TextBlock).SetValue(TextBlock.PaddingProperty, new Thickness(maxWidth - actualWidth, 0, 0, 0));
                        (dataField.Label as TextBlock).SetValue(TextBlock.MinWidthProperty, maxWidth);
                       
                    }
            }

    Pelo que eu olhei no código do DataField, eles fizeram algo parecido com isso.

    Breno Ferreira

    Site: http://brsilverlight.com
    Blog: http://brenocferreira.spaces.live.com
    Twitter : http://twitter.com/breno_ferreira

    Se a resposta foi útil, por favor, marque como resposta

    • Marcado como Resposta LTres terça-feira, 2 de fevereiro de 2010 17:40
    terça-feira, 2 de fevereiro de 2010 16:30
  • Irei concordar com o colega.. afinal andei pesquisando bastante tb e não encontrei outra alternativa. Mas como no meu prob em particular eu tenho esses DataFields dentro de um Grid em um AccordionItem que é gerado conforme um DataSource, acabei optando por organizar os controles manualmente. Defino em cada um uma margem no TextBox interno. É trabalhoso mas por se tratar de um componente dinamico e afim de evitar probs fiz assim, mas a solução proposta cai bem tb.
    • Marcado como Resposta LTres terça-feira, 2 de fevereiro de 2010 17:43
    terça-feira, 2 de fevereiro de 2010 17:43