这个让我受伤;
我有一个WPF窗口,其中有两个(对于这种情况很重要)控件,都来自CodePlex提供的WPF工具包; DatePicker和DataGrid。
此窗口的DataContext设置为CLR对象,该对象具有所需的所有信息。这个CLR对象有一个庞大的数据列表,还有一个名为GetDataForDate(DateTime date)的方法,它决定了我们将看到数据的日期。
如何创建数据网格可以绑定到的ObjectDataProvider(我假设它是正确的解决方案),它提供对GetDataForDate()返回的数据的访问,并使用DatePicker的选定日期作为参数调用? / p>
换句话说,我希望用户使用日期选择器来选择日期,并且每当更改日期以反映正确的数据时,网格都应自动更新。
我需要做什么样的黑魔法来实现这样的目标 - 我猜这应该是一个相对常见的数据绑定场景?
提前致谢!
答案 0 :(得分:7)
这是我的完整代码。我希望这会有所帮助。
xaml代码:
<Window x:Class="DataGridSort.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dg="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit"
xmlns:System="clr-namespace:System;assembly=mscorlib"
Title="Window1" Height="413" Width="727"
x:Name="_this">
<Window.Resources>
<ObjectDataProvider ObjectInstance="_this.DataContext"
MethodName="GetFromDate"
x:Key="odp">
<ObjectDataProvider.MethodParameters>
<System:DateTime>2008-01-01</System:DateTime>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<dg:DatePicker Grid.Row="0" x:Name="dtpSource" >
<dg:DatePicker.SelectedDate>
<Binding Source="{StaticResource odp}"
Path="MethodParameters[0]"
BindsDirectlyToSource="True"
Mode="OneWayToSource"/>
</dg:DatePicker.SelectedDate>
</dg:DatePicker>
<dg:DataGrid x:Name="dtgGrid"
ItemsSource="{Binding Source={StaticResource odp}}"
AutoGenerateColumns="True"
Grid.Row="1"/>
</Grid>
</Window>
背后的代码:
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
LoadData();
}
protected void LoadData()
{
DataContext = new Data();
ObjectDataProvider odp = this.Resources["odp"] as ObjectDataProvider;
odp.ObjectInstance = DataContext;
}
}
和业务对象:
public class DataItem
{
public string Name { get; set; }
public int BirthYear { get; set; }
}
public class Data
{
private readonly List<DataItem> data;
public Data()
{
data = new List<DataItem>();
data.Add(new DataItem { Name = "John", BirthYear = 2007 });
data.Add(new DataItem { Name = "Mike", BirthYear = 2007 });
data.Add(new DataItem { Name = "Aaron", BirthYear = 2006 });
data.Add(new DataItem { Name = "Bill", BirthYear = 2006 });
data.Add(new DataItem { Name = "Steven", BirthYear = 2005 });
data.Add(new DataItem { Name = "George", BirthYear = 2004 });
data.Add(new DataItem { Name = "Britany", BirthYear = 2004 });
}
public List<DataItem> GetFromDate(DateTime dt)
{
return this.data.Where(d => d.BirthYear == dt.Year).ToList();
}
}
答案 1 :(得分:1)
您可以在DatePicker.SelectedDate属性上设置OneWayToSource绑定,该属性将文本值推送到ObjectDataProvider MethodParameter。
首先创建ObjectDataProvider:
<ObjectDataProvider ObjectType="{x:Type theObjectType}"
MethodName="GetDataForDate"
x:Key="odp">
<ObjectDataProvider.MethodParameters>
<System:DateTime>2008-01-01</System:DateTime>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
然后将DatePicker的SelectedDate属性绑定到ObjectDataProvider:
<dg:DatePicker x:Name="datePicker" >
<dg:DatePicker.SelectedDate>
<Binding Source="{StaticResource odp}"
Path="MethodParameters[0]"
BindsDirectlyToSource="True"
Mode="OneWayToSource"/>
</dg:DatePicker.SelectedDate>
</dg:DatePicker>
最后将ObjectDataProvider绑定到ObjectDataProvider:
<dg:DataGrid x:Name="dtgGrid"
ItemsSource="{Binding Source={StaticResource odp}}"
AutoGenerateColumns="False"/>
答案 2 :(得分:1)
我们应该注意的一件事是DatePicker的SelectedDate属性返回一个可为空的DateTime(这意味着:DateTime?而不仅仅是DateTime)。 我提出这个问题的原因是因为如果你的方法签名包含简单的DateTime,WPF将返回一个错误,如Rune Jacobsen所示,因为它无法找到正确的方法签名。
HTH!伟大的文章BTW
答案 3 :(得分:0)
如果你用这样的INotifyPropertyChanged构建你的类:
public class MyDataObject : INotifyPropertyChanged
{
private DateTime _SelectedDate;
public DateTime SelectedDate
{
get
{
return _SelectedDate;
}
set
{
_SelectedDate = value;
NotifyPropertyChanged("SelectedDate");
GetDataForDate();
}
}
private ObservableCollection<YourDataType> _Data;
public ObservableCollection<YourDataType> Data
{
get
{
return _Data;
}
set
{
_Data = value;
NotifyPropertyChanged("Data");
}
}
public void GetDataForDate()
{
// Your code here to fill the Data object with your data
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
然后,您可以在XAML中创建ObjectDataProvider并直接绑定到它。在您的资源中:
<ObjectDataProvider x:Key="MyDataSource" ObjectType="{x:Type local:MyDataObject}" />
然后绑定:
<DockPanel>
<toolkit:DatePicker SelectedDate="{Binding Path=SelectedDate, Mode=Default, Source={StaticResource MyDataSource}}"/>
<toolkit:DataGrid ItemsSource="{Binding Path=Data, Mode=Default, Source={StaticResource MyDataSource}}"/>
</DockPanel>