locked
WPF binding error when databinding a ComboBox inside a ListView item RRS feed

  • Question

  • I am displaying a ComboBox in the data template of a ListView item.  The ComboBox is item bound to an observable collection and is member bound to a second observable collection. 

    Code Snippet
    <ComboBox ItemsSource="{Binding ElementName=WindowName, Path=ObserableCollection1}"  IsSynchronizedWithCurrentItem="False" DisplayMemberPath="Item1"  SelectedValuePath="Item1" SelectedValue="{Binding Path= ObserableCollection2,  UpdateSourceTrigger=Explicit}"/>

     

    The ComboBox binding works well when it is NOT used in a ListView.  However, when it is used in a ListView, the SelectedValue of the ComboBox does not bind correctly.  The ComboBox does not display (or bind at all) the selected value when it loads.

     

    I do not get compiler or runtime errors.  Instead, I simply get null values for the ComboBox selected item.  Even stranger… the null values occur MOST of the time, but very infrequently the binding seems to work correctly.

     

    One other complexity that may offer insight to my UI designs.  I’m using an explicit update trigger to manage my data binding so that I can do custom validation before updating the underlying object.  My explicit save is accomplished by recursively looping through UI Elements to get their BindingExpression and then calling BindingExpression.UpdateSource().  Below is some sample code of how this works:

     

    Code Snippet

    public void RecurseSave(UIElement element)
            {
                if (element is Grid)
                {
                    foreach (UIElement childElement in ((Grid) element).Children)
                    {
                        RecurseSave(childElement);
                    }
                }
                else if (element is Panel)
                {
                    foreach (UIElement childElement in ((Panel) Element).Children)
                    {
                        RecurseSave(childElement);
                    }
                }
                else if (element is ScrollViewer)
                {
                    ScrollViewer s = (ScrollViewer) element;
                    if (s.Visibility == Visibility.Visible)
                    {
                        RecurseSave((UIElement)s.Content);
                    }
                }
                else if (element is ListView)
                {
                    ListView l = (ListView) element;
                    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(l); i++)
                    {
                        RecurseSave((UIElement)VisualTreeHelper.GetChild(l, i));
                    }
                }
                else if (element is ListViewItem)
                {
                    ListViewItem item = (ListViewItem) element;
                    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(item); i++)
                    {
                        RecurseSave((UIElement)VisualTreeHelper.GetChild(item, i));
                    }
                }
                else if(element is GroupBox)
                {
                    GroupBox gb = (GroupBox)element;
                    {
                        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(gb); i++)
                        {
                            RecurseSave((UIElement)VisualTreeHelper.GetChild(gb, i));
                        }
                    }
                }
                else if (element is DockPanel)
                {
                    DockPanel dp = (DockPanel)element;
                    {
                        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(dp); i++)
                        {
                            RecurseSave((UIElement)VisualTreeHelper.GetChild(dp, i));
                        }
                    }
                }
                else if (element is Border)
                {
                    Border b = (Border) element;
                    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(b); i++)
                    {
                        RecurseSave((UIElement)VisualTreeHelper.GetChild(b, i));
                    }
                }
                else if (element is ContentPresenter)
                {
                    ContentPresenter cp = (ContentPresenter) element;
                    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(cp); i++)
                    {
                        RecurseSave((UIElement)VisualTreeHelper.GetChild(cp, i));
                    }
                }
                else
                {
                    BindingExpression bindingExpression = null;
                    if (element is TextBox)
                    {
                        bindingExpression =
       ((TextBox)element).GetBindingExpression(TextBox.TextProperty);
                    }
                    else if (element is ComboBox)
                    {
                        bindingExpression =
       ((ComboBox)element).GetBindingExpression(ComboBox.SelectedValueProperty);
                    }
                    else if (element is DatePicker)
                    {
                        bindingExpression =
       ((DatePicker)element).GetBindingExpression(DatePicker.ValueProperty);
                    }
                    else if(element is ToggleButton)
                    {
         bindingExpression = ((ToggleButton)element).GetBindingExpression
            (ToggleButton.IsCheckedProperty);
                    }

                    if (bindingExpression != null)
                    {
                        bindingExpression.UpdateSource();

                        if(!HasErrors)
                        {
                            HasErrors = bindingExpression.HasError;
                        }
                    }
                }
            }

     

    Does anyone have any ideas about how I can resolve my ComboBox binding issue?  I’d be happy to post additional XAML source or email it, but it’s about 6 pages of XAML, so I thought I’d try to post this simple posting first.  If anyone has any ideas, please reply to this post, or send me an email at jeff_townes@hotmail.com.

     

    Thanks,
    Jeff

    Tuesday, May 1, 2007 3:50 PM