How to bind lost focus to a command in viewmodel - wpf

<ComboBox x:Name="PrimaryCountyFIPS" Grid.Row="3" Grid.Column="3" Margin="3"
IsSynchronizedWithCurrentItem="False"
IsEditable="True"
LostFocus="{Binding LostFocusCommand }"
ItemContainerStyle ="{StaticResource ComboBoxItemStyle}"
IsEnabled="{Binding IsChecked, ElementName=IncludePrimZipCodeCheckBox}"
ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type viewmodel:GeocoderDataCleanerViewModel}, AncestorLevel=1}, Path=DestinationColsDictionary}" DisplayMemberPath="Value" SelectedItem="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type viewmodel:GeocoderDataCleanerViewModel}, AncestorLevel=1}, Path=PrimaryCountyFIPSField, Mode=OneWay}">
</ComboBox>
I have a ComboBox that I am wanting to Bind it's lost focus event to a command that I have in it's ViewModel. When I try to bind it I get an error that says "LostFocus is not a method" How would I go about binding it to that Command or is that even possible?

I guess this is what you are looking for:
<ComboBox>
<i:Interaction.Triggers>
<i:EventTrigger EventName="LostFocus">
<i:InvokeCommandAction Command="{Binding Path=DoSomethingCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ComboBox>

Related

WPF launch Datagrid Interaction.Triggers on specific column

I have recently started using Interaction.Triggers and I was wondering if it would be possible to activate the trigger only when clicking on a certain column. In this case, I want it to launch when the user clicks on elements of the Nom Produit column (in blue).
The binding is already working great between the trigger and the datagrid. I just want to modify the launch condition of the trigger because now wherever the user clicks in the row (even Action, Impression/Édition buttons), it will launch.
Here is a minified version of my ProductsListView.xaml.
<DataGrid x:Name="myDataGrid" ItemsSource="{Binding ProductsList}" x:FieldModifier="public" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="No MAT" Binding="{Binding MATProductNumber}" IsReadOnly="True" Width="0.1*"/>
<DataGridTextColumn Header="Format" Binding="{Binding tblFormat.FormatName}" IsReadOnly="True" Width="0.1*"/>
</DataGrid.Columns>
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding ProductNavCommand}"
CommandParameter="{Binding Path=SelectedItem, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</DataGrid>
Thanks in advance!
You could define a CellTemplate for the "Nom Produit" column and place your Interaction.Triggers there:
<DataGridTemplateColumn Header="Nom Produit" MinWidth="120">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Propriete2, Mode=OneWay}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonUp">
<i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}, Path=DataContext.ProductNavCommand}"
CommandParameter="{Binding Path=SelectedItem, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBlock>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
This way it will only trigger when the click is on the "Nom Produit" column.
(As shown above, you will have to change the Binding for the Command to bind to your ViewModel).

Executing the Button's Command on ListBoxItem Selection

I have this (simplified for SO) listbox:
<ListBox x:Name="CurriculumList"
ItemsSource="{Binding FilteredCurriculums}"
SelectedIndex="0"
SelectionMode="Single"
IsSynchronizedWithCurrentItem="True">
<ListBox.ItemTemplate>
<DataTemplate>
<Button Name="TheButton"
HorizontalContentAlignment="Stretch"
Content="{Binding DisplayMember}"
CommandParameter="{Binding Id}"
Command="{Binding OpenCurriculumEditViewCommand}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I can navigate up and down the listBoxItems with the keyboard to change selection, but it doesn't change the detail view - the Button in the DataTemplate doesn't actually get clicked, so the OpenCurriculumEditViewCommandnever gets executed.
Anyone have any idea how I can do this?
Well, if you want to execute OpenCurriculumEditViewCommand when the ListBox selection changes, you could do the following:
First:
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
And then..
<ListBox x:Name="CurriculumList"
ItemsSource="{Binding FilteredCurriculums}"
SelectedIndex="0"
SelectionMode="Single"
IsSynchronizedWithCurrentItem="True">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction CommandParameter="{Binding Path=SelectedItem.Id, RelativeSource={RelativeSource AncestorType=ListBox}}" Command="{Binding OpenCurriculumEditViewCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ListBox>
You should not use a Button at all if you want it to trigger on selection.

ComboBoxItem Selectvalue is Empty in WPF MVVM

<ComboBox x:Name="ddDate" SelectedItem="{Binding SelectedDate}" HorizontalAlignment="Right" VerticalAlignment="Center" Width="170" Margin="0,4,0,0" Style="{StaticResource Light-ComboBoxStyle}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<cal:ActionMessage MethodName="DropDownSelectionChanged" cal:View.Model="{Binding Source={StaticResource VMResource}}">
<!--<cal:Parameter Value="{Binding Hierarchy}" />-->
</cal:ActionMessage>
</i:EventTrigger>
</i:Interaction.Triggers>
<ComboBoxItem IsSelected="True">Current Week</ComboBoxItem>
<ComboBoxItem>Last Week</ComboBoxItem>
<ComboBoxItem>Year to Date</ComboBoxItem>
</ComboBox>
ComboxItem Value by default not selected when i have added attribute isSelected = True.
Please pay attention that each item in the combobox is ComboBoxItem therefore if you bind it to a string it will give you the value of ComboBoxItem.ToString()
You can use SelectedValue and SelectedValuePath properties to force the binding give you the value of each comboBoxItem content:
<ComboBox x:Name="ddDate" SelectedValuePath="Content" SelectedValue="{Binding SelectedDate}" HorizontalAlignment="Right" VerticalAlignment="Center" Width="170" Margin="0,4,0,0">
<ComboBoxItem IsSelected="True">Current Week</ComboBoxItem>
<ComboBoxItem>Last Week</ComboBoxItem>
<ComboBoxItem>Year to Date</ComboBoxItem>
</ComboBox>

Partially Bound WPF TreeView

Edit: It now looks like this is a bug with the Telerik controls I'm using. After re-implementing my XAML using the .Net TreeView I get the results I would expect. I've reported this to Telerik and will answer this posting after hearing back from them.
I'm attempting (with limited success) to create a TreeView that contains a mixture of dynamic and static data.
You'll find my current best attempt at this below, however since I'm nesting TreeViews there is a side effect wherein it is possible to have multiple items within the parent TreeView selected. When I've tried nesting TreeViewItems the results were not positive, i.e. only the parent level TreeViewItem in the ItemTemplate is displayed and space for it's children is created but nothing is output.
I would really like to know how to acheive my goal without resorting to specifying the entire menu in collections which I bind to the TreeView.
Thank you
<telerik:RadTreeView Width="225" HorizontalAlignment="Left" Background="Transparent" FontWeight="SemiBold">
<telerik:RadTreeViewItem Header="Customer" Command="{Binding OpenCustomerCommand}"/>
<telerik:RadTreeViewItem Header="Sites" Command="{Binding OpenSiteBrowserCommand}" ItemsSource="{Binding Sites}">
<telerik:RadTreeViewItem.ItemTemplate>
<DataTemplate>
<telerik:RadTreeView>
<telerik:RadTreeViewItem Header="{Binding Key}"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=view:WindowViewBase},
Path=DataContext.OpenSiteCommand}"
CommandParameter="{Binding Value}">
<telerik:RadTreeViewItem Header="Material Profiles"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=view:WindowViewBase},
Path=DataContext.OpenMaterialProfileBrowserCommand}"
CommandParameter="{Binding Value}"/>
<telerik:RadTreeViewItem Header="Prices"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=view:WindowViewBase},
Path=DataContext.OpenPriceBrowserCommand}"
CommandParameter="{Binding Value}"/>
<telerik:RadTreeViewItem Header="Orders"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=view:WindowViewBase},
Path=DataContext.OpenOrderBrowserCommand}"
CommandParameter="{Binding Value}"/>
<telerik:RadTreeViewItem Header="Activity">
<telerik:RadTreeViewItem Header="Collection"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=view:WindowViewBase},
Path=DataContext.OpenActivityCollectionsBrowserCommand}"
CommandParameter="{Binding Value}"/>
<telerik:RadTreeViewItem Header="Call Outs"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=view:WindowViewBase},
Path=DataContext.OpenActivityCallOutBrowserCommand}"
CommandParameter="{Binding Value}"/>
<telerik:RadTreeViewItem Header="Gate"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=view:WindowViewBase},
Path=DataContext.OpenActivityGateBrowserCommand}"
CommandParameter="{Binding Value}"/>
<telerik:RadTreeViewItem Header="One Off Charges"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=view:WindowViewBase},
Path=DataContext.OpenActivityOneOffChargeBrowserCommand}"
CommandParameter="{Binding Value}"/>
</telerik:RadTreeViewItem>
</telerik:RadTreeViewItem>
</telerik:RadTreeView>
</DataTemplate>
</telerik:RadTreeViewItem.ItemTemplate>
</telerik:RadTreeViewItem>
Telerik have confirmed that this isn't possible with their RadTreeView control and they've added it to their TODO list.
Thanks for the comments anyway.

RadTreeViewItem, MVVM, and Click events

I'm having trouble getting a click event or mouse down event to fire on a RadTreeViewItem in the ViewModel. What syntax should I be using? This is the relevant XAML below:
<Toolkit:AccordionItem x:Name="Accordion1" Header="{Binding Header, Mode=TwoWay}" Width="200">
<ListBox x:Name="SitesList" Width="195" BorderThickness="0" ItemsSource="{Binding Games, Mode=OneWay}" SelectedItem="{Binding SelectedItem, Mode=TwoWay}">
<ListBox.ItemTemplate>
<DataTemplate>
<telerik:RadTreeView IsDragDropEnabled="True" IsSingleExpandPath="True"
telerikDragDrop:RadDragAndDropManager.AllowDrag="True" PreviewDragEnded="RadTreeView_PreviewDragEnded"
IsDragTooltipEnabled="False">
<telerik:RadTreeViewItem Header="{Binding siteName, Mode=TwoWay}" Tag="{Binding siteKey, Mode=TwoWay}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<cmd:EventToCommand Command="{Binding RadTreeItemClickCommand, Mode=TwoWay}" MustToggleIsEnabledValue="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</telerik:RadTreeViewItem>
</telerik:RadTreeView>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Toolkit:AccordionItem>
As far as I can tell, binding the events of the RadTreeViewItem has to be done in code-behind; the ItemPrepared event of RadTreeView is fired when a RadTreeViewItem is created and bindings can be set in a handler. More information here:
http://www.telerik.com/help/silverlight/radtreeview-events-working-with-item-prepared-event.html
Don't bother with the event to command. You can set a command on the RadTreeViewItem directly.

Resources