Hi,
I am trying to fire an event KeyDown using trigger for a textbox bound in a template column for a XamWebGrid. Here is the code that I used. We have been using MVVM to bind the data to the view. However, the event KeyDown is not firing only for textbox. The event Click is working perfectly for a button bound in a similar way. Kindly let me know if I am doing anything wrong.
<controls:ChildWindow.Resources> <!--<Resource:ResourceService x:Key="resources"/>--> <B:DataContextProxy x:Key="DataContextProxy"/> </controls:ChildWindow.Resources>
<controls:ChildWindow.Title> <TextBlock /> </controls:ChildWindow.Title> <!--<controlsToolkit:BusyIndicator x:Name="BusyIndicator" IsBusy="{Binding IsBusy}" BusyContent="{Binding BusyMessage}">--> <Grid x:Name="LayoutRoot" Background="White"> <Grid.RowDefinitions> <RowDefinition Height="*"/> <RowDefinition Height="auto" /> </Grid.RowDefinitions> <igGrid:XamWebGrid x:Name="igGrid" Grid.Row="0" AutoGenerateColumns="False" CellStyle="{StaticResource CellControlStyle}" RowHover="Row" ItemsSource="{Binding LucaAttributes}" B:XamWebSelectionChanged.Command="{Binding GridRowSelected}"> <igGrid:XamWebGrid.SelectionSettings> <igGrid:SelectionSettings RowSelection="Single" CellSelection="None" CellClickAction="SelectRow" /> </igGrid:XamWebGrid.SelectionSettings> <igGrid:XamWebGrid.Columns> <igGrid:TextColumn Key="Name" TextWrapping="Wrap" Width="auto"> <igGrid:TextColumn.HeaderTemplate> <DataTemplate> <TextBlock Text="Attribute Name" /> </DataTemplate> </igGrid:TextColumn.HeaderTemplate> </igGrid:TextColumn> <igGrid:TextColumn Key="Description" TextWrapping="Wrap" Width="auto"> <igGrid:TextColumn.HeaderTemplate> <DataTemplate> <TextBlock Text="Description" /> </DataTemplate> </igGrid:TextColumn.HeaderTemplate> </igGrid:TextColumn> <igGrid:TemplateColumn Key="CompanyOverrideValue" Width="*" IsSortable="False" Visibility="{Binding Source={StaticResource DataContextProxy},Path=DataSource.IsCompanyMode, Mode=OneWay, Converter={StaticResource boolToVisibilityConverter}}"> <igGrid:TemplateColumn.HeaderTemplate> <DataTemplate> <TextBlock Text="Override Value" /> </DataTemplate> </igGrid:TemplateColumn.HeaderTemplate> <igGrid:TemplateColumn.ItemTemplate> <DataTemplate> <TextBox IsEnabled="True" Text="{Binding Path=CompanyOverrideValue, Mode=TwoWay}" Width="100"> <B:BehaviorService.Behavior> <B:TextBoxFastBindBehavior/> </B:BehaviorService.Behavior> <i:Interaction.Triggers> <i:EventTrigger EventName="KeyDown"> <Commands:EventToCommand Command="{Binding Path=KeyDown, Mode=TwoWay}" CommandParameter="{Binding}" PassEventArgs="False" /> </i:EventTrigger> </i:Interaction.Triggers> </TextBox> </DataTemplate> </igGrid:TemplateColumn.ItemTemplate> </igGrid:TemplateColumn> <igGrid:TemplateColumn Key="UserOverrideValue" Width="*" IsSortable="False" Visibility="{Binding Source={StaticResource DataContextProxy},Path=DataSource.IsUserMode, Mode=OneWay, Converter={StaticResource boolToVisibilityConverter}}"> <igGrid:TemplateColumn.HeaderTemplate> <DataTemplate> <TextBlock Text="Override Value" /> </DataTemplate> </igGrid:TemplateColumn.HeaderTemplate> <igGrid:TemplateColumn.ItemTemplate> <DataTemplate> <TextBox IsEnabled="True" Style="{StaticResource Copyable}" Text="{Binding Path=UserOverrideValue, Mode=TwoWay}" Width="100"> <B:BehaviorService.Behavior> <B:TextBoxFastBindBehavior/> </B:BehaviorService.Behavior> <i:Interaction.Triggers> <i:EventTrigger EventName="KeyDown"> <Commands:EventToCommand Command="{Binding Source={StaticResource DataContextProxy},Path=DataSource.KeyDown, Mode=TwoWay}" CommandParameter="{Binding}" PassEventArgs="False" /> </i:EventTrigger> </i:Interaction.Triggers> </TextBox> </DataTemplate> </igGrid:TemplateColumn.ItemTemplate> </igGrid:TemplateColumn> <igGrid:TextColumn Key="DefaultValue" TextWrapping="Wrap" Width="auto"> <igGrid:TextColumn.HeaderTemplate> <DataTemplate> <TextBlock Text="Default Value" /> </DataTemplate> </igGrid:TextColumn.HeaderTemplate> </igGrid:TextColumn> <igGrid:TemplateColumn Key="AttributeId" Visibility="Visible"> <igGrid:TemplateColumn.HeaderTemplate> <DataTemplate> <TextBlock Text="" /> </DataTemplate> </igGrid:TemplateColumn.HeaderTemplate> <igGrid:TemplateColumn.ItemTemplate> <DataTemplate> <StackPanel> <Button IsEnabled="True" Content="{Binding Resource.ControlText_Save, Source={StaticResource resources}}"> <!--<HyperlinkButton IsEnabled="True" Content="{Binding Resource.ControlText_Save, Source={StaticResource resources}}">--> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <Commands:EventToCommand Command="{Binding Source={StaticResource DataContextProxy},Path=DataSource.SaveAttribute}" CommandParameter="{Binding}" PassEventArgs="False" /> </i:EventTrigger> </i:Interaction.Triggers> <!--</HyperlinkButton>--> </Button> </StackPanel> </DataTemplate> </igGrid:TemplateColumn.ItemTemplate> </igGrid:TemplateColumn> </igGrid:XamWebGrid.Columns> </igGrid:XamWebGrid> </Grid>
My ViewModel code:
public class EditAttributesViewModel: INotifyPropertyChanged { #region Private Fields
private Guid _productID; private Guid _userID;
private readonly ILucaAttributeClientService _lucaAttributeClientService;
private IList<LucaAttribute> _allAttributes;
private LucaAttribute _selectedRow;
private bool _iscompanymode = false; private bool _isusermode = false; private string _str = "Shutup"; #endregion
#region Public Properties
public DelegateCommand<object> GridRowSelected { get; set; } public IList<LucaAttribute> LucaAttributes { get; set; } public DelegateCommand<LucaAttribute> SaveAttribute { get; set; } public DelegateCommand<KeyEventArgs> KeyDown;
public Guid ProductID { get { return _productID; } set { _productID = value; GetAttributesList(_productID); } }
public Guid UserID { get { return _userID; } set { _userID = value; } }
public LucaAttribute SelectedRow { get { return _selectedRow; } set { _selectedRow = value; OnPropertyChanged("SelectedRow"); } }
public bool IsCompanyMode { get { return _iscompanymode; } set { _iscompanymode = value; OnPropertyChanged("IsCompanyMode"); } }
public bool IsUserMode { get { return _isusermode; } set { _isusermode = value; OnPropertyChanged("IsUserMode"); } }
#endregion
#region Constructor public EditAttributesViewModel(ILucaAttributeClientService lucaAttributeClientService) { _allAttributes = new List<LucaAttribute>(); LucaAttributes = new List<LucaAttribute>(); _lucaAttributeClientService = lucaAttributeClientService; _lucaAttributeClientService.GetAttributesByProductAsyncCompleted += GetAttributesByProductCompleted; GridRowSelected = new DelegateCommand<object>(OnGridRowSelected); SaveAttribute = new DelegateCommand<LucaAttribute>(OnSaveAttribute,CanSaveAttribute); KeyDown = new DelegateCommand<KeyEventArgs>(OnKeyDown);
} #endregion
#region Public methods
private void OnKeyDown(KeyEventArgs e) { if (SelectedRow.ValidateValueforDouble(SelectedRow.CompanyOverrideValue)) { throw new ArgumentException(Resource.ValidationMessage_ValidInteger); } else if (SelectedRow.ValidateValueforDate(SelectedRow.CompanyOverrideValue)) { throw new ArgumentException(Resource.ValidationMessage_ValidDate); } }
public bool CanSaveAttribute(LucaAttribute item) { return true; }
public void OnSaveAttribute(LucaAttribute item) { if (SelectedRow != null && IsCompanyMode) { string text = SelectedRow.CompanyOverrideValue; } }
public void GetAttributesList(Guid productID) { _lucaAttributeClientService.GetAttributesByProductAsync(productID); }
void GetAttributesByProductCompleted(object sender, EventArgs<List<LucaAttribute>> e) { if (_allAttributes != null) { _allAttributes.Clear(); LucaAttributes.Clear(); e.Value.ForEach(_allAttributes.Add); foreach (LucaAttribute item in _allAttributes) { LucaAttributes.Add(item); } } }
private void OnGridRowSelected(object obj) { SelectedRow = obj as LucaAttribute;
if (SelectedRow != null) { OnPropertyChanged("SelectedRow"); } }
public void OnPropertyChanged(string name) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(name)); }
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion }
Thanks,
Abhiram.
Hello Abhiram,
Thank you for your post!
I have been looking into your issue and have created a small sample application for you. In the sample application I have a simple behavior with a command, created in the ViewModel. I have added this behavior to the xamGrid and the command fires on the KeyDown event of the TextBox.
Please find the attached sample application and feel free to let me know if you have any further questions on this matter.
Thanks very much Gergana!
However, we have been using a custom framework for interactivity and hence I do not see option interactivity.behaviours. I only have interactivity.triggers. The issue was, with triggers if I pass KeyEventArgs as parameter to the delegate in ViewModel the page goes blank without giving an exception. Instead of KeyEventArgs if I pass a parameter of type object it is working fine. I am getting row bound object as a parameter instead of KeyEventArgs.
But your project was helpful though, thanks again!
Thank you for the feedback. I am glad I was able to help. Please do not hesitate to let me know if you have any further questions on this matter.