I have a WPF DataGrid that I bind to a DataTable. I don't like doing this but the data is coming from a delimited text file, and I don't know how many fields (columns) that the table will contain going in. Programatically this seems to be the easiest way to accomplish this (using MVVM and avoiding code behind), but given that I want two way binding, perhaps this won't work.
The DataGrid is defined like this in the view:
<DataGrid x:Name="dataGrid" ItemsSource="{Binding FileTable, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
HorizontalAlignment="Stretch" Margin="0,60,0,0" VerticalAlignment="Stretch">
</DataGrid>
The ViewModel sets up the datatable by reading a text file, and adds two boolean values to the end of each row. I want the boolean values to map to the checkboxes in the DataGrid, but they don't, and I don't get any events in the viewmodel when the values are changed. I am thinking that I need to change out the datatable as seen in other related questions, but they are all responding to the viewmodel changing the view (like a button that adds a column), rather than having the change come from the datagrid within the view.
For context here is the FileTable member in my ViewModel:
private DataTable _fileTable;
public DataTable FileTable
{
get
{
return _fileTable;
}
set
{
if (value != _fileTable)
{
_fileTable = value;
NotifyPropertyChanged("FileTable");
}
}
}
And here is the code that creates the datatable from a text file:
public DataTable ParseFileToTable(Document doc, string PlaceHolders)
{
if (dt == null)
{
dt = new DataTable();
}
else dt.Clear();
if (filepath == null)
{
OpenFileDialog dlg = new OpenFileDialog();
dlg.DefaultExt = ".txt"; // Default file extension
dlg.Filter = "Text documents (.txt)|*.txt"; // Filter files by extension
Nullable<bool> result = dlg.ShowDialog();
if (result != true) return null;
filepath = dlg.FileName;
StreamReader r = new StreamReader(filepath);
string line = r.ReadLine(); // First Line is Column Names
string[] h_line = line.Split('\t'); // tab delimeter is hardcoded for now
for(int i = 0; i < h_line.Count(); i++)
{
dt.Columns.Add(h_line[i]);
}
dt.Columns.Add(new DataColumn("Exists", typeof(bool)));
dt.Columns.Add(new DataColumn("Placeholder", typeof(bool)));
//read the rest of the file
while (!r.EndOfStream)
{
line = r.ReadLine();
string [] a_line = line.Split('\t');
DataRow nRow = dt.NewRow();
for(int i = 0; i < h_line.Count(); i++)
{
nRow[h_line[i]] = a_line[i];
}
nRow["Exists"] = DoesSheetExist(doc, h_line[0], a_line[0]);
nRow["Placeholder"] = IsAPlaceholder(a_line[0], PlaceHolders);
dt.Rows.Add(nRow);
}
}
return dt;
}