title: WPF Binding DataTable Row Column to textbox
body: <blockquote>
    <p><strong>NARROWED DOWN SOLUTION</strong>
    <br />I'm much closer, but don't know how to apply XAML to change datacontext value.  Please review context of original question below as may be needed.</p>
  </blockquote>
  
  <p>My issue is that I have a ViewModel class as the datacontext to a window.  On this view model, I have a "DataTable" object (with columns and just a single row for testing).  When I try to set a Textbox "TEXT" binding to the column of the datatable, it doesn't work.  What I've ultimately found is that no matter what "source" or "path" I give it, it just won't cooperate.  HOWEVER, just by playing around with scenarios, I said the heck with it.  Lets look.  The Textbox control has its own "DataContext" property.  So, in code, I just FORCED the textbox.DataContext = "MyViewModel.MyDataTableObject" and left the path to just the column it should represent "MyDataColumn", and it worked.</p>
  
  <p>So, that said, how would I write the XAML for the textbox control so it's "DataContext" property is set to that of the datatable object of the view model the window but can't get that correct.  Ex:</p>
  
  <pre><code>&lt;TextBox Name="myTextBox" 
      Width="120"
      DataContext="THIS IS WHAT I NEED" --- to represent
      Text="{Binding Path=DataName, 
                      ValidatesOnDataErrors=True,
                      UpdateSourceTrigger=PropertyChanged }" /&gt;
  </code></pre>
  
  <p>DataContext for this textbox should reflect XAML details below and get</p>
  
  <p>(ActualWindow) ( DDT = View Model)  (oPerson = DataTable that exists ON the view model)
  CurrentWindow.DDT.oPerson</p>
  
  <p><br /><br /><br /></p>
  
  <p>I'm stuck on something with binding.  I want to bind a column of a datatable to a textbox control.  Sounds simple, but I'm missing something.  Simple scenario first.  If I have my window and set the data context to that of "MyDataTable", and have the textbox PATH=MyDataColumn, all works fine, no problems, including data validation (red border on errors).</p>
  
  <p>Now, the problem.  If I this have a same "MyDataTable" as a public on my Window Class directly (but same thing if I had it on an actual ViewModel object, but the window to simplify the level referencing), I can't get it to work from direct XAML source.  I knew I had to set the "SOURCE=MyDataTable", but the path of just the column didn't work.  </p>
  
  <pre><code>&lt;TextBox Name="myTextBox" 
           Text="{Binding  Source=DDT, Path=Rows[0][DataName], 
                           ValidatesOnDataErrors=True,
                           UpdateSourceTrigger=PropertyChanged }" /&gt;
  </code></pre>
  
  <p>However, from other testing, if I set the path (in code-behind) to </p>
  
  <pre><code>object txt = FindName("myTextBox");
  Binding oBind = new Binding("DataName");
  oBind.Source = DDT;
  oBind.Mode = BindingMode.TwoWay;
  oBind.ValidatesOnDataErrors = true;
  oBind.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
  ((TextBox)txt).SetBinding(TextBox.TextProperty, oBind);
  </code></pre>
  
  <p>It DOES work (when the datatable is available as public in the window (or view model))</p>
  
  <p>What am I missing otherwise.</p>
  
  <p><em><strong>UPDATE:  HERE IS A FULL POST of the sample code I'm applying here.</em></strong></p>
  
  <pre><code>using System.ComponentModel;
  using System.Data;
  
  namespace WPFSample1
  {
    /// &lt;summary&gt;
    /// Interaction logic for MainWindow.xaml
    /// &lt;/summary&gt;
    public partial class MainWindow : Window
    {
      public DerivedDataTable DDT;
  
      public MainWindow()
      {
        InitializeComponent();
        // hook up to a Data Table 
        DDT = new DerivedDataTable();
        DataContext = this;
  
        // with THIS part enabled, the binding works.  
        // DISABLE this IF test, and binding does NOT.
        // but also note, I tried these same settings manually via XAML.
        object txt = FindName("myTextBox");
        if( txt is TextBox)
        {
          Binding oBind = new Binding("DataName");
          oBind.Source = DDT;
          oBind.Mode = BindingMode.TwoWay;
          oBind.ValidatesOnDataErrors = true;
          oBind.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
          ((TextBox)txt).SetBinding(TextBox.TextProperty, oBind);
        }
      }
    }
  
    // Generic class with hooks to enable error trapping at the data table
    // level via ColumnChanged event vs IDataErrorInfo of individual properties
    public class MyDataTable : DataTable
    {
      public MyDataTable()
      {
        // hook to column changing
        ColumnChanged += MyDataColumnChanged;
      }
  
      protected void MyDataColumnChanged(object sender, DataColumnChangeEventArgs e)
      { ValidationTest( e.Row, e.Column.ColumnName); }
  
      // For any derived datatable to just need to define the validation method
      protected virtual string ValidationTest(DataRow oDR, string ColumnName)
      { return ""; }
    }
  
    public class DerivedDataTable : MyDataTable
    {
      public DerivedDataTable()
      {
        // simple data table, one column, one row and defaulting the value to "X"
        // so when the window starts, I KNOW its properly bound when the form shows
        // "X" initial value when form starts
        Columns.Add( new DataColumn("DataName", typeof(System.String))  );
        Columns["DataName"].DefaultValue = "X";
  
        // Add a new row to the table
        Rows.Add(NewRow());
      }
  
      protected override string ValidationTest(DataRow oDR, string ColumnName)
      {
        string error = "";
        switch (ColumnName.ToLower())
        {
          case "dataname" :
            if (   string.IsNullOrEmpty(oDR[ColumnName].ToString() )
              || oDR[ColumnName].ToString().Length &lt; 4 )
              error = "Name Minimum 4 characters";
  
            break;
        }
  
        // the datarow "SetColumnError" is what hooks the "HasErrors" validation
        // in similar fashion as IDataErrorInfo.
        oDR.SetColumnError(Columns[ColumnName], error);
  
        return error;
      }
    }
  }
  </code></pre>
  
  <p>AND here's the XAML.  Any brand new form and this is the only control in the default "grid" of the window.</p>
  
  <p>Tried following versions, just defining the Rows[0][Column]</p>
  
  <pre><code>&lt;TextBox Name="myTextBox" 
      Width="120"
      Text="{Binding  Path=Rows[0][DataName], 
                      ValidatesOnDataErrors=True,
                      UpdateSourceTrigger=PropertyChanged }" /&gt;
  </code></pre>
  
  <p>Including the source of "DDT" since it is public to the window</p>
  
  <pre><code>&lt;TextBox Name="myTextBox" 
      Width="120"
      Text="{Binding  Source=DDT, Path=Rows[0][DataName], 
                      ValidatesOnDataErrors=True,
                      UpdateSourceTrigger=PropertyChanged }" /&gt;
  </code></pre>
  
  <p>And even suggestions offered by grantnz</p>