I am currently working on a WPF project using MVVM.
I am trying to bind commands in the ViewModel to buttons in a column of the xamdatagrid. But seems unable to fire the command when the button is clicked.
Please see following codes:
View:
<UserControl x:Class="Ratebooks.Modules.Tiers.TiersView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:igDP="clr-namespace:Infragistics.Windows.DataPresenter;assembly=InfragisticsWPF4.DataPresenter.v12.1" xmlns:igEditors="clr-namespace:Infragistics.Windows.Editors;assembly=InfragisticsWPF4.Editors.v12.1" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300"> <Grid> <Grid.Resources> <Style TargetType="{x:Type igDP:CellValuePresenter}" x:Key="RemoveButton"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type igDP:CellValuePresenter}"> <Grid Width="{TemplateBinding Width}" Height="{TemplateBinding Height}"> <Button Content="Remove" Margin="5,5,5,5" Command="{Binding RemoveTierCommand}"/> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> </Grid.Resources> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition /> </Grid.ColumnDefinitions> <igDP:XamDataGrid Grid.Row="0" DataSource="{Binding TierGroupsList}" Name="xdgTierGroups" AutoFit="True" IsSynchronizedWithCurrentItem="True" ActiveRecord="{Binding SelectedRecord,Mode=TwoWay}" ActiveDataItem="{Binding SelectedDataItem}"> <igDP:XamDataGrid.Resources> <Style TargetType="{x:Type igDP:DataRecordPresenter}" x:Key="IndentStyle"> <Setter Property="Margin" Value="80,0,0,0"/> </Style> </igDP:XamDataGrid.Resources> <igDP:XamDataGrid.FieldLayouts> <igDP:FieldLayout> <igDP:Field Name="GroupDescription" Label="Tier Group"></igDP:Field> </igDP:FieldLayout> <igDP:FieldLayout> <igDP:FieldLayout.Settings> <igDP:FieldLayoutSettings DataRecordPresenterStyle="{StaticResource IndentStyle}"/> </igDP:FieldLayout.Settings> <igDP:Field Name="Tier" Label="Tier"></igDP:Field> <igDP:Field Name="TierDescription" Label="Description"></igDP:Field> <igDP:UnboundField Name="Action" Label="Action"> <igDP:UnboundField.Settings> <igDP:FieldSettings CellValuePresenterStyle="{StaticResource RemoveButton}" /> </igDP:UnboundField.Settings> </igDP:UnboundField> <igDP:Field Name="TierID" Visibility="Hidden"></igDP:Field> </igDP:FieldLayout> </igDP:XamDataGrid.FieldLayouts> </igDP:XamDataGrid> </Grid></UserControl>
Codes behind:
public partial class TiersView : UserControl { public TiersView() { InitializeComponent(); this.DataContext = new TiersViewModel(); } }
ViewModel:
namespace Ratebooks.Modules.Tiers{ public class TiersViewModel:BaseViewModel { private IUnionContractsService _unionContractsService; private IUnionCodesService _unionCodesService; private IEventAggregator _eventAggregator; public TiersViewModel() { _eventAggregator = ((UnionContractEventAggregator)UnityContainerFactory .Current.Resolve<UnionContractEventAggregator>())._EventAggregator; _eventAggregator.GetEvent<UnionContractSelectedEvent>().Subscribe(UnionContractChanged); _unionContractsService = UnityContainerFactory.Current.Resolve<IUnionContractsService>(); _unionCodesService = UnityContainerFactory.Current.Resolve<IUnionCodesService>(); } private ObservableCollection<TierGroupTiers> tierGroupsList; public ObservableCollection<TierGroupTiers> TierGroupsList { get { return tierGroupsList; } set { tierGroupsList = value; OnPropertyChanged("TierGroupsList"); } } private ObservableCollection<TiersDTO> tiersList; public ObservableCollection<TiersDTO> TiersList { get { return tiersList; } set { tiersList = value; OnPropertyChanged("TiersList"); } } private DataRecord selectedRecord; public DataRecord SelectedRecord { get { return selectedRecord; } set { selectedRecord = value; OnPropertyChanged("SelectedRecord"); } }
Thank you. private object activeDataItem; public object SelectedDataItem { get { return activeDataItem; } set { activeDataItem = value; if (activeDataItem is TierGroupTiers) { } if (activeDataItem is Tiers) { } OnPropertyChanged("SelectedDataItem"); } } private DelegateCommand<object> _removeTierCommand; public ICommand RemoveTierCommand { get { if (_removeTierCommand == null) { _removeTierCommand = new DelegateCommand<object>(RemoveTier, CanRemoveTier); } return _removeTierCommand; } } private void RemoveTier(object o) { var di = SelectedDataItem; } private bool CanRemoveTier(object arg) { return true; } } }
Hi Krasimir,
Thank you so much for your response.
Following your instructions, I fixed my problem.
Thanks again.
Hello,
Thank you for your post. I have been looking into it and by looking into the Style that you have created for the CellValuePresenter, it seems that the command is not executing, since the DataContext of the CellValuePresenter is actually its corresponding DataRecord. The command that you are trying to bind to the Command property of the Button in the style, is a property of you main view model. In order to access that property, you can use RelativeSource binding with FindAncestor and AncestorType XamDataGrid. By doing so you can access the DataContext of the XamDataGrid and using its data context to access the command. I have create a sample application for you, that demonstrates how you can bind the Command of a button in the CellValuePresenter to a Command of the ViewModel and also added Command property to the RowViewModel that show details to the row and bind that command to Button in different UnboundField.
Please let me know if you need any further assistance on the matter.
Sincerely,
Krasimir
Developer Support Engineer
Infragistics
www.infragistics.com/support