protected override void AddChildItemToVisualTree(object newItem) { if (_useNativeComboBox) { object value = PropertyPathHelper.AccessValueByApplyingPropertyPathIfAny(newItem, DisplayMemberPath); //if (value is UIElement) //{ // SwitchToNonNativeComboBox(); // If the value is a UI element, we should switch to a non-native combo box: //} //else //{ if (value != null) { if (_nativeComboBoxDomElement != null) { var optionDomElement = INTERNAL_HtmlDomManager.AddOptionToNativeComboBox(_nativeComboBoxDomElement, value.ToString()); _itemContainerGenerator.INTERNAL_RegisterContainer(optionDomElement, newItem); } } //todo: else --> ? //} } else { base.AddChildItemToVisualTree(newItem); } }
protected virtual void ManageSelectedIndex_Changed(DependencyPropertyChangedEventArgs e) { // Note: in this method, we use "Convert.ToInt32()" intead of casting to "(int)" because otherwise the JS code is not compatible with IE 9 (or Windows Phone 8.0). //if (!AreObjectsEqual(e.OldValue, e.NewValue)) //{ int newValue = Convert.ToInt32(e.NewValue); if (newValue < Items.Count) //The new value is ignored if it is bigger or equal than the amount of elements in the list of Items. { if (!_selectionChangeIsOnValue && !_selectionChangeIsOnItem) //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) { object oldItem = SelectedItem; _selectionChangeIsOnIndex = true; if (newValue == -1) { SetLocalValue(SelectedItemProperty, null); //we call SetLocalvalue directly to avoid replacing the BindingExpression that could be here on Mode = TwoWay SetLocalValue(SelectedValueProperty, null); //we call SetLocalvalue directly to avoid replacing the BindingExpression that could be here on Mode = TwoWay //todo: update binding of SelectedIndex //selector.SelectedItem = null; //selector.SelectedValue = null; } else { object item = Items[newValue]; //todo: make sure that the index always corresponds (I think it does but I didn't check) SetLocalValue(SelectedItemProperty, item); //we call SetLocalvalue directly to avoid replacing the BindingExpression that could be here on Mode = TwoWay SetLocalValue(SelectedValueProperty, PropertyPathHelper.AccessValueByApplyingPropertyPathIfAny(item, SelectedValuePath)); //we call SetLocalvalue directly to avoid replacing the BindingExpression that could be here on Mode = TwoWay //todo: update binding of SelectedIndex //selector.SelectedItem = item; //selector.SelectedValue = selector.AccessValueByApplyingPropertyPathIfAny(item, selector.SelectedValuePath); } _selectionChangeIsOnIndex = false; List <object> oldItems = new List <object>(); oldItems.Add(oldItem); List <object> newItems = new List <object>(); newItems.Add(SelectedItem); RefreshSelectedItem(); if (!ChangingSelectionInHtml) //the SelectionChanged event is already fired from the javascript event. { OnSelectionChanged(new SelectionChangedEventArgs(oldItems, newItems)); } } if (!ChangingSelectionInHtml) { ChangingSelectionProgrammatically = true; //so that it doesn't end up in a loop ApplySelectedIndex(newValue); ChangingSelectionProgrammatically = false; } } //} }
private static void OnSelectedItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { Selector s = (Selector)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 (!s._selectionChangeIsOnValue && !s._selectionChangeIsOnIndex) { s._selectionChangeIsOnItem = true; try { if (newValue == null) { // we use SetCurrentValue to preserve any potential bindings. s.SetCurrentValue(Selector.SelectedValueProperty, null); s.SetCurrentValue(Selector.SelectedIndexProperty, -1); } else { // we use SetCurrentValue to preserve any potential bindings. s.SetCurrentValue(Selector.SelectedValueProperty, PropertyPathHelper.AccessValueByApplyingPropertyPathIfAny(newValue, s.SelectedValuePath)); s.SetCurrentValue(Selector.SelectedIndexProperty, s.Items.IndexOf(newValue)); s.OnSelectedItemChanged(newValue); if (s.ItemsSource is ICollectionView view) { view.MoveCurrentToPosition(s.Items.IndexOf(newValue)); } } } finally { s._selectionChangeIsOnItem = false; } } //calling the methods to update the Visual Tree/Selection: s.ApplySelectedIndex(s.SelectedIndex); s.ManageSelectedIndex_Changed(s._indexChangeEventArgs); //We do not want to raise the event here when we have a MultiSelector (or when SelectionMode is not Single ?) if (!(s is MultiSelector)) { // Raise the selection changed event List <object> removedItems = new List <object>(); removedItems.Add(e.OldValue); List <object> addedItems = new List <object>(); addedItems.Add(e.NewValue); SelectionChangedEventArgs args = new SelectionChangedEventArgs(removedItems, addedItems); s.OnSelectionChanged(args); } }
internal override FrameworkElement GenerateEditingElement(object childData) { Binding b = Binding as Binding; if (b.Mode == BindingMode.OneWay) { if (!b.INTERNAL_WasModeSetByUserRatherThanDefaultValue()) { b.Mode = BindingMode.TwoWay; } } object value = PropertyPathHelper.AccessValueByApplyingPropertyPathIfAny(childData, b.Path.Path); if (!(value is Enum)) { throw new NotImplementedException("DataGridComboBoxColumns currently only works with Enum types"); } Type enumType = value.GetType(); var enumValues = Enum.GetValues(enumType);// enumType.GetEnumValues(); NativeComboBox cb = new NativeComboBox(); cb.DataContext = childData; if (enumValues != null && enumValues.Length > 0) { #if BRIDGE //Note: work around the fact that Enum is not a persistant type (the value is replaced by the base type of the enum (int32 by default)) // because of that, we need to set the ItemsSource of the ComboBox to a list of the names (as strings) of the possible enum values. // Otherwise, the value shown in the comboBox would be the base type value (so 0 or 1 for example). // Create a list of the enum's values' names and set it as the ItemsSource of the ComboBox: var enumValuesAsStrings = new List <string>(); Type valueType = value.GetType(); foreach (object val in enumValues) { enumValuesAsStrings.Add(Enum.GetName(valueType, val)); } cb.ItemsSource = enumValuesAsStrings; //Add a converter so that we go smoothly between the selected value in the ComboBox and the expected value in the source of the binding: b.Converter = new MyConverter(); b.ConverterParameter = valueType; #else cb.ItemsSource = enumValues; #endif cb.SetBinding(NativeComboBox.SelectedItemProperty, b); } return(cb); }
private void AddOption(object option, int index) { if (this._nativeComboBoxDomElement == null) { return; } object value = PropertyPathHelper.AccessValueByApplyingPropertyPathIfAny(option, this.DisplayMemberPath); if (value != null) { INTERNAL_HtmlDomManager.AddOptionToNativeComboBox( this._nativeComboBoxDomElement, value.ToString(), index); } }
private static void OnSelectedItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { Selector s = (Selector)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 (!s._selectionChangeIsOnValue && !s._selectionChangeIsOnIndex) { s._selectionChangeIsOnItem = true; try { if (newValue == null) { // we use SetCurrentValue to preserve any potential bindings. s.SetCurrentValue(Selector.SelectedValueProperty, null); s.SetCurrentValue(Selector.SelectedIndexProperty, -1); } else { // we use SetCurrentValue to preserve any potential bindings. s.SetCurrentValue(Selector.SelectedValueProperty, PropertyPathHelper.AccessValueByApplyingPropertyPathIfAny(newValue, s.SelectedValuePath)); s.SetCurrentValue(Selector.SelectedIndexProperty, s.Items.IndexOf(newValue)); } } finally { s._selectionChangeIsOnItem = false; } } // Raise the selection changed event List <object> removedItems = new List <object>(); removedItems.Add(e.OldValue); List <object> addedItems = new List <object>(); addedItems.Add(e.NewValue); SelectionChangedEventArgs args = new SelectionChangedEventArgs(removedItems, addedItems); s.OnSelectionChanged(args); }
protected FrameworkElement GenerateFrameworkElementToRenderTheItem(object item) { FrameworkElement result; if (item is FrameworkElement) { //--------------- // The item is already a FrameworkElement, so we return itself: //--------------- result = (FrameworkElement)item; } else { object displayElement = PropertyPathHelper.AccessValueByApplyingPropertyPathIfAny(item, this.DisplayMemberPath); if (this.ItemTemplate != null) { //--------------- // An ItemTemplate was specified, so we instantiate it and return it: //--------------- // Apply the data template: result = ItemTemplate.INTERNAL_InstantiateFrameworkTemplate(); result.DataContext = displayElement; } else { //--------------- // Otherwise we simply call "ToString()" to display the item as a string inside a TextBlock: //--------------- // Show as string: //result = new TextBlock() { Text = displayElement.ToString() }; TextBlock t = new TextBlock(); Binding b = new Binding(DisplayMemberPath); t.SetBinding(TextBlock.TextProperty, b); t.DataContext = item; result = t; } } return(result); }
private static void SelectedValue_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (!AreObjectsEqual(e.OldValue, e.NewValue)) { Selector selector = (Selector)d; object newValue = (object)e.NewValue; object oldItem = selector.SelectedItem; if (!selector._selectionChangeIsOnItem && !selector._selectionChangeIsOnIndex) //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) { selector._selectionChangeIsOnValue = true; if (newValue == null) { selector.SetLocalValue(SelectedIndexProperty, -1); //we call SetLocalvalue directly to avoid replacing the BindingExpression that could be here on Mode = TwoWay selector.SetLocalValue(SelectedItemProperty, null); //we call SetLocalvalue directly to avoid replacing the BindingExpression that could be here on Mode = TwoWay //todo: update binding of SelectedIndex //selector.SelectedIndex = -1; //selector.SelectedItem = null; } else { var selectedPropertyPath = selector.SelectedValuePath; object item = selector.Items.First(element => Object.Equals(PropertyPathHelper.AccessValueByApplyingPropertyPathIfAny(element, selectedPropertyPath), newValue)); //todo: perf? //Note: there is no way we can know which value was intended in the case of multiple items with the same values. selector.SetLocalValue(SelectedIndexProperty, GetIndexOfElementInItems(selector, item)); //we call SetLocalvalue directly to avoid replacing the BindingExpression that could be here on Mode = TwoWay selector.SetLocalValue(SelectedItemProperty, item); //we call SetLocalvalue directly to avoid replacing the BindingExpression that could be here on Mode = TwoWay //todo: update binding of SelectedIndex //selector.SelectedIndex = GetIndexOfElementInItems(selector, item); //selector.SelectedItem = item; } selector._selectionChangeIsOnValue = false; List <object> oldItems = new List <object>(); oldItems.Add(oldItem); List <object> newItems = new List <object>(); newItems.Add(selector.SelectedItem); selector.RefreshSelectedItem(); selector.OnSelectionChanged(new SelectionChangedEventArgs(oldItems, newItems)); } } }
private static void SelectedItem_changed(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (!AreObjectsEqual(e.OldValue, e.NewValue)) { Selector selector = (Selector)d; object newValue = (object)e.NewValue; if (!selector._selectionChangeIsOnValue && !selector._selectionChangeIsOnIndex) //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) { selector._selectionChangeIsOnItem = true; if (newValue == null) { selector.SetLocalValue(SelectedIndexProperty, -1); //we call SetLocalvalue directly to avoid replacing the BindingExpression that could be here on Mode = TwoWay selector.SetLocalValue(SelectedValueProperty, null); //we call SetLocalvalue directly to avoid replacing the BindingExpression that could be here on Mode = TwoWay //todo: update binding of SelectedIndex //selector.SelectedIndex = -1; //selector.SelectedValue = null; } else { selector.SetLocalValue(SelectedIndexProperty, GetIndexOfElementInItems(selector, newValue)); //we call SetLocalvalue directly to avoid replacing the BindingExpression that could be here on Mode = TwoWay selector.SetLocalValue(SelectedValueProperty, PropertyPathHelper.AccessValueByApplyingPropertyPathIfAny(newValue, selector.SelectedValuePath)); //we call SetLocalvalue directly to avoid replacing the BindingExpression that could be here on Mode = TwoWay //todo: update binding of SelectedIndex //selector.SelectedIndex = GetIndexOfElementInItems(selector, newValue); //selector.SelectedValue = selector.AccessValueByApplyingPropertyPathIfAny(newValue, selector.SelectedValuePath); } selector._selectionChangeIsOnItem = false; List <object> oldItems = new List <object>(); oldItems.Add(e.OldValue); List <object> newItems = new List <object>(); newItems.Add(e.NewValue); selector.RefreshSelectedItem(); selector.OnSelectionChanged(new SelectionChangedEventArgs(oldItems, newItems)); } } }
protected FrameworkElement GenerateFrameworkElementToRenderTheItem(object item) { //--------------------------------------------------- // if the item is a FrameworkElement, return itself //--------------------------------------------------- FrameworkElement result = item as FrameworkElement; if (result == null) { object displayElement = PropertyPathHelper.AccessValueByApplyingPropertyPathIfAny(item, this.DisplayMemberPath); if (this.ItemTemplate != null) { //--------------------------------------------------- // An ItemTemplate was specified, so we instantiate // it and return it //--------------------------------------------------- // Apply the data template result = ItemTemplate.INTERNAL_InstantiateFrameworkTemplate(); result.DataContext = displayElement; } else { //--------------------------------------------------- // Otherwise we simply call "ToString()" to display // the item as a string inside a TextBlock //--------------------------------------------------- ContentPresenter container = new ContentPresenter(); Binding b = new Binding(this.DisplayMemberPath); container.SetBinding(ContentControl.ContentProperty, b); container.DataContext = item; result = container; } } #if WORKINPROGRESS this.PrepareContainerForItemOverride(result, item); #endif return(result); }
private object FindItemWithValue(object value, out int index) { index = -1; if (this.Items.Count == 0) { return(DependencyProperty.UnsetValue); } string selectedValuePath = this.SelectedValuePath; // optimize for case where there is no SelectedValuePath if (string.IsNullOrEmpty(selectedValuePath)) { index = this.Items.IndexOf(value); if (index >= 0) { return(value); } else { return(DependencyProperty.UnsetValue); } } index = 0; foreach (object item in this.Items) { object displayedItem = PropertyPathHelper.AccessValueByApplyingPropertyPathIfAny(item, selectedValuePath); if (ItemsControl.EqualsEx(displayedItem, value)) { return(item); } ++index; } index = -1; return(DependencyProperty.UnsetValue); }
private static void OnSelectedValuePathChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { Selector s = (Selector)d; s._selectionChangeIsOnItem = true; s._selectionChangeIsOnIndex = true; try { object item = null; if (s.SelectedItem != null) { item = PropertyPathHelper.AccessValueByApplyingPropertyPathIfAny(s.SelectedItem, (string)e.NewValue); } s.SetCurrentValue(Selector.SelectedValueProperty, item); } finally { s._selectionChangeIsOnItem = false; s._selectionChangeIsOnIndex = false; } }
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) { Selector s = (Selector)d; s._indexChangeEventArgs = e; //keeping the event args for the call of ManageSelectedIndex_Changed in OnSelectedItemChanged int newValue = (int)e.NewValue; // 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 (!s._selectionChangeIsOnValue && !s._selectionChangeIsOnItem) { s._selectionChangeIsOnIndex = true; try { if (newValue == -1) { // Note : we use SetCurrentValue to preserve any potential bindings. s.SetCurrentValue(Selector.SelectedValueProperty, null); // Skip the call to Items.IndexOf() s.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. s.SetCurrentValue(Selector.SelectedItemProperty, null); } finally { s.SkipCoerceSelectedItemCheck = false; } } else { object item = s.Items[newValue]; // Note : we use SetCurrentValue to preserve any potential bindings. s.SetCurrentValue(Selector.SelectedValueProperty, PropertyPathHelper.AccessValueByApplyingPropertyPathIfAny(item, s.SelectedValuePath)); // Skip the call to Items.IndexOf() s.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. s.SetCurrentValue(Selector.SelectedItemProperty, item); } finally { s.SkipCoerceSelectedItemCheck = false; } } } finally { s._selectionChangeIsOnIndex = false; } } }
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; } } }