This is a migrated thread and some comments may be shown as answers.

Delegatecommand inside GridView is not working

5 Answers 158 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Clas Ericson
Top achievements
Rank 2
Clas Ericson asked on 04 Oct 2011, 03:40 PM
Hi,
I'm having difficulties in creating a button column in a RadGridView. The problem is that it seems like each button is not connected to any command in the viewmodel because nothing happens when clicking on the buttons.
I have followed several threads on this forum and the Telerik documentation but nothing has helped me. Does anyone have a clue what's wrong?

Regards, Clas

VIEW
<UserControl 
    x:Class="XYZ.Views.MonthReport.MonthReportView"
    xmlns:local="clr-namespace:XYZ.Views.MonthReport">
     
 
     
    <Grid x:Name="LayoutRoot" MaxWidth="1200">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
 
         
        <telerik:RadGridView x:Name="MonthReportGrid"
                             Grid.Row="2"
                             IsBusy="{Binding IsLoading}"
                             ItemsSource="{Binding SelectList}"
                             SelectedItem="{Binding SelectedItem, Mode=TwoWay}">
            <telerik:RadGridView.Columns>
                <!-- Other columns have been left out clearer code -->
                <telerik:GridViewColumn Header="Mätarbyte" >
                    <telerik:GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <telerik:RadButton x:Name="btnCounterChange" Content="Lägg till"
                                   Command="{Binding ShowDialogCommand}"
                                   CommandParameter="{Binding counterId}" />
                        </DataTemplate>
                    </telerik:GridViewColumn.CellTemplate>
                </telerik:GridViewColumn>
            </telerik:RadGridView.Columns>
        </telerik:RadGridView>
        <StackPanel Orientation="Horizontal" Grid.Row="3" Margin="0,5">
            <telerik:RadButton x:Name="btnSaveMonthReport" Content="Spara inrapportering" Command="{Binding SaveMonthReportCommand}" />           
        </StackPanel>       
    </Grid>
</UserControl>
VIEW CODEBEHIND
using System;
using System.Collections.Generic;
using System.Windows.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Windows.Controls;
using System.Windows;
using Telerik.Windows.Controls;
using Telerik.Windows.Controls.GridView;
 
 
namespace XYZ.Views.MonthReport
{
 
    public partial class MonthReportView : UserControl, IMonthReportView
    {
        private IEnumerable<GridViewColumn> columnSelectorSource = null;
        public IEnumerable<GridViewColumn> ColumnSelectorSource
        {
            get { return columnSelectorSource; }
            set { columnSelectorSource = value; }
        }
 
        /// <summary>
        /// ViewModel attached to the View
        /// </summary>
        public IMonthReportViewModel Model
        {
            get {   return this.DataContext as IMonthReportViewModel; }
            set {   this.DataContext = value; }
        }
         
        /// <summary>
        /// Default constructor
        /// </summary>
        public MonthReportView()
        {
            InitializeComponent();     
        }
 
}

VIEWMODEL
using System;
 
 
namespace XYZ.Views.MonthReport
{
    public class MonthReportViewModel : ViewModel<IMonthReportView>, IMonthReportViewModel
    {
 
        /// <summary>
        /// Event aggregator
        /// </summary>
        private readonly IEventAggregator eventAggregator;
        /// <summary>
        /// Service principal
        /// </summary>
        private readonly IMonthReportService dataService;
        /// <summary>
        /// data Controller
        /// </summary>
        private readonly IMonthReportController dataController;
        /// <summary>
        /// Unity container
        /// </summary>
        private readonly IUnityContainer container;
        private bool isCounterChangeDialogOpen = false;
 
        #endregion
        public IUnityContainer Container
        {
            get
            {
                return container;
            }
        }
        private bool isLoading;
        public bool IsLoading
        {
            get
            {
                return isLoading;
            }
            set
            {
                if (isLoading != value)
                {
                    isLoading = value;
                    Notify(() => this.IsLoading);
                }
            }
        }
 
        private MonthReportEntity _selectedItem;
        public MonthReportEntity SelectedItem
        {
            get
            {
                return _selectedItem;
            }
            set
            {
                if (_selectedItem != value)
                {
                    _selectedItem = value;
                    Notify(() => this.SelectedItem);
                }
            }
        }
        private MonthReportEntityCollection _selectList;
        public MonthReportEntityCollection SelectList
        {
            get
            {
                return _selectList;
            }
            set
            {
                if (_selectList != value)
                {
                    _selectList = value;
                    Notify(() => this.SelectList);
                }
            }
        }
 
 
        //This one's not working
        private DelegateCommand _showDialogCommand;
        public DelegateCommand ShowDialogCommand
        {
            get {
                if (_showDialogCommand == null)
                {
                    _showDialogCommand = new DelegateCommand((o) =>
                    {
                        OnShowDialog(o as object);
                    });
                }
                return _showDialogCommand;
            }
            set
            {
                _showDialogCommand = value;
                Notify(() => this.ShowDialogCommand);
            }
        }
 
        //This one's working
        private DelegateCommand _saveMonthReportCommand;
        public DelegateCommand SaveMonthReportCommand
        {
            get {
                return _saveMonthReportCommand;
            }
            set
            {
                _saveMonthReportCommand = value;
                Notify(() => this.SaveMonthReportCommand);
            }
        }
 
 
 
        /// <summary>
        /// Default constructor
        /// </summary>
        /// <param name="view"></param>
        /// <param name="eventAggregator"></param>
        /// <param name="dataService"></param>
        /// <param name="dataController"></param>
        /// <param name="container"></param>
        public MonthReportViewModel(IMonthReportView view,
            IEventAggregator eventAggregator, IUnityContainer container, IMonthReportService dataService, IMonthReportController dataController)
        {
             
            this.eventAggregator = eventAggregator;
            this.dataController = dataController;
            this.dataService = dataService;
            this.container = container;
            this.View = view;
            this.View.Model = this;
 
            dataService.onGetMonthReportComplete += new EventHandler<MonthReportEventArgs>(OnGetMonthReportComplete);
            dataService.onSaveMonthReportComplete += new EventHandler<MonthReportEventArgs>(OnSaveMonthReportComplete);
             
            InitializeData();
            InitializeCommands();
        }
 
        // Initializing methods
        public void InitializeCommands()
        {
            this.ShowDialogCommand = new DelegateCommand((o) =>
            {
                OnShowDialog(o as object);
            });
            this.SaveMonthReportCommand = new DelegateCommand(this.SaveMonthReport, this.CanSaveMonthReport);
        }
 
        public void InitializeData()
        {        
            GetMonthReport();           
        }
         
        //Methods for handling the dialog
 
        //This method is never called. I have checked with breakpoints.
        public void OnShowDialog(object args)
        {
            if (!isCounterChangeDialogOpen)
            {
                if ((SelectedItem == null) || ((int) args != SelectedItem.counterId))
                {
                    SelectedItem = SelectList.GetEntityWithId((int)args);
                }
                 
                var dialog = this.Container.Resolve<ICounterChangeDialogViewModel>();
                dialog.ConfirmAction = new Action<ICounterChangeDialogViewModel, bool?>(this.OnConfirm);
                CreateCounterChange();
                dialog.SelectedMRE = this.SelectedItem;
                dialog.View.Show();
                isCounterChangeDialogOpen = true;
            }
        }
        public void OnConfirm(ICounterChangeDialogViewModel sender, bool? confirmResult)
        {
            if (confirmResult != null)
            {
                if ((bool)confirmResult)
                {
                    //Yet to be implemented
                }
            }
            sender.Clean();
            isCounterChangeDialogOpen = false;
        }
 
 
 
        //Methods for fetching the data via WCF
        public void GetMonthReport()
        {
            this.IsLoading = true;
            dataService.GetMonthReport();
        }
 
        public bool CanSaveMonthReport()
        {
            return (isCounterChangeDialogOpen) ? false : true;
        }
 
        public void SaveMonthReport()
        {
            this.IsLoading = true;
            dataService.SaveMonthReport(SelectList);           
        }
 
        void OnGetMonthReportComplete(object sender, MonthReportEventArgs e)
        {
            if (!e.HasError)
                this.SelectList = e.MonthReportData;
            else
            {
                this.SelectList = null;
                eventAggregator.GetEvent<ErrorEvent>().Publish(new ErrorEvent
                {
                    Message = e.Error.ToString(),
                    ExceptionObj = e.Error
                });
            }
 
            this.IsLoading = false;
        }
 
        void OnSaveMonthReportComplete(object sender, MonthReportEventArgs e)
        {
            if (!e.HasError)
            {
                eventAggregator.GetEvent<MessageShowEvent>().Publish(new MessageShowEvent
                    {
                        MessageTitle = "Bekräftelse",
                        Message = "Månadsrapporteringen sparades."
                    });
            }
            else
            {
                this.SelectList = null;
                eventAggregator.GetEvent<ErrorEvent>().Publish(new ErrorEvent
                {
                    Message = e.Error.ToString(),
                    ExceptionObj = e.Error
                });
            }
 
            this.IsLoading = false;
        }
 
 
        public override void Clean()
        {
            base.Clean();
        }
 
    }
}

5 Answers, 1 is accepted

Sort by
0
Maya
Telerik team
answered on 05 Oct 2011, 06:51 AM
Hello Clas,

You can define your ViewModel in the Resources section of your UserControl for example and set the Source property of the Command binding afterwards. For example:

<UserControl.Resources>
    <local:MyViewModel x:Key="MyViewModel"/>
</UserControl.Resources>
<telerik:RadButton x:Name="btnCounterChange" Content="Lägg till"
                                   Command="{Binding ShowDialogCommand, Source={StaticResource MyViewModel}}"
                                   CommandParameter="{Binding counterId}" />



Regards,
Maya
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
Clas Ericson
Top achievements
Rank 2
answered on 07 Oct 2011, 12:39 PM
Hello Maya,
thanks for your suggestion but I have tried that and ended up with:
Error 48 Type 'MonthReportViewModel' is not usable as an object element because it is not public or does not define a public parameterless constructor or a type converter.

My viewmodel constructor wants the view, an AventAggregator, a UnityContainer, a WCF-service and a Controller as parameters. All Telerik examples, including yours has constructors without parameters in the viewmodel. Isn't there another way to make the view to know about the viewmodel? I have also tried to use the Views DataContext-property like this:
<telerik:RadButton x:Name="btnCounterChange" Content="Lägg till" Command="{Binding ShowDialogCommand, Source=DataContext}" CommandParameter="{Binding counterId}"  />

But with no success...

Regards, Clas
0
Accepted
Maya
Telerik team
answered on 07 Oct 2011, 01:12 PM
Hi Clas,

You could try to use a DataContextProxy for example. Please refer to this article for a reference.  

Kind regards,
Maya
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
Clas Ericson
Top achievements
Rank 2
answered on 07 Oct 2011, 01:57 PM
Sweet! The DataContextProxy made my day for sure! Thank you so much!

Regards, Clas
0
palak
Top achievements
Rank 1
answered on 06 Nov 2012, 10:59 AM
Hi Maya,

Same problem i was facing , wrapped commands in radgridview, and datacontext was dynamic.

DataContextProxy just saved my day.

Thanks,
palak

Tags
GridView
Asked by
Clas Ericson
Top achievements
Rank 2
Answers by
Maya
Telerik team
Clas Ericson
Top achievements
Rank 2
palak
Top achievements
Rank 1
Share this question
or