c#MVVM在组合框选择后更新Datagrid
c# MVVM update Datagrid after combobox selection
我正在创建一个按日期过滤数据集的小型 wpf 程序。它最终将对数据进行分组和求和,但目前我只是想显示数据行。我想要一个 window,顶部有一个 ComboBox
,可能的日期为 select,DataGrid
显示正确的记录。我已将 ComboBox
绑定到可能日期的列表,并将标签绑定到 ComboBox
更新的值。当我 select 来自 ComboBox
的值时,此标签会更新。但是我无法让 DataGrid
更新以显示新数据。
A DataSet
被传递给 ViewModel 构造函数,它提取两个 DataTables
。一个用于为要绑定的 ComboBox
项创建 ObservableCollection<DateTime>
(通过 WorkItemsDates
)。另一个存储用于 DataGrid
通过过滤绑定到(最终 grouping/summing 等)属性 WorkItems
。 ComboBox
绑定到 DateTime
SelectedDate
。该标签还绑定到 SelectedDate
以确保它被 ComboBox
更新
Xaml视图如下:
<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>
后面的代码:
public partial class TheView: Window
{
public UserControl1(DataSet tigerDataSet)
{
InitializeComponent();
DataContext = new TimeTotalsDateSelectorViewModel(tigerDataSet);
}
}
ViewModel如下:
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;
}
}
在 SelectedDate 的 setter 中,调用获取网格值的代码。您还应该实施 INotifyPropertyChanged,因此 UI 将更新数据并且用户可以看到它。
首先,由于您正在使用 MVVM
,因此您必须通过实现 INotifyPropertyChanged
接口来通知您的属性。
从您的 SelectedItem
属性 的 Setter
开始,您还必须通知您的 WorkItems
属性,这样当您更改来自下拉列表的日期,它还会更新 DataGrid
的 ItemsSource
。
我正在创建一个按日期过滤数据集的小型 wpf 程序。它最终将对数据进行分组和求和,但目前我只是想显示数据行。我想要一个 window,顶部有一个 ComboBox
,可能的日期为 select,DataGrid
显示正确的记录。我已将 ComboBox
绑定到可能日期的列表,并将标签绑定到 ComboBox
更新的值。当我 select 来自 ComboBox
的值时,此标签会更新。但是我无法让 DataGrid
更新以显示新数据。
A DataSet
被传递给 ViewModel 构造函数,它提取两个 DataTables
。一个用于为要绑定的 ComboBox
项创建 ObservableCollection<DateTime>
(通过 WorkItemsDates
)。另一个存储用于 DataGrid
通过过滤绑定到(最终 grouping/summing 等)属性 WorkItems
。 ComboBox
绑定到 DateTime
SelectedDate
。该标签还绑定到 SelectedDate
以确保它被 ComboBox
Xaml视图如下:
<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>
后面的代码:
public partial class TheView: Window
{
public UserControl1(DataSet tigerDataSet)
{
InitializeComponent();
DataContext = new TimeTotalsDateSelectorViewModel(tigerDataSet);
}
}
ViewModel如下:
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;
}
}
在 SelectedDate 的 setter 中,调用获取网格值的代码。您还应该实施 INotifyPropertyChanged,因此 UI 将更新数据并且用户可以看到它。
首先,由于您正在使用 MVVM
,因此您必须通过实现 INotifyPropertyChanged
接口来通知您的属性。
从您的 SelectedItem
属性 的 Setter
开始,您还必须通知您的 WorkItems
属性,这样当您更改来自下拉列表的日期,它还会更新 DataGrid
的 ItemsSource
。