title: Two way data binding in a GridView
body: <p>We have an app that uses simple one way binding with a GridView to display some data. Well, now we need to allow the user to change some of that data, so I've been trying to get two way data binding to work in the GridView. So far everything displays correctly, but editing cells in the GridView seems to do nothing at all. What am I messing up? Is two way databinding like this even possible? Should I just start converting everything to use a different control, like maybe a DataGrid? </p>
  
  <p>I wrote a tiny test app that shows my problem. If you try it, you'll see that the property setters never get called after their initialization.</p>
  
  <p>Xaml:
      
  
  <pre><code>    Title="Window1" Height="300" Width="300"&gt;
      &lt;Grid&gt;
          &lt;ListView Name="TestList"&gt;
              &lt;ListView.View&gt;
                  &lt;GridView&gt;
                      &lt;GridViewColumn Header="Strings"&gt;
                          &lt;GridViewColumn.CellTemplate&gt;
                              &lt;DataTemplate&gt;
                                  &lt;TextBox Text="{Binding Path=String, Mode=TwoWay}"/&gt;
                              &lt;/DataTemplate&gt;
                          &lt;/GridViewColumn.CellTemplate&gt;
                      &lt;/GridViewColumn&gt;
                      &lt;GridViewColumn Header="Bools"&gt;
                          &lt;GridViewColumn.CellTemplate&gt;
                              &lt;DataTemplate&gt;
                                  &lt;CheckBox IsChecked="{Binding Path=Bool, Mode=TwoWay}"/&gt;
                              &lt;/DataTemplate&gt;
                          &lt;/GridViewColumn.CellTemplate&gt;
                      &lt;/GridViewColumn&gt;
                  &lt;/GridView&gt;
              &lt;/ListView.View&gt;
          &lt;/ListView&gt;
      &lt;/Grid&gt;
  &lt;/Window&gt;
  </code></pre>
  
  <p>And here's the corresponding code:</p>
  
  <pre><code>using System.Collections.Generic;
  using System.Windows;
  
  namespace GridViewTextbox
  {
      public partial class Window1 : Window
      {
          private List&lt;TestRow&gt; _rows = new List&lt;TestRow&gt;();
  
          public Window1()
          {
              InitializeComponent();
  
              _rows.Add(new TestRow("a", false));
              _rows.Add(new TestRow("b", true));
              _rows.Add(new TestRow("c", false));
  
              TestList.ItemsSource = _rows;
              TestList.DataContext = _rows;
          }
      }
  
      public class TestRow : System.Windows.DependencyObject
      {
          public TestRow(string s, bool b)
          {
              String = s;
              Bool = b;
          }
  
          public string String
          {
              get { return (string)GetValue(StringProperty); }
              set { SetValue(StringProperty, value); }
          }
  
          // Using a DependencyProperty as the backing store for String.  This enables animation, styling, binding, etc...
          public static readonly DependencyProperty StringProperty =
              DependencyProperty.Register("String", typeof(string), typeof(TestRow), new UIPropertyMetadata(""));
  
  
          public bool Bool
          {
              get { return (bool)GetValue(BoolProperty); }
              set { SetValue(BoolProperty, value); }
          }
  
          // Using a DependencyProperty as the backing store for Bool.  This enables animation, styling, binding, etc...
          public static readonly DependencyProperty BoolProperty =
              DependencyProperty.Register("Bool", typeof(bool), typeof(TestRow), new UIPropertyMetadata(false));
      }
  }
  </code></pre>