简体   繁体   中英

Assign enum property in xaml using silverlight

I have a property of datattype enum : like

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

And enum defined :

  public enum BreakLevel
    {
        Warning, Fatal
    }

I want bind the neum property to the visibility of my border , somewhat like this:

Visibility="{Binding BreakLevel.Fatal}" so is it possible?

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

Scott has a good answer to the actual question, however its always a good idea to ask yourself "How might I need code like this in the future? How can I avoid creating yet another class and instead re-use what I have already got?".

Here is a more general variation of Scott's solution:-

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" />

In this approach we can converter any enum to a Visibility value by using the ConverterParameter to specify the enum value (in string form) that constitute the "Visible" state.

Its tempting to take this further to allow more than one enum value to be equated to "Visible". However currently the code isn't much more complicated than Scott's more specific implementation. Hence this enhancement should be left until needed.

I think you can just create a BreakLevelToVisibilityConverter and bind just like the example you provided.

I'm assuming that the DataContext of your border is set to an instance of a class that has a property of type 'BreakLevel' (we'll call this property 'BreakLvlProperty').

The code below will then show the border if the value of BreakLvlProperty is 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}" />

I know it's a bit old question but all of you focused on converters and there's much better (in my opinion) way of doing it without involving 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>

I assumed that in DataContext resists an object which has a property Level which is of your BreakLevel type.

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}" >

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM