Question

Je me demande quel est le moyen le plus rapide et le meilleur d’obtenir la combinaison bien connue d’entrée étiquette [ou sortie, peu importe] dans WPF. C’est une tâche simple, il suffit de penser à une sortie rapide de "l’objet". ME:

Nom - Chrétien

Âge - 28

Humeur - Bien

Je sais, je peux utiliser une grille avec TextBlocks. Mais pour être honnête, le "court" & Le code XAML utilisé pour cette opération est long d’une demi-page (RowDefinitions, ColDefs, Grid.Col sur chaque étiquette)

L’utilisation alternative de trois StackPanels (horizontaux) avec une verticale semble également un peu stupide. Dans ce cas, je dois attribuer une largeur fixe à chaque étiquette pour que le retrait soit correct. Et ça ne "sent" pas. à droite.

Donc, étant donné la situation ci-dessus, vous avez un objet personnalisé avec 3 à 6 propriétés que vous voulez simplement vider en lecture seule dans votre interface graphique. Comment le feriez-vous (dans WPF, Silverlight aussi, si vous êtes vraiment d'humeur :).

Je peux bien sûr écrire un contrôle utilisateur pour cela. Mais pourquoi réinventer la roue, si elle existe déjà ...

Enfin, pour illustrer encore davantage l’exemple que j’ai créé dans la vie réelle, c’était la raison de ce message:

      <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>
Était-ce utile?

La solution

Si vous utilisez 3.5sp1, vous pouvez utiliser StringFormat dans la liaison. Quelque chose comme ça devrait marcher ...

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

Autres conseils

Peut-être devriez-vous repenser votre interface utilisateur. Pourquoi voudriez-vous Label - Zone de texte sur la même ligne? C'est une perte d'espace épouvantable.

Pourquoi ne pas étiqueter sur texbox? Ensuite, vous avez une interface utilisateur simple et XAML simple:

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

Ajoutez du style à vos TextBlocks pour obtenir une interface utilisateur agréable et claire, avec très peu de répétition.

Vous pouvez utiliser des groupes de tailles partagées pour obtenir le comportement de la grille de dimensionnement automatique de deux colonnes bien alignées, tout en pouvant extraire la complexité dans un contrôle UserControl.

Voici un exemple d'utilisation d'un contrôle LabeledEdit qui ferait ce que vous cherchez. La complexité a été entièrement prise en compte dans UserControl et tout ce que vous avez à faire est de vous rappeler de définir Grid.IsSharedSizeScope sur 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>

Et voici le code source de 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); }
        }
    }
}

La boîte à outils silverlight a un DataForm , un contrôle qui fonctionne très bien!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top