2009-09-15 11 views
7

Ho il seguente codice per visualizzare l'età di un client.WPF Mixing Bound e testo fisso in un TextBox

<TextBox x:Name="txtClientAge" Text="{Binding Path=ClientAge}" /> 

Tuttavia, invece di visualizzare solo il numero, voglio prefisso con il testo "Age" e il suffisso con il testo "anni", così si diventa effettivamente "Età 36 anni"

Posso ottenere questo con uno StackPanel orizzontale e 3 caselle di testo, ma c'è un metodo molto più semplice che mi manca?

+0

Vuoi che le parti "età" e "anni" siano modificabili? Cioè l'utente dovrebbe essere autorizzato a digitare "età 40 anni" (o forse anche semplicemente "40") nella casella di testo nella sua interezza, e farlo analizzare correttamente? –

+0

In ogni caso, se nella tua applicazione è presente una sola casella di testo di questo tipo (cioè non è necessario che sia riutilizzabile), la soluzione StackPanel + 2 TextBlocks + TextBox sarà la più semplice. –

+0

E 'solo per essere usato come readonly, nessun aggiornamento richiesto. – Mitch

risposta

8

Supponendo che non sia necessario modificare il valore dell'età, in WPF 4.0 la proprietà Text di Run sarà associabile, questo probabilmente non ti aiuta in questo momento, a meno che tu non stia utilizzando la pre-release ma sarai in grado di fare qualcosa di simile al seguente:

<TextBlock x:Name="txtClientAge" > 
    <Run Text="Age "/><Run Text="{Binding Path=ClientAge}"/><Run Text=" Yrs"/> 
</TextBlock> 

UPDATE Heres un'altra alternativa alla soluzione stringa di formato che funziona, ma non è particolarmente bella (in realtà è abbastanza hacky). Utilizzare il seguente convertitore sul legame (proprietà clientage assumendo è di tipo int):

public class AgeConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, 
          System.Globalization.CultureInfo culture) 
    { 
     string age = value.ToString(); 
     return "Age " + age + " years"; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, 
           System.Globalization.CultureInfo culture) 
    { 
     string age = value as string; 
     return Int32.Parse(age.Replace("Age ", " ").Replace(" years", "")); 
    } 
} 
+0

Grazie Simon, questo era il genere di cose che stavo cercando ma, come dici tu, non è ancora abbastanza per noi! Potrei dover adottare un approccio a lungo termine fino a quando WPF 4.0 non sarà con noi. – Mitch

+0

Bel po 'di compagno di pensiero laterale. Attualmente mi piace usare i convertitori per tutti i tipi di cose, quindi il tuo approccio è davvero interessante. Grazie per quello! – Mitch

+0

Sì, ConvertBack è la parte che non mi piace, ma poiché è una situazione di sola lettura che non sarà un problema. –

5

È possibile creare una proprietà nella classe che si sta impegnando anche per creare la stringa di testo che si desidera visualizzare.

C'è anche il percorso StringFormat:

<textblock text="{Binding Path=mydate, StringFormat=d}"/> 

È possibile hackerare le costanti nella stringa di formattazione.

Preferisco il metodo di proprietà.

+3

Si tratta essenzialmente di modificare il modello in modo che sia sensibile alla vista: una pessima idea dal punto di vista del design. –

+1

+1 per StringFormat. Accetta con @Pavel - non creare una proprietà con questo testo al suo interno. – Andy

+2

Se vuoi davvero farlo bene, allora anche il testo non appartiene alla vista. Deve trovarsi in un'area delle risorse selezionata dal livello di presentazione in base alla tua attuale impostazione di cultura. Questo è il motivo per cui tutte le mie cose provengono da proprietà del presentatore. – Jay

5

Questo è piuttosto una vecchia questione, ma credo che questa sia la migliore soluzione attuale (se si vuole modificare il testo).

È possibile farlo con un InlineUIContainer in un TextBlock con uno Textbox nidificato.

Nota: ho utilizzato BaselineAlignment="Center" per allineare i componenti. È anche possibile aggiungere margini positivi o negativi allo TextBox secondo necessità. Inoltre, ho impostato il bordo dello TextBox come trasparente per farlo sembrare parte dello TextBlock anche se è modificabile e selezionabile.

<TextBlock Foreground="SteelBlue"> 
    <Run Text="Package Barcode:" FontWeight="Bold" BaselineAlignment="Center"/> 
    <InlineUIContainer BaselineAlignment="Center"> 
     <TextBox Margin="2,0,0,0" Foreground="Gray" Text="{Binding BarcodeNumber}" BorderThickness="0" Padding="0"/> 
    </InlineUIContainer> 
</TextBlock> 
+1

sì, mi rendo conto che l'intervistatore originale alla fine voleva che l '"età" fosse di sola lettura - ma questa è una risposta alla domanda così come è stata posta :-) –

1

Questo è come un precedente risposta - (ma sono tutte con Texblocks ... ecco una versione Casella di testo), ho anche voluto mostrare l'approccio MultiBinding. Per ottenere un texbox di fare ciò che si desidera, è possibile utilizzare il seguente codice:

<TextBox> 
<TextBox.Text> 
    <MultiBinding StringFormat="Age {0} yrs and {1} months"> 
    <Binding Path="Years" /> 
    <Binding Path="Months" /> 
    </MultiBinding> 
</TextBox.Text> 
</TextBox> 

Può essere utile se si desidera rendere il testo selezionabile in modo che un utente può copiare il codice.