1
votes

I have a WPF window that contains multiple user controls, some of which are invisible (Visibility = Hidden). One of these controls has a ComboBox that has an ItemsSource binding, and I want to preset its selected item while the window/control is loading.

However, it seems like the binding is not applied until the combobox is visible. When I go to set the SelectedItem property and I hit a breakpoint in the debugger, I notice that ItemsSource is null at that moment. Is there a way to force WPF to apply the data binding and populate the combobox while it stays invisible?

Reproducible Example:

MainWindow.xaml

<Window x:Class="HiddenComboBoxBinding.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:HiddenComboBoxBinding"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Border x:Name="comboboxParent" Visibility="Collapsed">
            <ComboBox x:Name="cmbSearchType" SelectedIndex="0" ItemsSource="{Binding SearchTypeOptions}" DisplayMemberPath="Name" SelectionChanged="cmbSearchType_SelectionChanged" />
        </Border>
    </Grid>
</Window>

MainWindow.xaml.cs

using System.Linq;
using System.Windows;
using System.Windows.Controls;

namespace HiddenComboBoxBinding
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private ViewModel viewModel { get; set; } = new ViewModel();

        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = viewModel;

            // Add some or all of our search types - in the real code, there's some business logic here
            foreach (var searchType in SearchType.AllSearchTypes)
            {
                viewModel.SearchTypeOptions.Add(searchType);
            }

            // Pre-select the last option, which should be "Bar"
            cmbSearchType.SelectedItem = SearchType.AllSearchTypes.Last();
        }

        private void cmbSearchType_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {

        }
    }
}

ViewModel.cs

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HiddenComboBoxBinding
{
    public class ViewModel : INotifyPropertyChanged
    {
        public ObservableCollection<SearchType> SearchTypeOptions { get; set; } = new ObservableCollection<SearchType>();

        #region INotifyPropertyChanged Members
        private void NotifyPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); }
        public event PropertyChangedEventHandler PropertyChanged;
        #endregion
    }

    public class SearchType
    {
        // Source list of Search Types
        private static List<SearchType> _AllSearchTypes;
        public static List<SearchType> AllSearchTypes
        {
            get
            {
                if(_AllSearchTypes == null)
                {
                    _AllSearchTypes = new List<SearchType>();
                    _AllSearchTypes.Add(new SearchType() { Name = "Foo" });
                    _AllSearchTypes.Add(new SearchType() { Name = "Bar" });
                }
                return _AllSearchTypes;
            }
        }

        // Instance properties - for the purposes of a minimal, complete, verifiable example, just one property
        public string Name { get; set; }
    }
}
1
Try Visibility = Visibility.Collapsed instead of Visibility.Hidden maybe it make a difference.k1ll3r8e
When ItemsSource == null (instead of empty) then you are setting SelectedItem at the wrong time. Create a minimal reproducible example for this.Henk Holterman
Collapsed visibility has the same resultjhilgeman
Added an example, toojhilgeman

1 Answers

0
votes

I was able to figure out the issue. Setting the SelectedItem actually did work (even though ItemsSource was null at that time) but in the XAML, the ComboBox had SelectedIndex="0" and it was taking precedence over the SelectedItem being set in the code-behind.