Multiple parameters from xaml

Topics: Prism v2 - Silverlight 4
Dec 10, 2010 at 1:05 PM

 

I am a newbie and I have a start date and end date on my xaml page. However the delegatecommand does not accept 2 parameters. 
How could go I about accessing both of these parameters in other modules which subscribe to this event. 


    public class DateRangeViewModel :INotifyPropertyChanged
    {
        IEventAggregator eventAggregator;

        public ICommand RefreshDashboard { get; private set; }
        
        public DateRangeViewModel(IEventAggregator eventAggregator)
        {
            this.StartDate = DateTime.Now.AddDays(-30).ToShortDateString();
            this.EndDate = DateTime.Now.ToShortDateString();
            this.Refresh = new DelegateCommand<string>(OnGoClick);
            this.eventAggregator = eventAggregator;
        }

        public void OnGoClick(string objDateRange)
        {
            eventAggregator.GetEvent<DateRangeEvent>().Publish(objDateRange);
        }

        private string startDate;
        /// <summary>
        /// Gets or sets the start date of the currently selected period.
        /// </summary>
        public string StartDate
        {
            get
            {
                return this.startDate;
            }
            set
            {
                if (this.startDate != value)
                {
                    this.startDate = value;
                    OnPropertyChanged("StartDate");
                }
            }
        }

        private string endDate;
        /// <summary>
        /// Gets or sets the end date of the currently selected period.
        /// </summary>
        public string EndDate
        {
            get
            {
                return this.endDate;
            }
            set
            {
                if (this.endDate != value)
                {
                    this.endDate = value;
                    OnPropertyChanged("EndDate");
                }
            }
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion


XAML code:
 <sdk:DatePicker Text="{Binding Path=StartDate,Mode=TwoWay}" />
 <sdk:DatePicker Text="{Binding Path=EndDate,Mode=TwoWay}"/>
  <Button Content="Go" Commands:Click.Command="{Binding Refresh}"
                    Commands:Click.CommandParameter="{Binding Path=EndDate}"/>


 

Developer
Dec 10, 2010 at 1:49 PM
Edited Dec 10, 2010 at 1:50 PM

Hi,

A possible way to achieve this would be to create a new type (for example, called DateRange) which would contain two strings. Then, you could create a DelegateCommand<DateRange>, and pass a parameter of type DateRange as the Command Parameter.

You could read more about Commanding in this section of the Prism documentation.

I hope you find this helpful.

Guido Leandro Maliandi
http://blogs.southworks.net/gmaliandi

 

Dec 10, 2010 at 3:08 PM

Thanks for the reply. I now have a class DateRange which has two other string types. How would I be referencing an object of this class in the xaml to bind to the datePicker and pass it in the CommandParameter.

Dec 10, 2010 at 4:32 PM

Hi,

One way to pass multiple bindings to a command is to use the MultiBinding class.  It allows you to easily bind multiple values available from multiple sources into any binding.  I have found it most useful in command parameter cases.   MSDN documentation is here: http://msdn.microsoft.com/en-us/library/system.windows.data.multibinding.aspx.

You'll need to use XAML elements to specify it rather than a single binding string (per the MSDN docs):

<TextBlock Name="textBox2" DataContext="{StaticResource NameListData}">
  <TextBlock.Text>
    <MultiBinding Converter="{StaticResource myNameConverter}"
                  ConverterParameter="FormatLastFirst">
      <Binding Path="FirstName"/>
      <Binding Path="LastName"/>
    </MultiBinding>
  </TextBlock.Text>
</TextBlock>

Another option is to bind the calendar date to the the command parameter, then use that date as an index to look up the other data your command needs.  You would need to create a structure or dictionary that contains the data you need keyed by date.


Hope this is helpful,

Geoff Cox
http://blogs.southworks.net/geoff

 

Dec 10, 2010 at 6:00 PM

I get the below error when I insert MultiBinding tag in my xaml code.

"The type 'MultiBinding' was not found. verify that you are not missing an assembly reference and that all referenced assemblies have been built."

Dec 11, 2010 at 4:59 AM

Why do you even need a DateRange class? Since Start and End dates are bound with twoway mode your view model is going to have the updated values. So you dont need to send a command parameter to your command. Instead when your command gets called you can build the daterange in your OnGoClick using your StartDate and Enddate properties in your view model.

I dont think you should always make use of CommandParameters. In cases like this you have updated properties in your view model so you can directly access them.

Dec 13, 2010 at 2:41 PM
Edited Dec 13, 2010 at 3:08 PM

Thanks for your help gan s. This seems to work however the string parameter on my delgate call to button click seems useless. Can I get rid of the parameter in the code below in the DelegateCommand

this.RefreshDashboard = new DelegateCommand<string>(OnGoClick);

and on the click event handler.

Dec 13, 2010 at 2:45 PM

That is fine. You cant avoid that as DelegateCommand is a generic.

You could probably have it as

this.RefreshDashboard = new DelegateCommand<object>(OnGoClick); 

instead.

Cheers.

Dec 13, 2010 at 3:12 PM

Ok will do. Thanks all for your help.