Pergunta

Eu estou querendo saber, qual é a melhor e mais rápida maneira de obter a entrada Etiqueta bem conhecida [ou de saída, não importa] combinação em WPF. É uma tarefa simples, basta pensar em uma saída rápida do "objeto" ME:


Nome - Christian

Idade - 28

Mood - Boa


Eu sei, eu posso usar uma grade com TextBlocks. Mas para ser honesto, o "curto" XAML para isso é quase a metade de uma página de comprimento (RowDefinitions, ColDefs, Grid.Col em cada Label)

A forma alternativa, utilizando três StackPanels (horizontal) com uma vertical também parece um pouco estúpido. Neste caso, eu tenho que dar a cada etiqueta uma largura fixa, para obter a correta travessão. E ele simplesmente não "sentir" a direita.

Assim, dada a situação acima, você tem um objeto personalizado com 3-6 Propriedades você só quer despejar como somente leitura para o seu GUI, como você fazê-lo (em WPF, Silverlight também, se você estiver realmente com vontade :).

Eu posso, é claro, escrever um usercontrol para isso. Mas por que reinventar a roda, se ele pode já estar lá ...

E, finalmente, para ilustrar ainda mais, o exemplo que acabou de criar na vida real e foi a razão para este post:

      <StackPanel>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="Log Count"  Width="100"/>
            <TextBlock Text="{Binding LastLogRun.LogMessageCount}"/>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="Start Time" Width="100"/>
            <TextBlock Text="{Binding LastLogRun.StartTime}"/>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="End Time" Width="100"/>
            <TextBlock Text="{Binding LastLogRun.EndTime}"/>
        </StackPanel>
    </StackPanel>
Foi útil?

Solução

Se você estiver usando 3.5SP1 você pode usar StringFormat na ligação. Algo como isso deve funcionar ...

<TextBlock Text="{Binding LastLogRun.LogMessageCount, StringFormat={}Log Count - {0}}" />

Outras dicas

Talvez você deve repensar a sua UI. Por que você quer etiqueta - Caixa de texto na mesma linha? Isso é um desperdício terrível do espaço.

porque não etiqueta mais texbox? Então você tem uma interface de usuário simples e XAML simples:

<StackPanel Orientation="Vertical">
  <TextBlock>Name</TextBlock>
  <TextBox />
  <TextBlock>Age</TextBlock>
  <TextBox />
  <TextBlock>Mood</TextBlock>
  <TextBox />
</StackPanel>

Adicione um pouco de estilo para seus TextBlocks e você tem um agradável, UI limpo, com muito pouca repetição.

Você pode usar grupos de tamanho compartilhados para obter o comportamento de dimensionamento automático de grade de duas colunas bem alinhadas-up-, enquanto ainda está sendo capaz de retirar a complexidade em um UserControl.

Aqui está um exemplo de como usar um controle LabeledEdit que faria o que você está procurando. A complexidade tem sido consignado afastado no UserControl, e tudo que você precisa fazer é se lembrar de Grid.IsSharedSizeScope set no StackPanel:

<Window x:Class="WpfApplication5.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication5"
        Name="Self" Title="Window1" Height="300" Width="300">
    <StackPanel Grid.IsSharedSizeScope="True">
        <local:LabeledEdit Label="Name"/>
        <local:LabeledEdit Label="Age" Text="28"/>
        <!-- and with databinding... -->
        <local:LabeledEdit Label="Width"
                           Text="{Binding Width, ElementName=Self}"/>
        <local:LabeledEdit Label="Height"
                           Text="{Binding Height, ElementName=Self}"/>
    </StackPanel>
</Window>

E aqui está o código fonte para o UserControl. LabeledEdit.xaml:

<UserControl x:Class="WpfApplication5.LabeledEdit"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             Name="Self">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" SharedSizeGroup="LabeledEdit_Labels"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Label Grid.Column="0" Content="{Binding Label, ElementName=Self}"/>
        <TextBox Grid.Column="1" Text="{Binding Text, ElementName=Self}"/>
    </Grid>
</UserControl>

LabeledEdit.xaml.cs:

using System.Windows;

namespace WpfApplication5
{
    public partial class LabeledEdit
    {
        public static readonly DependencyProperty LabelProperty =
            DependencyProperty.Register("Label", typeof(object), typeof(LabeledEdit));
        public static readonly DependencyProperty TextProperty =
            DependencyProperty.Register("Text", typeof(string), typeof(LabeledEdit),
            new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

        public LabeledEdit()
        {
            InitializeComponent();
        }

        public object Label
        {
            get { return GetValue(LabelProperty); }
            set { SetValue(LabelProperty, value); }
        }
        public string Text
        {
            get { return (string)GetValue(TextProperty); }
            set { SetValue(TextProperty, value); }
        }
    }
}

O Silverlight Toolkit tem um controle DataForm que funciona muito legal!

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