Este me ha latido;

Tengo una ventana WPF con dos (importante para este caso), los controles, tanto desde el WPF toolkit disponible en CodePlex; cuenta con Un calendario y un control DataGrid.

El DataContext de esta ventana se establece en un objeto CLR que tiene toda la información que necesita. Este objeto CLR tiene una gran lista de datos, y un método llamado GetDataForDate( DateTime fecha ) que decide qué fecha vamos a ver los datos de.

¿Cómo puedo crear un ObjectDataProvider (que supongo será la solución correcta) de que el datagrid puede enlazar, que proporciona acceso a los datos devueltos por GetDataForDate() se llama con la fecha seleccionada en el selector de fechas como el parámetro?

En otras palabras, quiero que el usuario utilice el selector de fecha para seleccionar una fecha, y la cuadrícula debe actualizar automáticamente cada vez que se cambia la fecha para reflejar los datos correctos.

¿Qué clase de magia negra ¿que tengo que hacer para lograr algo como esto – que me imagino que debe ser un fenómeno relativamente común de enlace de datos escenario?

Gracias de antemano!

4 Comentarios

  1. 7

    Aquí está mi código completo. Espero que esto ayude.

    El código 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>

    El código detrás de:

    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;
        }
    }

    y el objeto de negocio:

    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();
        }
    }
    • Puedo casar a tu cerebro!? Que trabajó en la diferencia de donde yo me encontraba, era, básicamente, que yo no intenta establecer la Instancia_objeto a través de código. Muchas gracias por la ayuda!
    • Si no desea mostrar todos los datos, ¿qué debo hacer? Por ejemplo, en este caso yo sólo quiero ver el «Nombre» de la col, no quiere ver el «Año», col. He intentado añadir los nombres a una lista de cadenas y regresar a la lista, pero lo que veo es una col, «Longitud» y yo no sé dónde está el «Longitud» vino de!
  2. 1

    Se podría configurar una OneWayToSource de unión en el selector de fechas.Propiedad SelectedDate que empuja el valor de texto en el ObjectDataProvider MethodParameter.

    Comienza con la creación de la ObjectDataProvider:

       <ObjectDataProvider ObjectType="{x:Type theObjectType}" 
                            MethodName="GetDataForDate"
                            x:Key="odp">
            <ObjectDataProvider.MethodParameters>
                <System:DateTime>2008-01-01</System:DateTime>  
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>

    A continuación, enlazar la propiedad SelectedDate de el selector de fecha para la 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>

    Y, finalmente, se unen los ObjectDataProvider a su ObjectDataProvider:

    <dg:DataGrid x:Name="dtgGrid"
                 ItemsSource="{Binding Source={StaticResource odp}}"
                 AutoGenerateColumns="False"/>
    • Wow, eso fue.. No obvio.. 😉 Gracias, creo que puedo conseguir el quid de la cuestión. Sin embargo, tengo un montón de excepciones, se intenta crear una instancia de un objeto del tipo especificado – ¿cómo puedo hacer para usar el no-objeto estático representado por mi DataContext?
    • Quitar el ObjectType propiedad del XAML y asignar el DataContext para Instancia_objeto. <Ventana de x:Class=»DataGridSort.Window1″ … x:Name=»esto» /> Usted debe dar un nombre a la ventana. Entonces: <ObjectDataProvider Instancia_objeto=»esto.DataContext» MethodName=»GetFromDate» x:Key=»pao»>…
  3. 1

    Una cosa que debe tener en cuenta es que la propiedad SelectedDate del selector de fecha se devuelve un aceptan valores null DateTime (que significa: DateTime? en lugar de simplemente DateTime).
    La razón por la que trajo esto es debido a que si su método de firma contiene simple DateTime, WPF devolverá un mensaje de error como se muestra por la Runa Jacobsen, porque no puede encontrar el método correcto de la firma.

    HTH! Gran artículo BTW

  4. 0

    Si usted construye su clase con INotifyPropertyChanged como este:

    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
    }

    A continuación, puede crear su ObjectDataProvider en XAML y se unen directamente a ella. En sus recursos:

    <ObjectDataProvider x:Key="MyDataSource" ObjectType="{x:Type local:MyDataObject}" />

    Y, a continuación, enlazar:

    <DockPanel>
        <toolkit:DatePicker SelectedDate="{Binding Path=SelectedDate, Mode=Default, Source={StaticResource MyDataSource}}"/>
        <toolkit:DataGrid ItemsSource="{Binding Path=Data, Mode=Default, Source={StaticResource MyDataSource}}"/>
    </DockPanel>

Dejar respuesta

Please enter your comment!
Please enter your name here