Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8410939
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 10, 20262026-06-10T00:18:37+00:00 2026-06-10T00:18:37+00:00

How can I get a WPF ComboBox that is within a DataTemplate within an

  • 0

How can I get a WPF ComboBox that is within a DataTemplate within an ItemsControl element to have, and always have, a default SelectedItem, all while sticking strictly to the MVVM pattern?

My goal is to define a list of “form fields” that then are translated, via templates, into actual form fields (i.e. – TextBox, ComboBox, DatePicker, etc.). The list of fields is 100% dynamic and fields can be added and removed (by the user) at any time.

The pseudo-implementation is:

MainWindow
    -> Sets FormViewModel as DataContext
FormViewModel (View Model)
    -> Populated the `Fields` Property
Form (View)
    -> Has an `ItemsControl` element with the `ItemsSource` bound to FormViewModel's `Fields` Property
    -> `ItemsControl` element uses an `ItemTemplateSelector` to select correct template based on current field's type**
FormField
    -> Class that has a `DisplayName`, `Value`, and list of `Operators` (=, <, >, >=, <=, etc.)
Operator
    -> Class that has an `Id` and `Label` (i.e.: Id = "<=", Label = "Less Than or Equal To")
DataTemplate
    -> 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 ***

** 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.

Here are the primary classes required to generate the form, based on the pseudo-implementation above:

FormViewModel.cs

public class FormViewModel : INotifyPropertyChanged {
    protected ObservableCollection<FormField> _fields;
    public ObservableCollection<FormField> 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<FormField>() {
            new FormField() {
                DisplayName = "Field1",
                Value = "Default Value",
                Operators = new ObservableCollection<Operator>() {
                    new Operator() { Id = "=", Label = "Equals" },
                    new Operator() { Id = "<", Label = "Less Than" },
                    new Operator() { Id = ">", Label = "Greater Than" }
                }
            }
        };
    }
}

Form.xaml

<UserControl.Resources>
    <ResourceDictionary Source="DataTemplates.xaml" />
</UserControl.Resources>
<ItemsControl
    ItemsSource="{Binding Fields}"
    ItemTemplateSelector="{StaticResource fieldTemplateSelector}">
    <ItemsControl.Template>
        <ControlTemplate TargetType="ItemsControl">
            <ItemsPresenter />
        </ControlTemplate>
    </ItemsControl.Template>
</ItemsControl>

Form.xaml.cs

public partial class Form : UserControl {
    public static readonly DependencyProperty FieldsProperty = DependencyProperty.RegisterAttached("Fields", typeof(ObservableCollection<FormField>), typeof(Form));

    public ObservableCollection<FormField> Fields {
        get { return ((ObservableCollection<FormField>)GetValue(FieldsProperty)); }
        set { SetValue(FieldsProperty, ((ObservableCollection<FormField>)value)); }
    }

    public Form() {
        InitializeComponent();
    }
}

FieldTemplateSelector.cs

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) && (item != null) && (item is FormField)) {
            return (element.FindResource("defaultFieldTemplate") as DataTemplate);
        }
        return DefaultTemplate;
    }
}

DataTemplates.xaml

<local:FieldTemplateSelector x:Key="fieldTemplateSelector" />
<DataTemplate x:Key="defaultFieldTemplate">
    <StackPanel Orientation="Vertical">
        <TextBlock Text="{Binding Path=DisplayName}" />
        <TextBox Text="{Binding Path=Value, UpdateSourceTrigger=PropertyChanged}" />
        <ComboBox
            ItemsSource="{Binding Path=Operators}"
            DisplayMemberPath="Label" SelectedValuePath="Id"
            SelectedItem="{Binding SelectedOperator, Mode=TwoWay}"
            HorizontalAlignment="Right"
        />
    </StackPanel>
</DataTemplate>

FormField.cs

public class FormField : INotifyPropertyChanged {
    public string DisplayName { get; set; }
    public string Value { get; set; }

    protected ObservableCollection<Operator> _operators;
    public ObservableCollection<Operator> 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));
    }
}

Operator.cs

public class Operator {
    public string Id { get; set; }
    public string Label { get; set; }
}

The form is properly generated; All “form fields” in the Fields list are created as TextBox elements with their name’s displayed as labels, and they each have a ComboBox full of operators. However, the ComboBox doesn’t have an item selected by default.

My initial step to fix the issue was to set SelectedIndex=0 on the ComboBox; this didn’t work. After trial and error, I opted to use a DataTrigger such as the following:

<ComboBox
    ItemsSource="{Binding Path=Operators}"
    DisplayMemberPath="Label" SelectedValuePath="Id"
    SelectedItem="{Binding SelectedOperator, Mode=TwoWay}"
    HorizontalAlignment="Right">
    <ComboBox.Style>
        <Style TargetType="{x:Type ComboBox}">
            <Style.Triggers>
                <!-- select the first item by default (if no other is selected) -->
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=SelectedItem}"  Value="{x:Null}">
                    <Setter Property="SelectedIndex" Value="0"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ComboBox.Style>
</ComboBox>

The trigger I added will check if the current SelectedItem is null and, if so, set the SelectedIndex to 0. This works! When I run the application, each ComboBox has an item selected by default! But wait, there’s more:
If an item is then removed from the Fields list and at any time added back, the ComboBox 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 SelectedItem. When the field is removed and then added back, SelectedItem is no longer null 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.

Summarized: When a ComboBox is used within a DataTemplate, the SelectedItem for the ComboBox is not using its bound property as a default value.

What I’ve tried:

  1. DataTrigger when SelectedItem is null to select the first item in the list.
    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.

  2. Same as 1, plus a DataTrigger for when SelectedItem is not null to re-select the first item in the list.
    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 Fields list itself is recreated using already-created FormField items, the selected item is empty again. Also, it would be nice to pre-select the previously selected operator (not a requirement though).

  3. Used SelectedIndex instead of SelectedItem, with – and without – DataTriggers (as in #1 and #2).
    Result: Did not successfully select default items in either case, almost as if the SelectedIndex was being read before the ItemsSource.

  4. Used a DataTrigger to check the Items.Count property; if it was greater-than-zero, set the SelectedItem to the first element in the list.
    Result: Did not successfully select an item.

  5. Same as 4, but using SelectedIndex instead of SelectedItem.
    Result: Same as #1 Result

  6. Used IsSynchronizedWithCurrentItem with both True and False values.
    Result: Nothing selected.

  7. Re-ordered the XAML properties to place SelectedItem (and SelectedIndex, when used) to be before ItemsSource. This was done for every test as I’ve read online that it helps.
    Result: Doesn’t help.

  8. Tried different types of collections for the Operators property. I’ve used List, IEnumerable, ICollectionView, and am currently using ObservableCollection.
    Result: All provided the same output, except IEnumerable – it lost the value after the field was removed/re-added.

Any help would be greatly appreciated.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-10T00:18:38+00:00Added an answer on June 10, 2026 at 12:18 am

    Though I restructured my application and the above issue is no longer present, I have also figured out a solution to solving it!

    The steps:

    1. Taking a hint from a comment by Will, I updated the Form‘s codebehind to add a PropertyMetadata callback to the FieldsProperty.

    2. The callback from #1 iterates through the entire list of fields and uses Dispatcher.BeginInvoke() to invoke a Delegate-Action on an Input-priority level that will set the current field’s SelectedOperator to the first operator in the field’s Operators list.

      • Without using .BeginInvoke() or any other lower priority, the update would attempt to access the field before it was GUI-generated and would fail.
    3. Removed the DataTriggers from the Operators ComboBox in the DataTemplate (now, it is the same as the first code-example for DataTemplates.xaml in my question).

    New, working code (updates only):

    Form.cs

    ...
    public static readonly DependencyProperty FieldsProperty =
        DependencyProperty.RegisterAttached("Fields", typeof(ObservableCollection<FormField>), typeof(Form), new PropertyMetadata(_fieldsListUpdated));
    ...
    // PropertyMetaData-callback for when the FieldsProperty is updated
    protected static void _fieldsListUpdated(DependencyObject sender, DependencyPropertyChangedEventArgs args) {
        foreach (FormField field in ((Form)sender).Fields) {
            // check to see if the current field has valid operators
            if ((field.Operators != null) && (field.Operators.Count > 0)) {
                Dispatcher.CurrentDispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Input, (Action)(() => {
                    // set the current field's SelectedOperator to the first in the list
                    field.SelectedOperator = field.Operators[0];
                }));
            }
        }
    }
    

    The slight caveat to the above is that the SelectedOperator will always be set to the first in the list. For me, this isn’t an issue – but I could see a case where the “last-selected-operator” would want to be re-selected.

    After debugging, when the Field is added back to the list of Fields, it still retains the previous SelectedItem value – and then the ComboBox‘s SelectedIndex is immediately set to -1. Preventing this in the setter for FormField.SelectedOperator (and by trying SelectedItem/SelectedIndex) doesn’t help.

    Instead, creating a second “placeholder” Property in FormField named LastOperator and setting it to the SelectedOperator when the setter is passed null, and then updating the field.Operator = line in Form.cs seems to work:

    FormField.cs

    ...
    public Operator SelectedOperator {
        get { return _selectedOperator; }
        set {
            if (value == null) LastOperator = _selectedOperator;
            _selectedOperator = value; _onPropertyChanged("SelectedOperator");
        }
    }
    
    public Operator LastOperator { get; set; }
    

    Form.cs

    ...
    field.SelectedOperator = ((field.LastOperator != null) ? field.LastOperator : field.Operators[0]);
    ...
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a WPF containing a dynamically created DataGridComboBoxColumn this has a comboBox that
I have a WPF CustomControl that is derived from ComboBox and I'm trying to
I have a WPF combobox that I would like to bind to an observable
I have a ComboBox in wpf that twoway binds between the view and viewmodel.
I have a WPF app that has a combobox with lookup items. The combobox
I've set up a very simple example with LINQ-TO-SQL in WPF. I can get
How can I get the OS details using C# code in my WPF application?
Can get all triples with value null in specific field? All people with date_of_birth
I have a wpf app with a combobox like this <ComboBox name=cmbBx1> <ComboBoxItem Name=Jan>January</ComboBoxItem>
I have a comboBox that has a datatrigger that set its SelectedIndex based on

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.