Domanda

Mi chiedo, qual è il modo migliore e più veloce per ottenere la nota etichetta Input [o output, non importa] in WPF. È un compito semplice, basti pensare a un rapido output di " oggetto " ME:


Nome - Cristiano

Età - 28

Mood - Good


Lo so, posso usare una griglia con TextBlocks. Ma ad essere onesti, il "breve" XAML per questo è lungo quasi mezza pagina (RowDefinitions, ColDefs, Grid.Col su ogni etichetta)

In alternativa, usare tre StackPanel (orizzontale) con una verticale sembra anche un po 'stupido. In questo caso, devo assegnare a ciascuna etichetta una larghezza fissa, per ottenere il rientro corretto. E semplicemente non "sente" a destra.

Quindi, data la situazione sopra, hai un oggetto personalizzato con 3-6 Proprietà che vuoi scaricare come sola lettura sulla tua GUI, come lo faresti (in WPF, anche Silverlight, se sei davvero in vena :).

Posso, ovviamente, scrivere un controllo utente per questo. Ma perché reinventare la ruota, se potrebbe essere già lì ...

E infine, per illustrare ulteriormente, l'esempio che ho appena creato nella vita reale ed è stato il motivo di questo 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>
È stato utile?

Soluzione

Se stai usando 3.5sp1 puoi usare StringFormat nell'associazione. Qualcosa del genere dovrebbe funzionare ...

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

Altri suggerimenti

Forse dovresti ripensare la tua interfaccia utente. Perché dovresti voler Label - Textbox sulla stessa riga? È uno spreco di spazio orrendo.

Perché non etichettare su texbox? Quindi hai una semplice interfaccia utente e semplice XAML:

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

Aggiungi un po 'di stile per i tuoi TextBlocks e hai un'interfaccia utente bella e pulita, con pochissima ripetizione.

È possibile utilizzare gruppi di dimensioni condivise per ottenere il comportamento Grid di dimensionamento automatico di due colonne ben allineate, pur essendo in grado di estrarre la complessità in un UserControl.

Ecco un esempio dell'uso di un controllo LabeledEdit che farebbe quello che stai cercando. La complessità è stata presa in considerazione in UserControl e tutto ciò che devi fare è ricordare di impostare Grid.IsSharedSizeScope su 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>

Ed ecco il codice sorgente per 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); }
        }
    }
}

Il silverlight toolkit ha un DataForm controllo che funziona abbastanza bene!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top