Search code examples
wpfcomboboxdata-synchronization

using wpf datagridcomboboxcolumn's IsSynchronizedWithCurrentItem


(see below for my own answer that I came up with after letting this percolate for days & days) I am trying to achieve the following scenario in WPF.

I have a datagrid that is displaying rows of data for viewing and additional data entry. It is a new app but there is legacy data.

One particular field in the past has had data randomly entered into it. Now we want to limit that field's values to a particular list. So I'm using a DataGridComboBoxColumn. FWIW I have alternatively tried this with a DataGridTemplateColumn containing a ComboBox.

At runtime, if the existing value is not on the list, I want it to display anyway. I just cannot seem to get that to happen. While I have attempted a vast array of solutions (all failures) here is the one that is most logical as a starting point.

The list of values for the drop down are defined in a windows resource called "months".

<DataGridComboBoxColumn x:Name="frequencyCombo"   MinWidth="100" Header="Frequency"
   ItemsSource="{Binding Source={StaticResource months}}"
   SelectedValueBinding="{Binding Path=Frequency,UpdateSourceTrigger=PropertyChanged}">
   <DataGridComboBoxColumn.ElementStyle>
     <Style TargetType="ComboBox">
       <Setter Property="IsSynchronizedWithCurrentItem" Value="False" />
     </Style>
   </DataGridComboBoxColumn.ElementStyle>
</DataGridComboBoxColumn>

What is happening is that if a value is not on the list then the display is blank. I have verified at runtime that the IsSynchronizedWithCurrentItem element is indeed False. It is just not doing what I am expecting.

Perhaps I am just going down the wrong path here. Maybe I need to use a textbox in combination with the combobox. Maybe I need to write some code, not just XAML. I have spent hours trying different things and would be really appreciative of a solution. I have had a few suggestions to use this class or that control but without explanation of how to use it.

Thanks a bunch!


Solution

  • I have finally solved this. The trick is to get rid of the comboboxcolumn and use a template that has a textbox for display and a combobox for editing. However, I still spent hours with a new problem...when making a selection in the combobox, it would modify any other rows where I had also used the combobox in the grid. Guess what solved the problem! The IsSynchronizedWithCurrentItem property that I was trying to use before. :)

     <DataGridTemplateColumn x:Name="frequencyCombo" Header="Frequency">
       <DataGridTemplateColumn.CellTemplate>
         <DataTemplate>
           <TextBlock Text="{Binding Path=Frequency}" />
         </DataTemplate>
       </DataGridTemplateColumn.CellTemplate>
       <DataGridTemplateColumn.CellEditingTemplate>
       <DataTemplate>
         <ComboBox 
           ItemsSource="{Binding Source={StaticResource frequencyViewSource},
           TargetNullValue=''}"
           SelectedItem="{Binding Path=Frequency}" IsSynchronizedWithCurrentItem="False"
          />
        </DataTemplate>
      </DataGridTemplateColumn.CellEditingTemplate>
    </DataGridTemplateColumn>
    

    No ugly hacks. No non-usable choices hanging around at the bottom of the dropdown. No code to add those extra values and then clean them up.

    I am not going to take away the "Answer" on Mark's suggestion since it enabled me to get the app into my client's hands, but this is the solution I was looking for. I found it buried in a "connect" item after hours of web searching.

    Thanks for everyones help!