2010-05-07 6 views
2

J'ai une propriété de datattype ENUM: commeAttribuer propriété ENUM en XAML en utilisant silverlight

public BreakLevel Level 
{ 
    get { return level; } 
    set { level = value; } 
} 

Et ENUM défini:

public enum BreakLevel 
    { 
     Warning, Fatal 
    } 

Je veux lier la propriété Neum à la visibilité de ma frontière, un peu comme ceci:

Visibilité = "{Binding BreakLevel.Fatal}" est-ce possible?

<Border CornerRadius="4" BorderThickness="1" BorderBrush="#DAE0E5" 
Visibility="{Binding DataContext.IsError, Converter={StaticResource BoolToVisibilityConverter}, RelativeSource={RelativeSource TemplatedParent}}" > 
+0

C'est amusant comment des questions de nature similaire semblent arriver comme des bus. Voir ma réponse à une autre question très récente http://stackoverflow.com/questions/2787725/how-to-display-different-enum-icons-using-xaml-only/2789422#2789422 – AnthonyWJones

Répondre

3

Je pense que vous pouvez simplement créer un BreakLevelToVisibilityConverter et lier tout comme l'exemple que vous avez fourni.

Je suppose que le DataContext de votre bordure est défini sur une instance d'une classe qui a une propriété de type 'BreakLevel' (nous appellerons cette propriété 'BreakLvlProperty').

Le code ci-dessous montre alors la frontière si la valeur de BreakLvlProperty est BreakLevel.Fatal

Converter:

public class BreakLevelToVisibilityConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     if ((BreakLevel)value == BreakLevel.Fatal) 
      return Visibility.Visible; 
     else 
      return Visibility.Hidden; 
    } 

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

XAML:

<TopLevelWindowOrControl.Resources> 
    <local:BreakLevelToVisibilityConverter x:Key="BreakLevelToVisibilityConverter" /> 
</TopLevelWindowOrControl.Resources> 

<Border Visibility="{Binding Path=BreakLvlProperty, Converter={StaticResource BreakLevelToVisibilityConverter}" /> 
+0

Hey scott merci mon exemple m'a aidé à Résoudre le problème des mines :) – Malcolm

4

Scott a une bonne réponse à la question réelle, mais c'est toujours une bonne idée de se demander "Comment pourrais-je besoin code comme cela dans le futur? Comment puis-je éviter creati Encore une autre classe et réutilise plutôt ce que j'ai déjà? ".

Voici une variante plus générale de la solution de Scott: -

public class EnumToVisibilityConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     if (Enum.GetName(value.GetType(), value).Equals(parameter)) 
      return Visibility.Visible; 
     else 
      return Visibility.Hidden; 
    } 

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

Xaml: -

<TopLevelWindowOrControl.Resources> 
    <local:EnumToVisibilityConverter x:Key="EnumToVisibilityConverter" /> 
</TopLevelWindowOrControl.Resources> 

<Border Visibility="{Binding Path=BreakLvlProperty, Converter={StaticResource EnumToVisibilityConverter}, ConverterParameter=Fatal" /> 

Dans cette approche, nous pouvons convertisseur tout ENUM à une valeur de visibilité en utilisant le ConverterParameter spécifier la valeur enum (sous forme de chaîne) qui constitue l'état "Visible".

Il est tentant d'aller plus loin pour permettre que plus d'une valeur d'énumération soit assimilée à "Visible". Cependant, actuellement, le code n'est pas beaucoup plus compliqué que la mise en œuvre plus spécifique de Scott. Par conséquent, cette amélioration devrait être laissée jusqu'au besoin.

+0

Intéressant vous avez mentionné cet Anthony!Je refaisais juste une partie de mon propre code après avoir écrit cette réponse et fait quelque chose de très similaire à votre réponse (je lie la visibilité à une classe au lieu d'une énumération). Au lieu de définir le paramètre ConverterParameter sur une chaîne représentant l'enum, je l'ai défini sur le type réel: {x: Tapez local: MyClassType}. Mon convertisseur: if ((paramètre en Type) .IsInstanceOfType (valeur)) renvoie Visibility.Visible sinon retourne Visibility.Hidden. Savez-vous s'il existe un bon moyen d'imposer l'utilisation de ConverterParameter au moment du design? – Scott

+0

@Scott: Tout d'abord, Silverlight prend en charge 'x: Type' de sorte que les choses commencent par le début. Il n'y a aucun moyen de "faire respecter" l'utilisation de toute propriété dans Silverlight au moment de la conception, je ne peux même pas imaginer comment une telle "mise en application" pourrait fonctionner. Le plus proche que vous obtiendriez est une erreur de compilation. Malheureusement, Silverlight est connu pour ses erreurs d'exécution lorsque le Xaml est clairement dans l'erreur, il provoque de nombreux développeurs à demander "Pourquoi est-ce pas ramassé au moment de la compilation?". – AnthonyWJones

+0

@Anthony: Merci pour la réponse! (Je ne savais même pas que c'était pour Silverlight ... lol ... je suis un gars de WPF). Je ne pensais pas qu'il y avait un moyen d'appliquer le paramètre ... mais je voulais juste vérifier si vous en connaissiez. En ce moment je vérifie si c'est nul et si c'est ('est Type') et sinon, je jette une exception d'argument dans mon convertisseur. Je ne sais pas si c'est une bonne pratique ou pas, mais je pense que cela aidera à trouver l'erreur plus tôt que plus tard si elle est utilisée par de futurs développeurs sur mon code. Merci encore! – Scott

0
public class EnumToVisibilityConvertor : IValueConverter 
{ 
    private bool chk; 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     if ((value != null) && (value is BreakLevel) && (targetType == typeof(Visibility))) 
     { 
      chk = ((((BreakLevel) value) == (BreakLevel) Enum.Parse(typeof (BreakLevel), parameter.ToString(), true))); 
      return (chk==true) ? Visibility.Visible : Visibility.Collapsed; 
     } 

     throw new InvalidOperationException("Invalid converter usage."); 
    } 

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

    } 
} 





     <Border CornerRadius="4" BorderThickness="1" BorderBrush="#DAE0E5" 
Visibility="{Binding Path=Level, Converter={StaticResource enumToVisibilityConvertor},ConverterParameter=Fatal}" > 
+0

Certainement c'est plus de ceintures et d'accolades que mon approche. Cependant, vous n'avez vraiment pas besoin de 'chk' comme champ ou même comme variable. Vous n'avez pas besoin de comparer une valeur booléenne avec == true. Lok 'chk' et le ternaire fonctionnent? : et utilisez un simple if..else à la place. – AnthonyWJones

0

Je sais qu'il est un peu vieille question, mais vous tous concentré sur les convertisseurs et il y a beaucoup mieux (à mon avis) façon de le faire sans impliquer le code-behind:

<ContentControl> 
     <ContentControl.Template> 
      <ControlTemplate> 
       <Grid> 
        <!-- Here is the border which will be shown if Object.Level has value Fatal --> 
        <Border x:Name="PART_Border" 
         Visibility="Collapsed" 
         BorderThickness="3" BorderBrush="Red" 
         CornerRadius="4"> 
        </Border> 
        <TextBlock>Interiors of the border</TextBlock> 
       </Grid> 
       <ControlTemplate.Triggers> 
        <!-- This is the code which turns on border's visibility --> 
        <DataTrigger Binding="{Binding Level}" Value="{x:Static local:BreakLevel.Fatal}"> 
         <Setter TargetName="PART_Border" Property="Visibility" Value="Visible" /> 
        </DataTrigger> 
       </ControlTemplate.Triggers> 
      </ControlTemplate> 
     </ContentControl.Template> 
    </ContentControl> 

Je suppose que dans DataContext résiste à un objet qui a une propriété Level qui est de votre type BreakLevel.

Questions connexes