Question How to set a Binding with a specific value of Enum to Ellipse in code behind?

Elad770

Member
Joined
Oct 4, 2021
Messages
20
Programming Experience
1-3
Hello, I have an Enum of statuses and I want to color an Ellipse according to a certain status value.
The solution I made is to create a binding in the code according to the variable of the Enum and with Converter I check the status and then return the appropriate color.
The problem with this is that I have many values of statuses in the Enum and I don't want the converter to be activated on every change of status, I want it to be activated on two specific statuses only.
I have several threads in the program that run and update the status every time.
I saw all kinds of solutions on Stack OverFlow but quite complex and they are not exactly related to my problem.

C#:
//Enum Status
public enum Status
{
     CREATION,
     COLLECTION,
     BRANCH_STORAGE,
     HUB_TRANSPORT,
     HUB_STORAGE,
     BRANCH_TRANSPORT,
     DELIVERY,
     DISTRIBUTION,
     DELIVERED
}

//in code behind of MainWindow
public Ellipse CreateBindingEllipse(Package pack)
{
   Ellipse el = new Ellipse();
   bool isEllipeDown = true;
   el.SetBinding(Ellipse.FillProperty, new Binding()
                     {
                        Source = pack,
                        Converter = new PackageElipseConverter(),
                        UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
                        //this is work well
                        Path = new PropertyPath("Status"),
                        ////---- I'm want make like Status.CREATION or Status.DELIVERED
                        //but not working
                        ConverterParameter = isEllipeDown
                    });
     return el;
}

//Converter
 internal class PackageElipseConverter : IValueConverter
 {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
       
            bool isEllipeDown = bool.Parse(parameter.ToString());
            Status sta = (Status)Enum.Parse(typeof(Status), value.ToString());
            if (isEllipeDown && sta==Status.DELIVERED || !isEllipeDown && sta == Status.CREATION)
            {
                return (SolidColorBrush)new BrushConverter().ConvertFrom("#B00000");
            }
            return (SolidColorBrush)new BrushConverter().ConvertFrom("#fc9595");
        }

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

//Class Package which contains property Status
//and threads update this Status during the program
using PropertyChanged;
public abstract class Package: INotifyPropertyChanged
{
        public int PackageID { get; }
        static int count = 1000;
     
        public Address SenderAddress { set; get; }
        public Address DestinationAddress { set; get; }
        public Priority Priority { set; get; }
        public ObservableCollection<Tracking> Tracking { get; }
        public Status Status { set; get; }
}
 
Last edited:
Ummm... But that is the nature of the WPF converters. The view needs to render or update. If it it sees a converter associated with a bound element, and the view got a notification that the bound value has changed, it has no recourse but to ask the converter for what the appropriate value to be displayed should be.

If the reason why you don't want your converter to be called often is because of all the memory allocations (and subsequent pauses due to garbage collection), then you should implement some form of caching within your converter. For example, in your code above, you seem to keep on creating new brush converter and each of those converters seem to create new brushes each time.
 
Anyway, regarding your specific problem: set a breakpoint on your line 40. Then step through the code and examine the values of your variables and see if it is running the lines you expect to be executed.

As a quick aside, as I recall, the AND and OR operators have equal precedences so your booleans on line 42 will be evaluated from left to right. If you want a different order of evaluation, you'll need to to put parentheses where appropriate.
 
My recollection was incorrect. AND has higher precedence than OR.

 
Ummm... But that is the nature of the WPF converters. The view needs to render or update. If it it sees a converter associated with a bound element, and the view got a notification that the bound value has changed, it has no recourse but to ask the converter for what the appropriate value to be displayed should be.

If the reason why you don't want your converter to be called often is because of all the memory allocations (and subsequent pauses due to garbage collection), then you should implement some form of caching within your converter. For example, in your code above, you seem to keep on creating new brush converter and each of those converters seem to create new brushes each time.
Regarding the condition, the way I wrote the conditions it should be exactly like this.
Regarding what you said that I assign on every change, are you suggesting that I keep 2 variables in the class? Instead of doing 'new' every time?
The question that came to my mind now, is every time the converter is turned on, am I really reinitializing its status behind the scenes? Or as soon as I defined the binding at the beginning (the first time) then it is considered static and therefore really the ideal solution is to really define 2 variables in the class that will hold the appropriate color.
 
Yes, have two variables in the converter to only create the brush if it hasn't been created yet, otherwise return the previously created brush.

If you set a breakpoint on the converter, you'll get the answers to your questions about how often it is called, and whether it is called whenever the status changes.
 
Back
Top Bottom