DataGridTemplateColumn Two way binding is not working
Asked Answered
T

2

19

I've got a DataGrid I've bound to a SqlDataApter. If I set up the XAML for the grid using DataTextColumn as illustrated in the code below it works perfectly

<DataGrid AutoGenerateColumns="False" HorizontalAlignment="Left" Margin="27,42,0,0"
          Name="dataGrid1" VerticalAlignment="Top" AreRowDetailsFrozen="True">
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding KEY}" Visibility="Hidden"
                            IsReadOnly="True"/>
        <DataGridTextColumn Binding="{Binding CHARACTERISTIC_CODE}"
                            Header="Unit" IsReadOnly="True"/>
        <DataGridTextColumn Binding="{Binding UNIT_CHAR}"
                            Header="Unit" IsReadOnly="True" />
        <DataGridTextColumn Binding="{Binding IC_DEF_CHAR_NUMERIC}"
                            Header="Number" IsReadOnly="False"/>
        <DataGridTextColumn Binding="{Binding IC_DEF_CHAR_TEXT}"
                            Header="Text" IsReadOnly="False" />
        <DataGridTextColumn Binding="{Binding IsNumeric}"
                            Header="Status" IsReadOnly="True"/>
        <DataGridTextColumn Binding="{Binding IsText}"
                            Header="Status" IsReadOnly="True"/>
    </DataGrid.Columns>
</DataGrid>

I am binding this to a DataTable in code using:

dataGrid1.ItemsSource = dTable.DefaultView

And I have a button that saves the changes using the ذSqlDataAdapterذ update method:

dAdapter.Update(dTable)

The problem is that I want to disable editing the IC_DEF_CHAR_TEXT field when the record isNumeric and the IC_DEF_CHAR_TEXT when the record IsText. I tried binding to the IsReadOnly property but found that it is not bind-able, so I created templates for the two fields and bound the IsEnabled property to the IsText and IsNumeric fields.

<DataGrid AutoGenerateColumns="False" HorizontalAlignment="Left"
          Margin="27,42,0,0" Name="dataGrid1" VerticalAlignment="Top" 
          AreRowDetailsFrozen="True">
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding KEY}" Visibility="Hidden"
                            IsReadOnly="True"/>
        <DataGridTextColumn Binding="{Binding CHARACTERISTIC_CODE}"
                            Header="Unit" IsReadOnly="True"/>
        <DataGridTextColumn Binding="{Binding UNIT_CHAR}"
                            Header="Unit" IsReadOnly="True"/>
        <DataGridTemplateColumn Header="Numeric">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBox Text="{Binding Path=IC_DEF_CHAR_NUMERIC,
                             Mode=TwoWay}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
            <DataGridTemplateColumn.CellEditingTemplate>
                <DataTemplate>
                    <TextBox IsReadOnly="False"
                             Text="{Binding Path=IC_DEF_CHAR_NUMERIC,
                             Mode=TwoWay,
                             UpdateSourceTrigger=PropertyChanged}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellEditingTemplate>
        </DataGridTemplateColumn>
        <DataGridTemplateColumn Header="Text" >
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBox Text="{Binding Path=IC_DEF_CHAR_TEXT,
                             Mode=TwoWay}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
            <DataGridTemplateColumn.CellEditingTemplate>
                <DataTemplate>
                    <TextBox Text="{Binding Path=IC_DEF_CHAR_TEXT,
                             Mode=TwoWay,
                             UpdateSourceTrigger=PropertyChanged}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellEditingTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

This worked exactly like I wanted, the textboxes were enabled when necessary. However the changes made in the TextBoxes are no longer saved to the database during update. Can someone out there explain to me why the database is no longer being updated?

Tagalog answered 13/8, 2013 at 18:42 Comment(7)
Try changing the CellTemplate to not use two-way binding as it's essentially only supposed to act as a window.Riehl
I originally set it up that way and that didn't work either. I think two way is the default but I'm not 100% sure of that.Tagalog
What I mean is that TextBox will default to Two-Way, try changing it to One-Way on the CellTemplate. You only want Two-Way on CellEditingTemplateRiehl
I just tried that and that didn't help either. Thanks for tryingTagalog
What do you mean when you say I tried binding to the IsReadOnly property but found that it is not bindable? You should be able to bind to this. What happened when you did?Riehl
Basically it did not do anything if I tried to bind it to a boolean field. I could set it true or false but when I tried to bind it it was always editable. I would like to find out why the twoway binding is not working on the textbox as I can see me having to use templates in my coding quite often.Tagalog
I didn't even have to read the question content, just the topic, and the answer was exactly what I was looking for. Guess that really is just a very stupid default behavior of DataGrid.Starch
W
79

I had the same problem, not updating the source:

<DataGridTemplateColumn Header="Obs" IsReadOnly="False">
  <DataGridTemplateColumn.CellTemplate>
     <DataTemplate>
         <TextBox Name="txtObs" Width="80"
                  Text="{Binding Path=ObsPedido, Mode=TwoWay}"/>
      </DataTemplate>
  </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

For me it worked just adding UpdateSourceTrigger=PropertyChanged

<TextBox Name="txtObs" Width="80"
         Text="{Binding Path=ObsPedido, Mode=TwoWay,
         UpdateSourceTrigger=PropertyChanged}"/>
Watertight answered 11/12, 2013 at 20:24 Comment(6)
I had the same problem and setting the UpdateSourceTrigger=PropertyChanged solved it. I guess this should be marked as answer.Sanguinolent
This solved my problem too. This is a bug with only DataGrid, I think. 2 way binding works as expected with normal fields outside DataGrid.Amylum
Had the same issue and this solved it for me as well! :-) Thank you.Raver
Oh my God! I was searching for this solution about 2 hours! I've even started to looking on implementing "TrueObservableCollection", but I've finally found this! Thanks!Ferne
UpdateSourceTrigger=LostFocus also works, in case you don't want to update on every key press.Sexism
I wish it could help me but I project text input into double variable, replacing invalid input with default value. So as soon as user edits text to a not-a-number (like placing decimal point after a digit or erasing the field) it's replaced with default value. So I still have to find solution not involving UpdateSourceTrigger=PropertyChangedApricot
O
1

I had the same problem and the solution posted by @jrivam did not help. For me to get my binding to work correctly I had to change the CellEditingTemplate to use the OneWayToSource Binding Mode.

<DataGridTemplateColumn.CellEditingTemplate>
    <DataTemplate>
        <TextBox Text="{Binding Path=IC_DEF_CHAR_TEXT,
                 Mode=OneWayToSource, UpdateSourceTrigger=PropertyChanged}"/>
    </DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
Otiliaotina answered 16/11, 2015 at 0:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.