Breaking the Recursive NotifyOfPropertyChange()

Another problem I ran into in the WPF world were controls whose side effects led to a endless loop of updates:


The outer one is called an “Order”, and the inner one is called a “Trade”

The problem goes like this:

  • Click on the outer one to select everything
    • Inner ones turn on
    • But clicking an inner one, if all of them are turned on
      • selects the Outer one.
        • recursive loop to infinity.

There’s probably some really crazy way to set this stuff up (there seems to be no end of the kind of hoops people will jump through for WPF), but here was my solution:

        private bool _onOrderCheckedFiring; 

        private void OrderChecked(CheckBoxListItemThreeState<OrderListItem> obj)
            if (_onTradeCheckedFiring) return; // we are a result of a trade check, so don't do anything.
                _onOrderCheckedFiring = true;
                foreach (var t in obj.Value.AllTrades)
                    t.IsChecked = true;
                _onOrderCheckedFiring = false;
        protected virtual void OnTradeChecked(CheckBoxListItem<HoldingBase> item)
            if (_onOrderCheckedFiring) return; // result of order check, so don't do any more logic. 
                _onTradeCheckedFiring = true;
                var theOrder = Orders.FirstOrDefault(o => o.Value.Order.OrderID == item.Value.OrderID);
                if (theOrder != null)
                    var areAllTradesChecked = theOrder.Value.AreAllTradesChecked;
                    var newState = theOrder.IsChecked;

                    if (areAllTradesChecked)
                        //all trades are checked; set the order checkbox to true
                        newState = true;
                    else if (theOrder.Value.AreAnyTradesChecked)
                        //not all trades are checked, but some are; set the order checkbox to indeterminate
                        newState = null;
                    else if (!theOrder.Value.AreAnyTradesChecked)
                        //no trades are checked; set the order checkbox to false
                        newState = false;

                    // ReSharper disable RedundantCheckBeforeAssignment
                    //NO, ReShaper, this is NOT a redundant check, because if the value is the same, I don't
                    //  want the notification events firing.
                    if (theOrder.IsChecked != newState)
                        // ReSharper restore RedundantCheckBeforeAssignment

                        theOrder.IsChecked = newState;

            } finally {
                _onTradeCheckedFiring = false;


This code is not complete, and it was reformatted to reduce the number of lines to paste.  Basically, I just flag that I’m doing something intricate in one routine, and in the other routine, I see if the intricateness is happening, and if so, I DO NOT fire the thing that would make it recursive.

I’m almost done with this WPF project, I’ll get to go back to the Web World probably next week.  Before I fully forget WPF, I would like to make a chart of all the stuff I’ve learned similar to what I did for MVC.

Tagged with: ,
Posted in Code

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

.net 3d 3d-printing 4k abc15 algorithms ames android anonymous types audio editing aws backup basecamp beatunes biorhythm bittorrent blender blog boston marathon bpm c# caffeine campfire candycrush car carmax certification charity chiropractor cities-skylines clog clone codelouisville codepalousa coding coffee collaboration color run ComputerElbow ComputerVision configuration consulting cooking crash course crashplan crestwood cryptocurrency cycling dabda dan dapper DataSet ddl diabetes dictation dotnetcore dotnetmud downtown e-cycling elite excel exercise expiration facebook feature-branching firefall flipflops Flow FL Studio focus food forecastle fortresscraft franklinplanner gadgets game-design games git github google docs google maps gopro gps grandpa greenshot hack half marathon headless health heart rate hiren ignew integration testing interop inventory ios ipad itunes javascript jobs karma kdf keyboards keys kittens lamont laptop lavalamp leaf lego life lifehack linq linqtotwitter linux los angeles louisville mandelbulber massage therapy mastery-teaching maths merge metformin Minecraft miniature modeling monitor mud muhammad ali institute music mvc mycartracks netfabb nexus10 node nomanssky nostalgia nutrition nwipe oldham county grand slam opal openjscad openscad owin pacedj paper mockup pepakura performance photoscan politics pomodoro postgresql powershell premiere priorities prius process product-management project-management qa ReFS resharper review rmi roman road 5k RSI rubiks running samsung 700t sandals schedule scooter scribblelive selenium service shapeways sleep slic3r sneakersync snot software software-engineering solidoodle soylent spacegame speaking sql sqlite SSDT SSIS standing state-machine stayfocusd stonehearth studying sunset tablet teaching team teamcity teamtreehouse terraform tesla testing tfs time timelapse torque touch tracks trs80 Tuple tutor twitter ubuntu unit testing utilities video video editing visual studio vscode vsvim warp stabilizer windows 8 windows home server wordpress wpf xml

Error: Twitter did not respond. Please wait a few minutes and refresh this page.

%d bloggers like this: