I am relatively new to WPF. I am trying to open an excel file and pull the column headers and displaying it in my window as a check list. Right now I'm having issues updating the my window/checklist.
Here is what I have in the xaml
<DockPanel Grid.Column="0" Grid.Row="1" Margin="10">
<ListBox ItemsSource="{Binding TagListData}">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsTagSelected}" Content="{Binding TagName}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DockPanel>
and here is what I have in the cs code. (Instead of reading the excel document that gets opened, I am just using a placeholder for now just to see if I'm doing this correctly.)
private Excel.Application xlApp;
private Excel.Workbook xlWorkbook;
public ObservableCollection<TagClass> TagListData { get; set; }
public MainWindow()
{
InitializeComponent();
...
TagListData = new ObservableCollection<TagClass>();
}
private void btnOpenFile_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "Excel Files|*.xls;*.xlsx;*.slxm";
if (openFileDialog.ShowDialog() == true)
{
xlApp = new Excel.Application();
xlWorkbook = xlApp.Workbooks.Open(openFileDialog.FileName);
//populate TagListData
TagListData.Add(new TagClass { IsTagSelected = true, TagName = "Tag Name 1" });
}
}
public class TagClass
{
public string TagName { get; set; }
public bool IsTagSelected { get; set; }
}
When I try top open a file to populate my checklist, nothing happens. Does anyone know what I am doing incorrectly?
I also found this which checks when an item gets updated but I want to check when the list/collection gets updated. I'm having a hard time figuring this out.. ListBox item doesn't get refresh in WPF?
Thank you
It looks like you haven't set the DataContext of your window. The data context is the thing that you bind to, it doesn't just automatically hookup binding to properties that you add to the window itself.
There are many ways to fix this, the simplest (but arguably wrong) way to fix it would be to add this to the end of your constructor:
this.DataContext = this;
But this is weird. I would suggest never doing this. We normally create a new object will house the data that we want to bind to. In this case, you can set your DataContext to your TagListData, and then update the binding accordingly.
public MainWindow()
{
InitializeComponent();
...
TagListData = new ObservableCollection<TagClass>();
this.DataContext = TagListData;
}
and update the binding
<DockPanel Grid.Column="0" Grid.Row="1" Margin="10">
<ListBox ItemsSource="{Binding}"> <!-- note no Path on this binding because the data context of the window IS the collection now -->
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsTagSelected}" Content="{Binding TagName}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DockPanel>
If there are other things you are going to want to bind to on the Window, then setting the DataContext to the collection won't work. Instead you should create a new class that will contain the collection and all the other things you will want to bind to. Add a property of the type of this new class, and set that as your window's DataContext. When you're using the MVVM pattern, this is normally what we call the ViewModel.