The binding for productColumn2 works perfect both ways. When I added a converter for each, productColumn1 called the converter; but always has it’s value set to null when loading from observable collection, or value set to product when assigning (but doesn’t actually assign observable collection).
Issue has to do with DataContext and LogicalTree. The DataContext for ProductSelectorTextBoxUserControl is itself, and is used for it’s own code. I want to be able to bind its ‘text’ property to my observable collection, as in productColumn2. I so far can’t seem to set ProductSelectorTextBoxUserControl DataContext to the DataContext used here.
<DataGrid ItemsSource="{Binding Path=ObservableCollectionItems, Mode=OneWay}" AutoGenerateColumns="False" EnableRowVirtualization="True" >
<DataGrid.Columns>
<DataGridTemplateColumn x:Name="productColumn1" SortMemberPath="Product" >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<productSelector:ProductSelectorTextBoxUserControl Text="{Binding Path=Product, Mode=TwoWay, NotifyOnSourceUpdated=True, UpdateSourceTrigger=LostFocus, ValidatesOnExceptions=True}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn x:Name="productColumn2" Binding="{Binding Path=Product, Mode=TwoWay, NotifyOnSourceUpdated=True}" />
</DataGrid.Columns>
Thanks @SellMeADog for helping me out on this, however this still took me way way to long to figure out. Final line is:
Key points are RelativeSource DataGridRow, Path is Item(ObservableCollection).Property
If you notice question referred to text and this refers to product, I had to switch to product and add converter. UserControl would then set its own text