0

I am quite new to XMAL but have managed to cobble together a form that retrieves data from SQL and populates a data grid. To extend this I want to only return data based on two dates. I have created a method GetAllActionLogsBetweenDates() this takes two properties QueryFromDate, QueryToDate.

I need to pass the 2 dates from the date pickers to the GetAllActionLogsBetweenDates method when the FindButton is clicked.

My XAML looks like this

<StackPanel Height="114" 
                    Orientation="Vertical"
                    HorizontalAlignment="Left" 
                    Name="StackPanel1" 
                    VerticalAlignment="Top" 
                    Width="507">
            <DatePicker Height="25"
                        SelectedDate="{Binding QueryFromDate, Mode=TwoWay}" 
                        HorizontalAlignment="Left" 
                        VerticalAlignment="Top"
                        Width="115"
                        x:Name="DateFrom"
                        Margin="5"/>
            <DatePicker Height="25"
                        SelectedDate="{Binding QueryToDate, Mode=TwoWay}"                        
                        HorizontalAlignment="Left" 
                        VerticalAlignment="Top" 
                        Width="115"
                        Margin ="5 "
                        x:Name="DateTo"/>
            <Button Content="Find"
                    x:Name="FindButton"
                    Command="{Binding ?????}"
                    Height="23" 
                    Margin="5"
                    Width="75" 
                    HorizontalAlignment="Left" />
        </StackPanel>

I think I have to do something in the Command="{Binding ?????}" element referencing my method and presumably the 2 properties QueryFromDate, QueryToDate but I am not sure what

Thanks

Ross
  • 325
  • 1
  • 3
  • 18
  • 1
    If your bindings are working, your dates should already be in QueryFromDate and QueryToDate. If you're using MVVM and a ViewModel file (instead of the codebehind), it can sometimes be easier to use an MVVM framework that implements ICommand for you. Otherwise, you could just use the `Click=""` event on the button. – Will Eddins Dec 12 '14 at 15:46

2 Answers2

0

If you're using a ViewModel, you'll need to implement ICommand and create a Command in your ViewModel class.

This question has an example implementation you could use: How to bind WPF button to a command in ViewModelBase?

Alternatively, if you're just using your codebehind (.xaml.cs), you can use the Click event:

<Button Content="Find" Click="FindClicked" />

You'd then add the FindClicked method into your codebehind:

void FindClicked(object sender, RoutedEventArgs e) { }
Community
  • 1
  • 1
Will Eddins
  • 13,628
  • 5
  • 51
  • 85
0

If you're using MVVM, you first need to define the RelayCommand object that implements ICommand like so:

public class RelayCommand : ICommand
{
    private Predicate<object> m_canExecute;
    private Action<object> m_execute;

    public RelayCommand(Action<object> execute)
    {
        m_execute = execute;
    }

    public RelayCommand(Predicate<object> canExecute, Action<object> execute)
    {
        m_canExecute = CanExecute;
        m_execute = execute;
    }

    public bool CanExecute(object parameter)
    {
        if (m_canExecute == null)
        {
            return true;
        }

        return m_canExecute(parameter);
    }

    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter)
    {
        if (m_execute != null)
        {
            m_execute(parameter);
        }
    }
}

You then need to create a command for your button in the ViewModel. Something like this:

public class MainViewModel : INotifyPropertyChanged
{
    // INotifyPropertyChanged implementation

    public ICommand GetAllActionLogsBetweenDatesCommand { get; set; }

    public MainViewModel()
    {
        GetAllActionLogsBetweenDatesCommand = new RelayCommand(GetAllActionLogsBetweenDates_Execute);
    }

    private void GetAllActionLogsBetweenDates_Execute(object parameter)
    {
        try
        {
            var stringList = parameter as string[];

            DateTime fromDate = DateTime.Parse(stringList[0]);
            DateTime toDate = DateTime.Parse(stringList[1]);
            // Query the data.
        }
        catch (Exception ex)
        {

        }
    }
}

Now since you want to pass multiple parameters to the command, you can use an IMultiValueConverter to get the two dates selected and pass them to the ViewModel. This is how the converter would look like:

public class ICommandMultiDateConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return new string[] { values[0].ToString(), values[1].ToString() };
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

And finally, in your XAML you create an instance of this converter and bind it to your button:

<Window.Resources>
    <myNamespace:ICommandMultiDateConverter x:Key="multiDateConverter"/>
</Window.Resources>

<DatePicker Name="fromDatePicker"></DatePicker>
<DatePicker Name="toDatePicker"></DatePicker>
<Button Content="Hello World">
    <Button.CommandParameter>
        <MultiBinding Converter="{StaticResource ResourceKey=multiDateConverter}">
            <Binding ElementName="fromDatePicker" Path="Text"></Binding>
            <Binding ElementName="toDatePicker" Path="Text"></Binding>
        </MultiBinding>
    </Button.CommandParameter>
    <Button.Command>
        <Binding Path="GetAllActionLogsBetweenDatesCommand"></Binding>
    </Button.Command>
</Button>
Arian Motamedi
  • 7,123
  • 10
  • 42
  • 82