1

I have the following XAML code:

<DataGrid ItemsSource="{Binding TempParameters}" AutoGenerateColumns="False" CanUserAddRows="False" Height="100" Name="TempParameterGrid" CanUserSortColumns="False" Width="{Binding Source={StaticResource theWidth}}" MouseDown="SetSelectedGrid">
     <DataGrid.Columns>
         <DataGridTextColumn Width="*" Header="ID"  IsReadOnly="True" Binding="{Binding ID}"/>
         <DataGridTemplateColumn Header="Parameter" IsReadOnly="False" >
             <DataGridTemplateColumn.CellEditingTemplate>
                 <DataTemplate>
                     <ComboBox SelectedValue="{Binding name, Mode=TwoWay}" ItemsSource ="{Binding ParameterNames, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
                 </DataTemplate>
             </DataGridTemplateColumn.CellEditingTemplate>
             <DataGridTemplateColumn.CellTemplate>
                 <DataTemplate>
                     <TextBox Text ="{Binding name, Mode=TwoWay}" />
                 </DataTemplate>
             </DataGridTemplateColumn.CellTemplate> 
         </DataGridTemplateColumn>
         <DataGridTextColumn Width="*" Header="Start"      IsReadOnly="False" Binding="{Binding start}"/>
         <DataGridTextColumn Width="*" Header="End"        IsReadOnly="False" Binding="{Binding end}"/>
         <DataGridTextColumn Width="*" Header="Samples"    IsReadOnly="False" Binding="{Binding samples}"/>
     </DataGrid.Columns>
 </DataGrid>

The DataGrid binds to a collection property TempParameters. This is a collection of the following objects.

    public class TuneParameterRecord {
        public int ID { get; set; }
        public string name { get; set; }
        public double start { get; set; }
        public double end { get; set; }
        public int samples { get; set; }
    }

All the columns are editable. However I need the name column to have a list of predefined names. Therefore I was thinking to provide a ComboBox with a list of acceptable values (while many will point it out, this list cannot be an enum. I need this to be a list of strings). This list is provided in the window data context.

I can reference it directly providing a relative source in the CellEditingTemplate. My problem is that when i try to edit a cell in the column in question, I get a cursor that can edit the textbox instead of getting a combobox.

In order to get the combobox. I have to click multiple times in the area indicated with red in the attached pictures. The first picture shows the cell being editable with a cursor, while the second image has the combobox (though masked) after I have clicked multiple times in the red area indicated.

Cursor Editing at a place where a combobox was supposed to beRed area where I click multiple times for the combobox to appear

msmechanized
  • 436
  • 4
  • 19
  • 1
    As many will *also* point out, enums can be easily converted to lists of strings. See https://stackoverflow.com/questions/14971631 – Robert Harvey Aug 05 '20 at 20:49
  • 1
    [This](https://stackoverflow.com/a/4398752/102937) is how you would bind it. – Robert Harvey Aug 05 '20 at 20:52
  • @RobertHarvey. Thank you for pointing this out. As I was researching the issue I saw about binding enums that is why I mentioned it. Using enums at this stage would cause some refactoring down the chain of abstraction and at this time i don't have a problem with binding to the correct data, but an issue with different behavior than what was defined. – msmechanized Aug 05 '20 at 20:57

2 Answers2

1

So I have found the problem. I have converted the

<DataGridTemplateColumn.CellTemplate>
     <DataTemplate>
         <TextBox Text ="{Binding name, Mode=TwoWay}" />
     </DataTemplate>
</DataGridTemplateColumn.CellTemplate>

to

<DataGridTemplateColumn.CellTemplate>
     <DataTemplate>
         <TextBlock Text ="{Binding name, Mode=TwoWay}" />
     </DataTemplate>
</DataGridTemplateColumn.CellTemplate>

This defaults to the desired behavior. I have a feeling that I got the inconsistent behavior because the TextBox can be edited while the Textblock cannot. Therefore a single click would select the TextBox but not revert to the cell editing template.

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
msmechanized
  • 436
  • 4
  • 19
0

I have essentially the same XAML you posted in my code. However, my XAML also includes the following as part of the Combo Box:

<i:Interaction.Triggers>
    <i:EventTrigger EventName="Loaded">
        <helpers:TakeFocusAction />
    </i:EventTrigger>
</i:Interaction.Triggers>

Its purpose is to put the focus into the combo box whenever the CellEditingTemplate kicks in.

The TakeFocus action looks like this:

using System.Windows;
using System.Windows.Interactivity;

namespace Helpers
{
    public class TakeFocusAction : TriggerAction<UIElement>
    {
        protected override void Invoke(object parameter)
        {
            AssociatedObject.Focus();
        }
    }
}

You'll need the following namespaces in your Xaml:

xmlns:helpers="clr-namespace:Helpers"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"

If you don't already have it, you'll need the Microsoft.Xaml.Behaviors.Wpf Nuget package, which provides the interactivity namespace above.

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
  • Trying to do that and I get `Severity Code Description Project File Line Suppression State Error XDG0008 The name "Interaction" does not exist in the namespace "http://schemas.microsoft.com/expression/2010/interactivity".` – msmechanized Aug 06 '20 at 09:03
  • Install [this](https://www.nuget.org/packages/Microsoft.Xaml.Behaviors.Wpf/) Nuget package. – Robert Harvey Aug 06 '20 at 15:23