I am new to WPF development. I've referred to many solutions online but still have no idea.
I have a Listbox and a Datagrid. The Listbox loads data and displays selectable items dynamically. The Datagrid shows static table with a checkbox column. I first load data of Datagrid from an Excel file and bind the ItemsSource of Datagrid to the dataset. Each line in the Datagrid is a class:
public class ExcelDataEntry
{
public bool isChecked { get; set; }
public string note { get; set; }
public ExcelDataEntry(string note)
{
this.isChecked = false;
this.note = note;
}
}
Displayed in the GUI are a Listbox and a Datagrid, in the backend they make a
viewModelObj:
class viewModelObj : INotifyPropertyChanged
{
public string displayName { get; set; }
private List<ExcelDataEntry> _generalNoteList;
public List<ExcelDataEntry> generalNoteList
{
get { return _generalNoteList; }
set
{
_generalNoteList = value;
OnPropertyChanged("generalNoteList");
MessageBox.Show($"generalNoteList changed from model.");
}
}
public viewModelObj(string name)
{
displayName = name;
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
The
ChangeRequestViewModel function executes the data loading and data binding:
class ChangeRequestViewModel
{
public ObservableCollection<ExcelDataEntry> generalNoteSource { get; set; } = new ObservableCollection<ExcelDataEntry>();
public ObservableCollection<viewModelObj> viewModelSource { get; set; } = new ObservableCollection<viewModelObj>();
public ChangeRequestViewModel()
{
List<ExcelDataEntry> dataPool = Default.GenerateDataPool("data.xlsx", 1, 4, 1, 71, 5);
foreach (var entry in dataPool.Where(x => x.note == "GN").ToList())
{
this.generalNoteSource.Add(entry);
}
CatDocFactory catDocFactory = new CatDocFactory();
foreach (var entry in catDocFactory.GetAllOpenedDocs())
{
this.viewModelSource.Add(new viewModelObj(entry.displayName));
}
}
}
The XAML is:
...
<Window.DataContext>
<changeRequestVM:ChangeRequestViewModel/>
</Window.DataContext>
...
<ListBox x:Name="catDocListView" Grid.Column="0" Grid.RowSpan="2" Margin="16" ItemContainerStyle="{StaticResource ContainerStyle}" ItemsSource="{Binding viewModelSource}" DisplayMemberPath="displayName"/>
...
<DataGrid x:Name="generalNoteDG" CanUserAddRows="False" AutoGenerateColumns="False" ItemsSource="{Binding generalNoteSource}">
<DataGrid.Columns>
<DataGridCheckBoxColumn Binding="{Binding isChecked, UpdateSourceTrigger=PropertyChanged}"/>
<DataGridTextColumn Header="Note" Binding="{Binding note}" Width="Auto"/>
</DataGrid.Columns>
</DataGrid>
...
The DataContext has been set to the viewModel in the main window initialization function:
this.DataContext = changeRequestDataContext;
Expected:
Situation is no matter which item in the Listbox is selected, the data content in the data grid reamins the unchanged. But I can select the data row under each selection of a Listbox item. Assuming I select the first item and select the first row of data grid then select the second item with the second row of the data grid. Expected is that in the backend, the note list of first item should have the first data row object in the note list property and the note list of second item should have the second data row object in the note list property.
You can imagine that the Datagrid is a data pool for selection.
How could I set the property of the
DataGrid,
DataGridTextColumn and
DataGridCheckBoxColumn and code in the backend?
Thank you guys for the help.
What I have tried:
I have googled for solutions but most of them bind the ItemsSource to the list of objects. In my case I need to set the data source of Datagrid to a List of data object and the List of viewModelObj is another thing but needs to contain the selection result of each element in the list.