/// <summary> /// Returns a stream of weighted values based on a percentage. /// </summary> /// <param name="values">A sequence of values.</param> /// <param name="percent">The percentage of values.</param> /// <returns>A sequence of percentages.</returns> public static IEnumerable <double> GetWeightedValues(this IEnumerable <double> values, double percent) { double total = values.Sum(); if (total == 0) { return(values.Select(_ => 0.0)); } return (EnumerableFunctions .Zip( values.Scan((acc, current) => acc + current, 0.0), values, (acc, current) => Tuple.Create(acc, current)) .Select(tuple => Tuple.Create(tuple.First / total, tuple.Second / total)) .Select(tuple => { double accumulated = tuple.First; double current = tuple.Second; if (percent > accumulated && accumulated + current > percent) { return (percent - accumulated) * total; } else if (percent <= accumulated) { return 0.0; } else { return 1.0; } })); }
/// <summary> /// Updates the values of the rating items. /// </summary> private void UpdateValues() { IList <RatingItem> ratingItems = GetRatingItems().ToList(); RatingItem oldSelectedItem = this.GetSelectedRatingItem(); IEnumerable <Tuple <RatingItem, double> > itemAndWeights = EnumerableFunctions .Zip( ratingItems, ratingItems .Select(ratingItem => 1.0) .GetWeightedValues(Value.GetValueOrDefault()), (item, percent) => Tuple.Create(item, percent)); foreach (Tuple <RatingItem, double> itemAndWeight in itemAndWeights) { itemAndWeight.First.Value = itemAndWeight.Second; } RatingItem newSelectedItem = this.GetSelectedRatingItem(); // Notify when the selection changes if (oldSelectedItem != newSelectedItem) { if (newSelectedItem != null && AutomationPeer.ListenerExists(AutomationEvents.SelectionItemPatternOnElementSelected)) { AutomationPeer peer = FrameworkElementAutomationPeer.CreatePeerForElement(newSelectedItem); if (peer != null) { peer.RaiseAutomationEvent(AutomationEvents.SelectionItemPatternOnElementSelected); } } if (oldSelectedItem != null && AutomationPeer.ListenerExists(AutomationEvents.SelectionItemPatternOnElementRemovedFromSelection)) { AutomationPeer peer = FrameworkElementAutomationPeer.CreatePeerForElement(oldSelectedItem); if (peer != null) { peer.RaiseAutomationEvent(AutomationEvents.SelectionItemPatternOnElementRemovedFromSelection); } } } if (HoveredRatingItem == null) { DisplayValue = Value.GetValueOrDefault(); } }
/// <summary> /// Updates the value and actual value of the rating items. /// </summary> private void UpdateDisplayValues() { IList <RatingItem> ratingItems = GetRatingItems().ToList(); IEnumerable <Tuple <RatingItem, double> > itemAndWeights = EnumerableFunctions .Zip( ratingItems, ratingItems .Select(ratingItem => 1.0) .GetWeightedValues(DisplayValue), (item, percent) => Tuple.Create(item, percent)); RatingItem selectedItem = null; Tuple <RatingItem, double> selectedItemAndWeight = itemAndWeights.LastOrDefault(i => i.Second > 0.0); if (selectedItemAndWeight != null) { selectedItem = selectedItemAndWeight.First; } else { selectedItem = GetSelectedRatingItem(); } foreach (Tuple <RatingItem, double> itemAndWeight in itemAndWeights) { if (SelectionMode == RatingSelectionMode.Individual && itemAndWeight.First != selectedItem) { itemAndWeight.First.DisplayValue = 0.0; } else { itemAndWeight.First.DisplayValue = itemAndWeight.Second; } } }