private static object CoerceSelectedValue(DependencyObject d, object baseValue) { NativeComboBox cb = (NativeComboBox)d; if (cb._selectionChangeIsOnIndex || cb._selectionChangeIsOnItem) { // If we're in the middle of a selection change (SelectedIndex // or SelectedItem), accept the value. return(baseValue); } else { // Otherwise, this is a user-initiated change to SelectedValue. // Find the corresponding item. int index; object item = cb.FindItemWithValue(baseValue, out index); // if the search fails, coerce the value to null. Unless there // are no items at all, in which case wait for the items to appear // and search again. if (item == DependencyProperty.UnsetValue && cb.Items.Count > 0) { baseValue = null; } // Store the new selected item so we don't have to look for it again // in OnSelectedValueChanged. cb._selectionInfo = new SelectionInfo(item == DependencyProperty.UnsetValue ? null : item, index); } return(baseValue); }
private static void OnDisplayMemberPathChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { NativeComboBox cb = (NativeComboBox)d; // Refresh the combobox cb.Refresh(); }
private static void OnSelectedValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { NativeComboBox cb = (NativeComboBox)d; // we only want to change the other ones if the change comes from // SelectedItem (otherwise it's already done by the one that was // originally changed (SelectedIndex or SelectedValue) if (!cb._selectionChangeIsOnItem && !cb._selectionChangeIsOnIndex) { cb._selectionChangeIsOnValue = true; try { cb.SetCurrentValue(NativeComboBox.SelectedIndexProperty, cb._selectionInfo.Index); // Note: always update the value of SelectedItem last when // synchronizing selection properties, so that all the properties // are up to date when the selection changed event is fired. cb.SetCurrentValue(NativeComboBox.SelectedItemProperty, cb._selectionInfo.Item); } finally { cb._selectionChangeIsOnValue = false; cb._selectionInfo = null; } } }
private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { NativeComboBox cb = (NativeComboBox)d; IEnumerable newValue = (IEnumerable)e.NewValue; if (e.NewValue != null) { // ItemsSource is non-null. Go to ItemsSource mode cb.Items.SetItemsSource(newValue); } else { // ItemsSource is explicitly null. Return to normal mode. cb.Items.ClearItemsSource(); } cb.SetCurrentValue(NativeComboBox.SelectedIndexProperty, -1); }
private static object CoerceSelectedItem(DependencyObject d, object baseValue) { NativeComboBox cb = (NativeComboBox)d; if (baseValue == null || cb.SkipCoerceSelectedItemCheck) { return(baseValue); } int selectedIndex = cb.SelectedIndex; if ((selectedIndex > -1 && selectedIndex < cb.Items.Count && cb.Items[selectedIndex] == baseValue) || cb.Items.Contains(baseValue)) { return(baseValue); } return(DependencyProperty.UnsetValue); // reset baseValue to old value. }
private static object CoerceSelectedIndex(DependencyObject d, object baseValue) { NativeComboBox cb = (NativeComboBox)d; int index = (int)baseValue; if (index < 0) { return(-1); } else if (index >= cb.Items.Count) { return(cb.Items.Count - 1); } else { return(index); } }
private static void OnSelectedValuePathChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { NativeComboBox cb = (NativeComboBox)d; cb._selectionChangeIsOnItem = true; cb._selectionChangeIsOnIndex = true; try { object item = null; if (cb.SelectedItem != null) { item = PropertyPathHelper.AccessValueByApplyingPropertyPathIfAny(cb.SelectedItem, (string)e.NewValue); } cb.SetCurrentValue(NativeComboBox.SelectedValueProperty, item); } finally { cb._selectionChangeIsOnItem = false; cb._selectionChangeIsOnIndex = false; } }
private static void OnSelectedItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { NativeComboBox cb = (NativeComboBox)d; object newValue = e.NewValue; // we only want to change the other ones if the change comes from // SelectedItem (otherwise it's already done by the one that was // originally changed (SelectedIndex or SelectedValue) if (!cb._selectionChangeIsOnValue && !cb._selectionChangeIsOnIndex) { cb._selectionChangeIsOnItem = true; try { if (newValue == null) { // we use SetCurrentValue to preserve any potential bindings. cb.SetCurrentValue(NativeComboBox.SelectedValueProperty, null); cb.SetCurrentValue(NativeComboBox.SelectedIndexProperty, -1); } else { // we use SetCurrentValue to preserve any potential bindings. cb.SetCurrentValue(NativeComboBox.SelectedValueProperty, PropertyPathHelper.AccessValueByApplyingPropertyPathIfAny(newValue, cb.SelectedValuePath)); cb.SetCurrentValue(NativeComboBox.SelectedIndexProperty, cb.Items.IndexOf(newValue)); } } finally { cb._selectionChangeIsOnItem = false; } } // Raise the selection changed event cb.OnSelectionChanged(e.OldValue, e.NewValue); }
private static void OnSelectedIndexChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { NativeComboBox cb = (NativeComboBox)d; int newValue = (int)e.NewValue; if (!cb._changingSelectionInHtml) { cb._changingSelectionProgrammatically = true; try { cb.SetSelectedIndexInNativeHtmlDom(newValue); } finally { cb._changingSelectionProgrammatically = false; } } // we only want to change the other ones if the change comes from // SelectedIndex (otherwise it's already done by the one that was // originally changed (SelectedItem or SelectedValue) if (!cb._selectionChangeIsOnValue && !cb._selectionChangeIsOnItem) { cb._selectionChangeIsOnIndex = true; try { if (newValue == -1) { // Note : we use SetCurrentValue to preserve any potential bindings. cb.SetCurrentValue(NativeComboBox.SelectedValueProperty, null); // Skip the call to Items.IndexOf() cb.SkipCoerceSelectedItemCheck = true; try { // Note: always update the value of SelectedItem last when // synchronizing selection properties, so that all the properties // are up to date when the selection changed event is fired. cb.SetCurrentValue(NativeComboBox.SelectedItemProperty, null); } finally { cb.SkipCoerceSelectedItemCheck = false; } } else { object item = cb.Items[newValue]; // Note : we use SetCurrentValue to preserve any potential bindings. cb.SetCurrentValue(NativeComboBox.SelectedValueProperty, PropertyPathHelper.AccessValueByApplyingPropertyPathIfAny(item, cb.SelectedValuePath)); // Skip the call to Items.IndexOf() cb.SkipCoerceSelectedItemCheck = true; try { // Note: always update the value of SelectedItem last when // synchronizing selection properties, so that all the properties // are up to date when the selection changed event is fired. cb.SetCurrentValue(NativeComboBox.SelectedItemProperty, item); } finally { cb.SkipCoerceSelectedItemCheck = false; } } } finally { cb._selectionChangeIsOnIndex = false; } } }