2009-03-22 12 views
1

Lors de la liaison avec Wpf, existe-t-il un moyen d'utiliser les fonctions System.String sans utiliser de convertisseurs?Lors de la liaison avec Wpf, existe-t-il un moyen d'utiliser les fonctions System.String sans utiliser de convertisseurs?

<TextBlock Text="({Binding Path=Text}).Trim()"/> 

c'est essentiellement mon désir.

+1

Je viens de réaliser que mon message est en C#. Vous appelez Trim sans parenthèse, utilisez-vous VB? Si oui, ajoutez un tag pour VB et je peux mettre à jour mon échantillon. – bendewey

+0

Dans l'avenir s'il vous plaît assurez-vous que les spécifications sont clairement énoncées dans la question, pas seulement dans le titre. – bendewey

+0

Je le ferai, merci. Je travaille avec VB et C#, mais ce poste était en effet VB puisque seul VB supporte les méthodes d'appel sans parenthèse. – Shimmy

Répondre

7

Je voudrais utiliser un convertisseur.

Reliure Xaml

<StackPanel> 
    <StackPanel.Resources> 
    <local:StringTrimmingConverter x:Key="trimmingConverter" /> 
    <StackPanel.Resources> 
    <TextBlock Text="{Binding Path=Text, Converter={StaticResource trimmingConverter}}" /> 
</StackPanel> 

StringTrimmingConverter.cs

using System; 
using System.Windows.Data; 

namespace WpfApplication1 
{ 
    [ValueConversion(typeof(string), typeof(string))] 
    public class StringTrimmingConverter : IValueConverter 
    { 
     #region IValueConverter Members 
     public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      return value.ToString().Trim(); 
     } 
     public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      return value; 
     } 
     #endregion 
    } 
} 

Et si VB StringTrimmingConverter.vb

Imports System.Globalization 

Public Class StringTrimmingConverter 
    Implements IValueConverter 

    Public Function ConvertBack(ByVal value As Object, ByVal targetType As Type, ByVal parameter As Object, ByVal culture As CultureInfo) As Object Implements IValueConverter.ConvertBack 
     Return value.ToString().Trim 
    End Function 

    Public Function Convert(ByVal value As Object, ByVal targetType As Type, ByVal parameter As Object, ByVal culture As CultureInfo) As Object Implements IValueConverter.Convert 
     Return value 
    End Function 

End Class 
+0

J'ai dit que je ne veux pas avoir de millions de convertisseurs, donc j'ai posé la question, j'ai commencé à traiter un convertisseur de chaîne ultime, regardez ci-dessous, dites-moi votre avis, à la recherche d'améliorations. Merci beaucoup quand même! – Shimmy

+0

Je ne sais pas pourquoi les gens ont tellement peur d'avoir un million de convertisseurs. Il suffit de les mettre dans un dossier et assurez-vous que leur nom bien. Cela s'inscrit parfaitement dans le principe du principe de responsabilité unique (PRS). – bendewey

+0

Je donno, je déteste personnellement, non seulement, mais, je mets tous mes convertisseurs dans un espace de noms «convertisseurs» et ils sont tous dans le même fichier. avec la navigation VS d'aujourd'hui Je n'ai aucun problème. de toute façon, merci pour votre message. – Shimmy

0

J'ai créé un convertisseur ultime pour toutes les fonctions de System.String, a besoin d'une certaine amélioration aimerait vous entendre, l'espoir de le mettre à jour à l'avenir, s'il vous plaît accepter:

<ValueConversion(GetType(String), GetType(String))> _ 
Class StringFunctions : Implements IValueConverter 
    Public Function Convert(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.Convert 
     If parameter Is Nothing OrElse Not TypeOf parameter Is String OrElse String.IsNullOrEmpty(parameter) Then Return Nothing 
     Dim parameters As New List(Of String)(parameter.ToString.Split(":"c)) 
     parameter = parameters(0) 
     parameters.RemoveAt(0) 
     If String.IsNullOrEmpty(parameter) Then Return value 

     Dim method = (From m In GetType(String).GetMethods _ 
       Where m.Name = parameter _ 
       AndAlso m.GetParameters.Count = parameters.Count).FirstOrDefault 
     If method Is Nothing Then Return value 
     Return method.Invoke(value, parameters.ToArray) 
    End Function 
    Public Function ConvertBack(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.ConvertBack 
     Throw New NotSupportedException 
    End Function 
End Class 

La dans la liaison, quand u utiliser un convertisseur vous avez une option pour passer un paramètre au convertisseur (Binding.ConverterParameter) passer tous vos paramètres séparés par: (deux points - vous pouvez le changer dans le paramètre délimiteur String.Split), tandis que le premier paramètre est le nom de la fonction, la fonction va compter les paramètres supplémentaires et essayer de le passer.
Je n'ai toujours pas travaillé sur l'adressage des paramètres, c'est une fonction superficielle.

Aimeriez-vous voir vos améliorations et notes.
merci. Shimmy

+0

Whoa! Utilisez la fonction de code dans l'éditeur pour garder votre code formaté. Fonctionne mieux si vous collez le code, puis appuyez sur le bouton. –

+0

Désolé je l'ai vu, il est maintenant formaté :) – Shimmy

+0

Je suggère de généraliser cela pour appeler une méthode sur n'importe quel type d'objet. Il n'y a rien de spécial à propos de l'utilisation de String.En fait, l'attribut "[ValueConversion (typeof (chaîne), typeof (chaîne))]" est déjà incorrect pour un appel à diviser car il ne renvoie pas de chaîne! –

0

Vous devrez utiliser un convertisseur pour transformer les données auxquelles votre contrôle est lié. Pour éviter d'écrire beaucoup de transformations simples, vous pouvez utiliser Dynamic Language Runtime et écrire des expressions dans votre langage de script DLR préféré (tel que Python, Ruby, etc.).

Voir my blog series pour un exemple de la façon d'y parvenir. Part 3 parle spécifiquement de ValueConverters.

1

J'ai créé un convertisseur ultime pour toutes les fonctions de System.String, a besoin d'une certaine amélioration aimerait vous entendre, l'espoir de le mettre à jour à l'avenir, s'il vous plaît accepter:

VB:

<ValueConversion(GetType(String), GetType(Object))> _ 
Class StringFunctions : Implements IValueConverter 
    Public Function Convert(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.Convert 
     If parameter Is Nothing OrElse Not TypeOf parameter Is String OrElse String.IsNullOrEmpty(parameter) Then Return Nothing 
     Dim parameters As New List(Of String)(parameter.ToString.Split(":"c)) 
     parameter = parameters(0) 
     parameters.RemoveAt(0) 
     If String.IsNullOrEmpty(parameter) Then Return value 

     Dim method = (From m In GetType(String).GetMethods _ 
       Where m.Name = parameter _ 
       AndAlso m.GetParameters.Count = parameters.Count).FirstOrDefault 
     If method Is Nothing Then Return value 
     Return method.Invoke(value, parameters.ToArray) 
    End Function 
    Public Function ConvertBack(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.ConvertBack 
     Return value.ToString() 
    End Function 
End Class 

C#: -convertis par un outil, ne comptez pas!

[ValueConversion(typeof(string), typeof(object))] 
public class StringConverter : IValueConverter 
{ 
    #region IValueConverter Members 

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     if (value == null) return null; 
     value = value.ToString(); 
     if (String.IsNullOrEmpty(value as string)) return ""; 
     if (parameter == null || !parameter is string || String.IsNullOrEmpty((string)parameter)) return value; 
     List<string> parameters = new List<string>(((string)parameter).Split(':')); 
     parameter = parameters[0]; 
     parameters.RemoveAt(0); 

     var method = (from m in typeof(String).GetMethods() 
         where m.Name== parameter 
         && m.GetParameters().Count()==parameters.Count 
          select m).FirstOrDefault(); 
     if (method == null) return value; 
     return method.Invoke(value, parameters.ToArray()); 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     return value; 
    } 

    #endregion 
} 

Xaml:

<TextBox Text="{Binding Path=String, Converter={StaticResource StringConverter}, ConverterParameter=Trim:Argument:AnotherArgument}" /> 

Puis, dans la fixation, lorsque u utiliser un convertisseur u ont la possibilité de passer un paramètre au convertisseur (Reliure.ConverterParameter) passe tous vos paramètres séparés par: (deux points - vous pouvez le changer dans le paramètre délimiteur String.Split), tandis que le premier paramètre est le nom de la fonction, la fonction comptera les paramètres supplémentaires et essaiera de la passer.
Je n'ai toujours pas travaillé sur l'adressage des paramètres, c'est une fonction superficielle.

Aimeriez-vous voir vos améliorations et notes.
merci. Shimmy

+0

Un peu en retard, mais je suis d'accord avec votre avis sur les convertisseurs. Vous ne devriez pas avoir à écrire 20 lignes (plus ou moins) afin qu'une seule ligne de fonctionnalité puisse être transmise au XAML –

0

Je sais que ce post est ancien, mais il est toujours le premier à apparaître lors de la recherche "WPF TextBox Binding Trim".

Je n'ai pas de réponse VB, mais n'utilisez pas de convertisseur.
Raisons:

  1. Un convertisseur signifie que vous devez ajouter du code XAML supplémentaire pour tous vos chaque fois la liaison XAML. Avoir toujours ajouter du code supplémentaire est tout aussi mauvais dans XAML que dans C#/VB.
  2. Cela vous empêchera de taper un espace si vous avez mis à jour UpdateSourceTrigger = PropertyChanged.

Utilisez la programmation orientée objet comme elle est censée être utilisée. Si vous avez besoin d'un TextBox découpé, créez un enfant de TextBox appelé TrimmedTextBox et utilisez-le. http://www.wpfsharp.com/2014/05/15/a-simple-trimmedtextbox-for-wpf/

C#

using System.Windows.Controls; 

namespace WpfSharp.UserControls 
{ 
    public class TrimmedTextBox : TextBox 
    { 
     public TrimmedTextBox() 
     { 
      LostFocus += TrimOnLostFocus; 
     } 

     void TrimOnLostFocus(object sender, System.Windows.RoutedEventArgs e) 
     { 
      var trimTextBox = sender as TrimmedTextBox; 
      if (trimTextBox != null) 
       trimTextBox.Text = trimTextBox.Text.Trim(); 
     } 
    } 
} 

VB (j'ai utilisé un convertisseur sur mon code C#)

Imports System.Windows.Controls 

Namespace WpfSharp.UserControls 
    Public Class TrimmedTextBox 
     Inherits TextBox 
     Public Sub New() 
      AddHandler LostFocus, AddressOf TrimOnLostFocus 
     End Sub 

     Private Sub TrimOnLostFocus(sender As Object, e As System.Windows.RoutedEventArgs) 
      Dim trimTextBox = TryCast(sender, TrimmedTextBox) 
      If trimTextBox IsNot Nothing Then 
       trimTextBox.Text = trimTextBox.Text.Trim() 
      End If 
     End Sub 
    End Class 
End Namespace 

Hope this helps. N'hésitez pas à utiliser cet objet comme s'il s'agissait d'un domaine public.