I have a model called TimeSheetByEmployeeModel
that is implemented with INotifyPropertyChanged
.
Model:
public class TimeSheetByEmployeeModel:INotifyPropertyChanged
{
//public string EmpID { get; set; }
string _EmpID;
public string EmpID
{
get
{
return _EmpID;
}
set
{
if (_EmpID != value)
{
_EmpID = value;
RaisePropertyChange("EmpID");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChange(string prop)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(prop));
}
}
}
ViewModel:
ObservableCollection<TimeSheetByEmployeeModel> _TimeSheetList = new ObservableCollection<TimeSheetByEmployeeModel>();
public ObservableCollection<TimeSheetByEmployeeModel> TimeSheetList
{
get
{
return _TimeSheetList;
}
set
{
_TimeSheetList = value;
}
}
View Code-Behind:
public TimeSheetByEmployee()
{
InitializeComponent();
this.DataContext = this;
}
View:
<DataGrid ItemsSource="{Binding TimeSheetList,UpdateSourceTrigger=PropertyChanged}"
AutoGenerateColumns="False"
CanUserAddRows="False"
x:Name="timesheetgrid"
HeadersVisibility="All"
RowHeaderWidth="20">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding EmpID,UpdateSourceTrigger=PropertyChanged}"
Header="EmpID"
IsReadOnly="True"
Width="100"/>
</DataGrid.Columns>
</DataGrid>
When I click a button inside the View it calls this method:
private void Ok_Click(object sender, RoutedEventArgs e)
{
try
{
TimeSheetList.Clear();
string EmployeeID = cboemployee.SelectedValue.ToString();
TimeSheetList = TimeSheetByEmployeeDataAccessor.GetTimeSheetByEmployee_ByFromTo(dtpfrom.SelectedDate.GetValueOrDefault(), dtpto.SelectedDate.GetValueOrDefault(), EmployeeID);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
I dynamically changed TimeSheetList
and it should reflect in the datagrid. I developed another form using this structure and it worked fine. However, in this form, when I change TimeSheetList
it does not update the datagrid.
What have I researched?
Firstly, I bound some data to TimeSheeList
in the view constructor and it's shown in the datagrid. So I assumed binding TimeSheetList
to the datagrid works.
Secondly, I changed some code in the Button Click Event:
private void Ok_Click(object sender, RoutedEventArgs e)
{
try
{
TimeSheetList.RemoveAt(0);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
This code is works perfectly and removes the first row in the datagrid. So I assumed the datagrid itemsource is dynamically changing.
But why does it not update with my original code?
More research,
I added code to the button:
timesheetgrid.ItemsSource = TimeSheetList;
I know it will work, and it does, but normally I don't databind to the datagrid in code-behind and I always databind in the XAML. It always works, but why doesn't it work here?
Update
If I add Mode=TwoWay
to the ItemsSource databinding in the datagrid in xaml while debugging like this:
<DataGrid
ItemsSource="{Binding TimeSheetList,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"
AutoGenerateColumns="False"
CanUserAddRows="False"
x:Name="timesheetgrid"
HeadersVisibility="All"
RowHeaderWidth="20">
It works and the datagrid shows data. So I saved and restarted the debugging process and it stops working again.
this line:
TimeSheetList = TimeSheetByEmployeeDataAccessor.GetTimeSheetByEmployee_ByFromTo(dtpfrom.SelectedDate.GetValueOrDefault(), dtpto.SelectedDate.GetValueOrDefault(), EmployeeID);
creates a new collection and there is no notification in setter about change:
set
{
_TimeSheetList = value;
}
I suggest to avoid changing collection and add items to existing collection:
var items = TimeSheetByEmployeeDataAccessor.GetTimeSheetByEmployee_ByFromTo(dtpfrom.SelectedDate.GetValueOrDefault(), dtpto.SelectedDate.GetValueOrDefault(), EmployeeID);
TimeSheetList.Clear();
foreach(var item in items)
TimeSheetList.Add(item);
... or if you prefer to change collection (like it is done now), then raise notification
set
{
_TimeSheetList = value;
RaisePropertyChange("TimeSheetList");
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.