title: Default SelectedItem for a WPF ComboBox inside a DataTemplate used in an ItemsControl not working
body: <p>How can I get a WPF <code>ComboBox</code> that is within a <code>DataTemplate</code> within an <code>ItemsControl</code> element to have, and always have, a default <code>SelectedItem</code>, all while sticking strictly to the MVVM pattern?</p>
  
  <p>My goal is to define a list of "form fields" that then are translated, via templates, into actual form fields (i.e. - <code>TextBox</code>, <code>ComboBox</code>, <code>DatePicker</code>, etc.). The list of fields is 100% dynamic and fields can be added and removed (by the user) at any time.</p>
  
  <p>The pseudo-implementation is:</p>
  
  <pre><code>MainWindow
      -&gt; Sets FormViewModel as DataContext
  FormViewModel (View Model)
      -&gt; Populated the `Fields` Property
  Form (View)
      -&gt; Has an `ItemsControl` element with the `ItemsSource` bound to FormViewModel's `Fields` Property
      -&gt; `ItemsControl` element uses an `ItemTemplateSelector` to select correct template based on current field's type**
  FormField
      -&gt; Class that has a `DisplayName`, `Value`, and list of `Operators` (=, &lt;, &gt;, &gt;=, &lt;=, etc.)
  Operator
      -&gt; Class that has an `Id` and `Label` (i.e.: Id = "&lt;=", Label = "Less Than or Equal To")
  DataTemplate
      -&gt; A `DataTemplate` element for each field type* that creates a form field with a label, and a `ComboBox` with the field's available Operators
      *** The `Operators` ComboBox is where the issue occurs ***
  </code></pre>
  
  <p>** The actual field's "type" and the implementation contained therein is not included in this question as it's not relevant to the display issue.</p>
  
  <p>Here are the primary classes required to generate the form, based on the pseudo-implementation above:</p>
  
  <p>FormViewModel.cs</p>
  
  <pre><code>public class FormViewModel : INotifyPropertyChanged {
      protected ObservableCollection&lt;FormField&gt; _fields;
      public ObservableCollection&lt;FormField&gt; Fields {
          get { return _fields; }
          set { _fields = value; _onPropertyChanged("Fields"); }
      }
  
      public event PropertyChangedEventHandler PropertyChanged;
      protected void _onPropertyChanged(string propertyName) {
          if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
      }
  
      public FormViewModel() {
          // create a sample field that has a list of operators
          Fields = new ObservableCollection&lt;FormField&gt;() {
              new FormField() {
                  DisplayName = "Field1",
                  Value = "Default Value",
                  Operators = new ObservableCollection&lt;Operator&gt;() {
                      new Operator() { Id = "=", Label = "Equals" },
                      new Operator() { Id = "&lt;", Label = "Less Than" },
                      new Operator() { Id = "&gt;", Label = "Greater Than" }
                  }
              }
          };
      }
  }
  </code></pre>
  
  <p>Form.xaml</p>
  
  <pre><code>&lt;UserControl.Resources&gt;
      &lt;ResourceDictionary Source="DataTemplates.xaml" /&gt;
  &lt;/UserControl.Resources&gt;
  &lt;ItemsControl
      ItemsSource="{Binding Fields}"
      ItemTemplateSelector="{StaticResource fieldTemplateSelector}"&gt;
      &lt;ItemsControl.Template&gt;
          &lt;ControlTemplate TargetType="ItemsControl"&gt;
              &lt;ItemsPresenter /&gt;
          &lt;/ControlTemplate&gt;
      &lt;/ItemsControl.Template&gt;
  &lt;/ItemsControl&gt;
  </code></pre>
  
  <p>Form.xaml.cs</p>
  
  <pre><code>public partial class Form : UserControl {
      public static readonly DependencyProperty FieldsProperty = DependencyProperty.RegisterAttached("Fields", typeof(ObservableCollection&lt;FormField&gt;), typeof(Form));
  
      public ObservableCollection&lt;FormField&gt; Fields {
          get { return ((ObservableCollection&lt;FormField&gt;)GetValue(FieldsProperty)); }
          set { SetValue(FieldsProperty, ((ObservableCollection&lt;FormField&gt;)value)); }
      }
  
      public Form() {
          InitializeComponent();
      }
  }
  </code></pre>
  
  <p>FieldTemplateSelector.cs</p>
  
  <pre><code>public class FieldTemplateSelector : DataTemplateSelector {
      public DataTemplate DefaultTemplate { get; set; }
  
      public override DataTemplate SelectTemplate(object item, DependencyObject container) {
          FrameworkElement element = (container as FrameworkElement);
          if ((element != null) &amp;&amp; (item != null) &amp;&amp; (item is FormField)) {
              return (element.FindResource("defaultFieldTemplate") as DataTemplate);
          }
          return DefaultTemplate;
      }
  }
  </code></pre>
  
  <p>DataTemplates.xaml</p>
  
  <pre><code>&lt;local:FieldTemplateSelector x:Key="fieldTemplateSelector" /&gt;
  &lt;DataTemplate x:Key="defaultFieldTemplate"&gt;
      &lt;StackPanel Orientation="Vertical"&gt;
          &lt;TextBlock Text="{Binding Path=DisplayName}" /&gt;
          &lt;TextBox Text="{Binding Path=Value, UpdateSourceTrigger=PropertyChanged}" /&gt;
          &lt;ComboBox
              ItemsSource="{Binding Path=Operators}"
              DisplayMemberPath="Label" SelectedValuePath="Id"
              SelectedItem="{Binding SelectedOperator, Mode=TwoWay}"
              HorizontalAlignment="Right"
          /&gt;
      &lt;/StackPanel&gt;
  &lt;/DataTemplate&gt;
  </code></pre>
  
  <p>FormField.cs</p>
  
  <pre><code>public class FormField : INotifyPropertyChanged {
      public string DisplayName { get; set; }
      public string Value { get; set; }
  
      protected ObservableCollection&lt;Operator&gt; _operators;
      public ObservableCollection&lt;Operator&gt; Operators {
          get { return _operators; }
          set {
              _operators = value;
              _onPropertyChanged("Operators");
          }
      }
  
      protected Operator _selectedOperator;
      public Operator SelectedOperator {
          get { return _selectedOperator; }
          set { _selectedOperator = value; _onPropertyChanged("SelectedOperator"); }
      }
  
      public event PropertyChangedEventHandler PropertyChanged;
      protected void _onPropertyChanged(string propertyName) {
          if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
      }
  }
  </code></pre>
  
  <p>Operator.cs</p>
  
  <pre><code>public class Operator {
      public string Id { get; set; }
      public string Label { get; set; }
  }
  </code></pre>
  
  <p>The form is properly generated; All "form fields" in the <code>Fields</code> list are created as <code>TextBox</code> elements with their name's displayed as labels, and they each have a <code>ComboBox</code> full of operators. However, the <code>ComboBox</code> doesn't have an item selected by default.</p>
  
  <p>My initial step to fix the issue was to set <code>SelectedIndex=0</code> on the <code>ComboBox</code>; this didn't work. After trial and error, I opted to use a <code>DataTrigger</code> such as the following:</p>
  
  <pre><code>&lt;ComboBox
      ItemsSource="{Binding Path=Operators}"
      DisplayMemberPath="Label" SelectedValuePath="Id"
      SelectedItem="{Binding SelectedOperator, Mode=TwoWay}"
      HorizontalAlignment="Right"&gt;
      &lt;ComboBox.Style&gt;
          &lt;Style TargetType="{x:Type ComboBox}"&gt;
              &lt;Style.Triggers&gt;
                  &lt;!-- select the first item by default (if no other is selected) --&gt;
                  &lt;DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=SelectedItem}"  Value="{x:Null}"&gt;
                      &lt;Setter Property="SelectedIndex" Value="0"/&gt;
                  &lt;/DataTrigger&gt;
              &lt;/Style.Triggers&gt;
          &lt;/Style&gt;
      &lt;/ComboBox.Style&gt;
  &lt;/ComboBox&gt;
  </code></pre>
  
  <p>The trigger I added will check if the current <code>SelectedItem</code> is <code>null</code> and, if so, set the <code>SelectedIndex</code> to 0. This works! When I run the application, each <code>ComboBox</code> has an item selected by default! But wait, there's more:
  If an item is then removed from the <code>Fields</code> list and at any time added back, the <code>ComboBox</code> has no item selected again. Basicaly, what's happening is, when the field is created for the first time, the data-trigger selects the first item in the operators list and sets that as the field's <code>SelectedItem</code>. When the field is removed and then added back, <code>SelectedItem</code> is no longer <code>null</code> so the original DataTrigger doesn't work. Oddly enough, even though there is clearly a binding for the SelectedItem property, the currently-selected item is not being selected.</p>
  
  <p>Summarized: When a <code>ComboBox</code> is used within a DataTemplate, the <code>SelectedItem</code> for the <code>ComboBox</code> is not using its bound property as a default value.</p>
  
  <p>What I've tried:</p>
  
  <ol>
  <li><p>DataTrigger when <code>SelectedItem</code> is null to select the first item in the list.<br>
  Result: Correctly selects the item when the field is created; Loses the item when the field is removed from the display and then added back.</p></li>
  <li><p>Same as 1, plus a DataTrigger for when <code>SelectedItem</code> is not null to re-select the first item in the list.<br>
  Result: Same as #1 Result + Correctly selects the first item in the list when the field is removed from the display and then added back; If the entire <code>Fields</code> list itself is recreated using already-created <code>FormField</code> items, the selected item is empty again. Also, it would be nice to pre-select the previously selected operator (not a requirement though).</p></li>
  <li><p>Used <code>SelectedIndex</code> instead of <code>SelectedItem</code>, with - and without - DataTriggers (as in #1 and #2).<br>
  Result: Did not successfully select default items in either case, almost as if the <code>SelectedIndex</code> was being read before the <code>ItemsSource</code>.</p></li>
  <li><p>Used a DataTrigger to check the <code>Items.Count</code> property; if it was greater-than-zero, set the <code>SelectedItem</code> to the first element in the list.<br>
  Result: Did not successfully select an item.</p></li>
  <li><p>Same as 4, but using <code>SelectedIndex</code> instead of <code>SelectedItem</code>.<br>
  Result: Same as #1 Result</p></li>
  <li><p>Used <code>IsSynchronizedWithCurrentItem</code> with both <code>True</code> and <code>False</code> values.<br>
  Result: Nothing selected.</p></li>
  <li><p>Re-ordered the XAML properties to place <code>SelectedItem</code> (and <code>SelectedIndex</code>, when used) to be before <code>ItemsSource</code>. This was done for every test as I've read online that it helps.<br>
  Result: Doesn't help.</p></li>
  <li><p>Tried different types of collections for the <code>Operators</code> property. I've used <code>List</code>, <code>IEnumerable</code>, <code>ICollectionView</code>, and am currently using <code>ObservableCollection</code>.<br>
  Result: All provided the same output, except <code>IEnumerable</code> - it lost the value after the field was removed/re-added.</p></li>
  </ol>
  
  <p>Any help would be greatly appreciated.</p>