I am creating a small wpf programme which filters a dataset by date. It will eventually group and sum the data, but at the moment I am just trying to display the data rows. I want a window with a ComboBox
at the top with possible dates to select and a DataGrid
showing the correct records. I have bound the ComboBox
to a list of possible dates, and I have bound a label to the value that the ComboBox
updates. This label updates when I select a value from the ComboBox
. I cannot however get the DataGrid
to update to show the new data.
A DataSet
is passed to the ViewModel constructor which extracts two DataTables
. One is used to create an ObservableCollection<DateTime>
for the ComboBox
s items to bind to (through WorkItemsDates
). The other is stored for the DataGrid
to bind to via a filtering (and eventually grouping/summing etc.) property WorkItems
. The ComboBox
is bound to the DateTime
SelectedDate
. The label is also bound to SelectedDate
to ensure it is being updated by the ComboBox
The Xaml View is as follows:
<Window ...>
<DockPanel>
<ComboBox DockPanel.Dock="Top"
ItemsSource="{Binding WorkItemsDates}"
SelectedItem="{Binding SelectedDate, Mode=TwoWay}"
ItemStringFormat="ddd d MMM yyyy"
IsSynchronizedWithCurrentItem="True" />
<Label DockPanel.Dock="Bottom"
Content="{Binding SelectedDate, FallbackValue=99/99/9999}"
ContentStringFormat="dd MM yyyy" />
<DataGrid Name="TimeTotalsDataGrid" AutoGenerateColumns="True"
ItemsSource="{Binding WorkItems, Mode=OneWay}"
IsSynchronizedWithCurrentItem="True" ></DataGrid>
</DockPanel>
</Window>
And code behind:
public partial class TheView: Window
{
public UserControl1(DataSet tigerDataSet)
{
InitializeComponent();
DataContext = new TimeTotalsDateSelectorViewModel(tigerDataSet);
}
}
The ViewModel is as follows:
internal class TimeTotalsDateSelectorViewModel
{
private ObservableCollection<DateTime> _workItemsDates;
private DataTable _workItems;
private DateTime _selectedDate;
public TimeTotalsDateSelectorViewModel(DataSet tigerDataSet)
{
if (tigerDataSet == null)
throw new ArgumentNullException("workItemsDates");
if (tigerDataSet.Tables["WorkItemsDates"] == null)
throw new ArgumentNullException("tigerDataSet.Tables[WorkItemsDates]");
if (tigerDataSet.Tables["WorkItems"] == null)
throw new ArgumentNullException("tigerDataSet.Tables[WorkItems]");
_workItems = tigerDataSet.Tables["WorkItems"];
_workItemsDates = new ObservableCollection<DateTime>();
foreach (DataRow row in tigerDataSet.Tables["WorkItemsDates"].Rows)
{
_workItemsDates.Add((DateTime)row["FinishDate"]);
}
SelectedDate = _workItemsDates[0];
}
public ObservableCollection<DateTime> WorkItemsDates
{
get { return _workItemsDates; }
}
public DateTime SelectedDate
{
get { return _selectedDate; }
set { _selectedDate = value; }
}
public DataTable WorkItems
{
get
{
DataRow[] _workItemsToShow = _workItems.Select("FinishTime>='" + _selectedDate.ToString() + "' AND FinishTime<'" + _selectedDate.AddDays(1).ToString() + "'");
return _workItemsToShow.Count() != 0 ? _workItemsToShow.CopyToDataTable() : null;
}
}
First thing, as you are using MVVM
, so you will have to notify your properties by implementing INotifyPropertyChanged
interface.
Second from the Setter
of your SelectedItem
property you will have to notify your WorkItems
property as well, so that when you change the date from dropdown, it will also update the ItemsSource
of the DataGrid
.
In the setter of SelectedDate, call the code that gets the values for the grid. You should be implementing INotifyPropertyChanged as well, so the UI will update the data and the user can see it.
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.