/// <summary> /// This method prepares a container to host an item. /// </summary> /// <param name="element">The container.</param> /// <param name="item">The item hosted in the container.</param> protected override void PrepareContainerForItemOverride(DependencyObject element, object item) { RatingItem ratingItem = (RatingItem)element; object defaultForegroundValue = ratingItem.ReadLocalValue(Control.ForegroundProperty); if (defaultForegroundValue == DependencyProperty.UnsetValue) { ratingItem.SetBinding(Control.ForegroundProperty, new Binding("Foreground") { Source = this }); } ratingItem.IsReadOnly = this.IsReadOnly; if (ratingItem.Style == null) { ratingItem.Style = this.ItemContainerStyle; } ratingItem.Click += RatingItemClick; ratingItem.MouseEnter += RatingItemMouseEnter; ratingItem.MouseLeave += RatingItemMouseLeave; ratingItem.ParentRating = this; base.PrepareContainerForItemOverride(element, item); }
/// <summary> /// This method is raised when a rating item value is selected. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">Information about the event.</param> private void RatingItemClick(object sender, RoutedEventArgs e) { if (!this.IsReadOnly) { RatingItem item = (RatingItem)sender; OnRatingItemValueSelected(item, 1.0); } }
/// <summary> /// IsReadOnlyProperty property changed handler. /// </summary> /// <param name="d">RatingItem that changed its IsReadOnly.</param> /// <param name="e">Event arguments.</param> private static void OnIsReadOnlyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { RatingItem source = (RatingItem)d; bool oldValue = (bool)e.OldValue; bool newValue = (bool)e.NewValue; source.OnIsReadOnlyChanged(oldValue, newValue); }
/// <summary> /// This method is invoked when the rating item value is changed. /// </summary> /// <param name="ratingItem">The rating item that has changed.</param> /// <param name="newValue">The new value.</param> protected virtual void OnRatingItemValueSelected(RatingItem ratingItem, double newValue) { List <RatingItem> ratingItems = GetRatingItems().ToList(); double total = ratingItems.Count(); double value = (ratingItems .Take(ratingItems.IndexOf(ratingItem)) .Count() + newValue) / total; this.Value = value; }
/// <summary> /// Selects a rating item. /// </summary> /// <param name="selectedRatingItem">The selected rating item.</param> internal void SelectRatingItem(RatingItem selectedRatingItem) { if (!this.IsReadOnly) { IList <RatingItem> ratingItems = GetRatingItems().ToList(); IEnumerable <double> weights = ratingItems.Select(ratingItem => 1.0); double total = ratingItems.Count(); double percent; if (total != 0) { percent = weights.Take(ratingItems.IndexOf(selectedRatingItem) + 1).Sum() / total; this.Value = percent; } } }
/// <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> /// This method clears a container used to host an item. /// </summary> /// <param name="element">The container that hosts the item.</param> /// <param name="item">The item hosted in the container.</param> protected override void ClearContainerForItemOverride(DependencyObject element, object item) { RatingItem ratingItem = (RatingItem)element; ratingItem.Click -= RatingItemClick; ratingItem.MouseEnter -= RatingItemMouseEnter; ratingItem.MouseLeave -= RatingItemMouseLeave; ratingItem.ParentRating = null; if (ratingItem == HoveredRatingItem) { HoveredRatingItem = null; UpdateDisplayValues(); UpdateHoverStates(); } base.ClearContainerForItemOverride(element, item); }
/// <summary> /// Gets a rating item at a certain index offset from another /// rating item. /// </summary> /// <param name="ratingItem">The rating item.</param> /// <param name="offset">The rating item at an offset from the /// index of the rating item.</param> /// <returns>The rating item at the offset.</returns> private RatingItem GetRatingItemAtOffsetFrom(RatingItem ratingItem, int offset) { IList <RatingItem> ratingItems = GetRatingItems().ToList(); int index = ratingItems.IndexOf(ratingItem); if (index == -1) { return(null); } index += offset; if (index >= 0 && index < ratingItems.Count) { ratingItem = ratingItems[index]; } else { ratingItem = null; } return(ratingItem); }
/// <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; } } }
/// <summary> /// Updates the hover states of the rating items. /// </summary> private void UpdateHoverStates() { if (HoveredRatingItem != null && !IsReadOnly) { IList <RatingItem> ratingItems = GetRatingItems().ToList(); int indexOfItem = ratingItems.IndexOf(HoveredRatingItem); double total = ratingItems.Count(); double filled = indexOfItem + 1; this.DisplayValue = filled / total; for (int cnt = 0; cnt < ratingItems.Count; cnt++) { RatingItem ratingItem = ratingItems[cnt]; if (cnt <= indexOfItem && this.SelectionMode == RatingSelectionMode.Continuous) { VisualStates.GoToState(ratingItem, true, VisualStates.StateMouseOver); } else { IUpdateVisualState updateVisualState = (IUpdateVisualState)ratingItem; updateVisualState.UpdateVisualState(true); } } } else { this.DisplayValue = this.Value.GetValueOrDefault(); foreach (IUpdateVisualState updateVisualState in GetRatingItems().OfType <IUpdateVisualState>()) { updateVisualState.UpdateVisualState(true); } } }
protected override void OnKeyDown(KeyEventArgs e) { if (!Interaction.AllowKeyDown(e)) { return; } base.OnKeyDown(e); if (e.Handled) { return; } switch (e.Key) { case Key.Left: { #if SILVERLIGHT RatingItem ratingItem = FocusManager.GetFocusedElement() as RatingItem; #else RatingItem ratingItem = FocusManager.GetFocusedElement(Application.Current.MainWindow) as RatingItem; #endif if (ratingItem != null) { ratingItem = GetRatingItemAtOffsetFrom(ratingItem, -1); } else { ratingItem = GetRatingItems().FirstOrDefault(); } if (ratingItem != null) { if (ratingItem.Focus()) { e.Handled = true; } } } break; case Key.Right: { #if SILVERLIGHT RatingItem ratingItem = FocusManager.GetFocusedElement() as RatingItem; #else RatingItem ratingItem = FocusManager.GetFocusedElement(Application.Current.MainWindow) as RatingItem; #endif if (ratingItem != null) { ratingItem = GetRatingItemAtOffsetFrom(ratingItem, 1); } else { ratingItem = GetRatingItems().FirstOrDefault(); } if (ratingItem != null) { if (ratingItem.Focus()) { e.Handled = true; } } } break; case Key.Add: { if (!this.IsReadOnly) { RatingItem ratingItem = GetSelectedRatingItem(); if (ratingItem != null) { ratingItem = GetRatingItemAtOffsetFrom(ratingItem, 1); } else { ratingItem = GetRatingItems().FirstOrDefault(); } if (ratingItem != null) { ratingItem.SelectValue(); e.Handled = true; } } } break; case Key.Subtract: { if (!this.IsReadOnly) { RatingItem ratingItem = GetSelectedRatingItem(); if (ratingItem != null) { ratingItem = GetRatingItemAtOffsetFrom(ratingItem, -1); } if (ratingItem != null) { ratingItem.SelectValue(); e.Handled = true; } } } break; } }
/// <summary> /// DisplayValueProperty property changed handler. /// </summary> /// <param name="d">RatingItem that changed its DisplayValue.</param> /// <param name="e">Event arguments.</param> private static void OnDisplayValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { RatingItem source = (RatingItem)d; source.OnDisplayValueChanged((double)e.OldValue, (double)e.NewValue); }