I have a ListBox with Button in ItemTemplate. When I press a Button, some Command fired. I want the ListBox to fire SelectionChanged event when Button Click event happen. How shoult I fire ListBox SelectionChanged event and pass appropriate context?
<ListBox ItemsSource="{Binding SomeSource}" >
<ListBox.ItemTemplate>
<DataTemplate>
<Button Grid.Row="0" BorderThickness="0" Background="Transparent" HorizontalAlignment="Stretch">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<cmd:EventToCommand Command="{Binding SomeCommand}" CommandParameter="{Binding}" PassEventArgsToCommand="True" />
</i:EventTrigger>
</i:Interaction.Triggers>
<Button.Template>
<ControlTemplate>
<TextBlock Text="{Binding Title}" />
</ControlTemplate>
</Button.Template>
</Button>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
If you can have a SelectedItem property in the ViewModel you can TwoWay bind that to the ListBox.Selecteditem and in the SomeCommand implementation you can set the ViewModel.SelectedItem so that it reflects to the UI and you get SelectionChanged call.
Related
I am using System.Windows.Interactivity and i have to display a Message on mouse enter event.
The problem is the same event is called when done outside the ListView, But it gets not called when inside the ListView.
I tried doing so using mvvm approach:
<Grid>
<StackPanel Grid.Row="1" Grid.Column="1" Name="events1">
//This Event works outside the ListView but not inside ListView
<Rectangle Fill="Yellow" Stroke="Black" Width="100" Height="30">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseEnter">
<i:InvokeCommandAction Command="{Binding SomeCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Rectangle>
<ListView BorderBrush="#FF1D93E4" BorderThickness="4" Behaviour:GridViewColumnResize.Enabled="True" ScrollViewer.VerticalScrollBarVisibility="Auto" SelectedItem="{Binding SelectedItem ,Mode=TwoWay}" ItemsSource="{Binding Ur1r2_Obj}" HorizontalContentAlignment="Stretch">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView>
<GridViewColumn Header="State" Behaviour:GridViewColumnResize.Width="*">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Grid Background="{Binding Converter={StaticResource colorToBrushConverter}}">
//The event do not work here
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseEnter">
<i:InvokeCommandAction Command="{Binding SomeCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<Button Margin="35,0,0,0" HorizontalAlignment="Center" Content="{Binding Path=Etat, Mode=OneWay}" Background="{Binding Converter={StaticResource colorToBrushConverter}}" />
</Grid>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</StackPanel>
</Grid>
In view Model
private ICommand someCommand;
public ICommand SomeCommand
{
get
{
//return plotButton;
return someCommand ?? (someCommand = new CommandHandler(() => MyAction2(), _canExecute));
}
set
{
someCommand = value;
OnPropertyChanged("SomeCommand");
}
}
private void MyAction2() //Messsage is popuped on Moseenter event when i try to hover mouse over rectangle outside the listview , But not get called when inside the Listview
{
MessageBox.Show("Yeah Called");
}
Why it event is not called from inside the ListView. How to make it call ?
If you are trying to invoke the same command (SomeCommand) you should specify a RelativeSource of the Binding:
<Grid Background="{Binding Converter={StaticResource colorToBrushConverter}}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseEnter">
<i:InvokeCommandAction Command="{Binding DataContext.SomeCommand,
RelativeSource={RelativeSource AncestorType=ListView}}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<Button Margin="35,0,0,0" HorizontalAlignment="Center" Content="{Binding Path=Etat, Mode=OneWay}" Background="{Binding Converter={StaticResource colorToBrushConverter}}" />
</Grid>
The DataContext of an item in the ListView is an object in your "Ur1r2_Obj" ItemsSource whereas the DataContext of the Rectangle is your view model. That's why the binding fails in your CellTemplate.
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.
I have a combobox, using databinding and MVVM pattern. Everytime the user changes the selection, I added an event trigger, and a command is executed. the code is the following:
<ComboBox x:Name="myComboBox" Width="150" ItemsSource="{Binding Items}" >
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding LoadCommand}" CommandParameter="{Binding SelectedItem, ElementName=myComboBox}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</ComboBox>
the problem is that the parameter it passes is always null.
I changed the parameter from SelectedItem to SelectedIndex, this way I get the parameter and it is not null. Then i get my object using the index.
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.
I have a textbox with a ContextMenu, the menu contains a tab control. The problem I'm running into is that when I click any of the tab control items to change the visible tab control item the Context Menu gets closed. Any ideas?
I've tried the ContextMenu_ContextMenuClosing event but it doesn't appear to catch the event
<TextBox x:Name="TestCB4" TextSearch.TextPath="Name" >
<TextBox.ContextMenu>
<ContextMenu ContextMenuOpening="ContextMenu_ContextMenuOpening"
ContextMenuClosing="ContextMenu_ContextMenuClosing"
MouseLeftButtonDown="ContextMenu_MouseLeftButtonDown"
StaysOpen="True"
Background="Transparent" Margin="0">
<TabControl ContextMenuClosing="TabControl_ContextMenuClosing" Margin="0">
<TabItem Header="User Space">
<WrapPanel Orientation="Horizontal"
HorizontalAlignment="Right"
Margin="10,2,2,2">
<Button Content="_Select" Margin="1"
Command="{Binding Path=SelectVendorCommand}"
CommandParameter="{Binding ElementName=ucFindVendorCtrl, Path=VendorListView.SelectedItems}" />
<Button Content="_Add To User Space" Margin="1"
Command="{Binding Path=AddVendorToUserSpaceCommand}"
Width="120"
CommandParameter="{Binding ElementName=ucFindVendorCtrl, Path=VendorListView.SelectedItems}" />
</WrapPanel>
</TabItem>
<TabItem Header="Find">
<WrapPanel Orientation="Horizontal"
HorizontalAlignment="Right"
Margin="10,2,2,2">
<Button Content="_Select" Margin="1"
Command="{Binding Path=SelectVendorCommand}"
CommandParameter="{Binding ElementName=ucFindVendorCtrl, Path=VendorListView.SelectedItems}" />
<Button Content="_Add To User Space" Margin="1"
Command="{Binding Path=AddVendorToUserSpaceCommand}"
Width="120"
CommandParameter="{Binding ElementName=ucFindVendorCtrl, Path=VendorListView.SelectedItems}" />
</WrapPanel>
</TabItem>
</TabControl>
</ContextMenu>
</TextBox.ContextMenu>
</TextBox>
I think that the problem is that the TabControl does not handle the propagation of the MouseLeftButtonDown routed events, and so the ContextMenu catches it, and closes.
If that's the case, then the solution is rather simple. Just wrap the TabControl in a ContentControl, and catch the event MouseLeftButtonDown on the ContentControl. In the event handler do e.Handled = true;
This way the ContextMenu would have no way of knowing that the user has clicked on the TabControl.
try to put your tabcontrol inside a menuItem like the example:
<ContextMenu>
<MenuItem StaysOpenOnClick="true">
<MenuItem.Header>
...your TabControl
</MenuItem.Header>
</MenuItem>
</ContextMenu>
I hope that it can be helpful.