Bind Boolean And Visibility DPs To Relational Operators/Conditions In WPF/XAML

Posted by Ahmed Tarek Hasan on 1/13/2017 11:28:00 PM with No comments

Bind Boolean And Visibility DPs To Relational Operators/Conditions In WPF/XAML

All code and samples can be downloaded from this link.


While working on a WPF/XAML application, if you have needed to enable/disable or show/hide a control based on a conditional logic using relational operators (e.g: =, !=, >, >=, <, <=, .....), this post will help you.

I worked on a value converter which enables you to bind boolean and visibility dependency properties to conditional logic using relational operators.

Supported relational operators are:
  • Equal (=)
  • Not Equal (!=)
  • Greater Than (>)
  • Greater Than Or Equal (>=)
  • Less Than (<)
  • Less Than Or Equal (<=)
  • Between (a < b < c)
  • Between (a <= b < c)
  • Between (a < b <= c)
  • Between (a <= b <= c)
Converter Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
using System.Windows;

namespace DevelopmentSimplyPut.RelationalOperatorsConverter
{
    public class RelationalOperatorsToBoolConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            bool result = true;
            Double valueAsDouble;

            if (value != null && value is IComparable && Double.TryParse(value.ToString(), out valueAsDouble) && parameter != null && parameter is string && parameter.ToString().Contains('|'))
            {
                string[] parts = parameter.ToString().Split('|');

                if (parts.Length > 1)
                {
                    string relationalOperatorDescription = parts[0].Trim().ToLower();
                    Double firstOperand = Double.Parse(parts[1].Trim());
                    Double secondOperand = default(Double);

                    if (parts.Length > 2)
                    {
                        secondOperand = Double.Parse(parts[2].Trim());
                    }

                    switch (relationalOperatorDescription)
                    {
                        case "greater than":
                            //>
                            result = (valueAsDouble > firstOperand);
                            break;
                        case "less than":
                            //<
                            result = (valueAsDouble < firstOperand);
                            break;
                        case "greater than or equal":
                            //>=
                            result = (valueAsDouble >= firstOperand);
                            break;
                        case "less than or equal":
                            //<=
                            result = (valueAsDouble <= firstOperand);
                            break;
                        case "equal":
                            //==
                            result = (valueAsDouble == firstOperand);
                            break;
                        case "not equal":
                            //!=
                            result = (valueAsDouble != firstOperand);
                            break;
                        case "between1":
                            //x < y < z
                            if (parts.Length > 2)
                            {
                                result = (firstOperand < valueAsDouble && valueAsDouble < secondOperand);
                            }
                            break;
                        case "between2":
                            //x <= y <= z
                            if (parts.Length > 2)
                            {
                                result = (firstOperand <= valueAsDouble && valueAsDouble <= secondOperand);
                            }
                            break;
                        case "between3":
                            //x <= y < z
                            if (parts.Length > 2)
                            {
                                result = (firstOperand <= valueAsDouble && valueAsDouble < secondOperand);
                            }
                            break;
                        case "between4":
                            //x < y <= z
                            if (parts.Length > 2)
                            {
                                result = (firstOperand < valueAsDouble && valueAsDouble <= secondOperand);
                            }
                            break;
                    }
                }
            }

            return result;
        }

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

    public class RelationalOperatorsToVisibilityConverter : IValueConverter
    {
        private static RelationalOperatorsToBoolConverter converter = new RelationalOperatorsToBoolConverter(); 

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            Visibility result = Visibility.Visible;

            bool booleanResult = (bool)converter.Convert(value, targetType, parameter, culture);

            if (!booleanResult)
            {
                result = Visibility.Collapsed;
            }

            return result;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}
Usage:
xmlns:converters="clr-namespace:DevelopmentSimplyPut.RelationalOperatorsConverter;assembly=RelationalOperatorsConverter"
<Window.Resources>
 <converters:RelationalOperatorsToVisibilityConverter x:Key="RelationalOperatorsToVisibilityConverter" />
</Window.Resources>



<StackPanel Visibility="{Binding Path=SomeNumericalValueProperty, Converter={StaticResource RelationalOperatorsToVisibilityConverter}, ConverterParameter='equal|0'}" />


If you run the demo application included in the attached code samples, you will find the results below.










That's it. If you like this post you can leave a comment :)

Good luck.


Categories: , , , ,