GridView/ListView Double Click - c#

I am trying to get a listview/grid view that has clickable rows.
I am using MVVM'ish style design so my datacontext does point to another class.
i have tried the following with no successes
<ListView ItemsSource="{Binding DelegateUsers}" SelectedItem="{Binding SelectedItem}">
<ListView.View>
<GridView>
<GridViewColumn Width="Auto">
<GridViewColumnHeader Content="Header1">
<GridViewColumnHeader.InputBindings>
<MouseBinding MouseAction="LeftDoubleClick" Command="{Binding CommandDoubleClick}"/>
</GridViewColumnHeader.InputBindings>
</GridViewColumnHeader>
When i put the input bindings into the i can get the command to trigger however it only triggers in white space not on any of the items in the listview.
has anyone got any good ideas on how to accomplish this please?
Thanks.

It can be done using event triggers.
Include
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
And on your xaml file,
<ListView ItemsSource="{Binding DelegateUsers}" SelectedItem="{Binding SelectedItem}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<i:InvokeCommandAction Command="{Binding CommandDoubleClick}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<ListView.View>
<GridView>
<GridViewColumn Width="Auto">
<GridViewColumnHeader Content="Header1">
</GridViewColumnHeader>

Related

Context menu event or trigger of a control inside an itemtemplate of a listview is not fired

I've got following problem. Following situation in my xaml code:
<ListView ItemsSource="{Binding ListViewItems}">
<ListView.ItemTemplate>
<DataTemplate>
<WrapPanel>
<Label Content="Test">
<Label.ContextMenu>
<ContextMenu ItemsSource="{Binding MenuItems}">
</ContextMenu>
</Label.ContextMenu>
</Label>
</WrapPanel>
</DataTemplate>
</ListView.ItemTemplate>
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewMouseUp">
<i:InvokeCommandAction Command="{Binding LabelMouseUpCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</ListView>
After clicking a label no context menu is shown and the trigger does not work as well, LabelMouseUpCommand method is not entered. I fear the listview handles the click itself and does not pass it to the embedded controls.
Is there any way to pass it to the controls. In future i want to add several controls to the itemtemplate and everyone has it own different context menu.
I found the answer for my problem with this stackoverflow article
There the author explains that the contextmenu does not lie in the same visual tree as the listview. Therefore my initial binding can't work because the source can't be found within the visual tree.
Furthermore Sinatr was totally right, the trigger was initially defined for listview, not for the label.
Here is my working code:
<ListView ItemsSource="{Binding ListViewItems}" x:Name="listViewMain">
<ListView.ItemTemplate>
<DataTemplate>
<WrapPanel>
<Label Content="Test">
<Label.ContextMenu>
<ContextMenu ItemsSource="{Binding DataContext.MenuItems, Source={x:Reference listViewMain}}">
</ContextMenu>
</Label.ContextMenu>
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewMouseUp">
<i:InvokeCommandAction Command="{Binding DataContext.LabelMouseUpCommand, Source={x:Reference listViewMain}}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Label>
</WrapPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

InvokeCommandAction CommmandParameter

I have a view model with a list of Invoices, these invoices are being displayed via a Telerik RadGridView This RadGridView has a RowDetailsTemplate. When I click on a row and expand to show the row details how can I pass the InvoiceViewModel of the selected RadGridViewRow so I can get those details from the database?
The purpose of not loading all of the information at once and waiting to load the details until after the row is selected is to reduce load time.
Here's some code for reference:
<telerik:RadGridView x:Name="InvoicesGridView"
ItemsSource="{Binding InvoicesForView}" DataContext="{Binding }"
RowDetailsVisibilityMode="VisibleWhenSelected"
// other stuff
telerik:GridViewVirtualizingPanel.IsVirtualizing="False" EnableRowVirtualization="False"
CanUserResizeColumns="False">
<i:Interaction.Triggers>
<i:EventTrigger EventName="RowDetailsVisibilityChanged" SourceObject="{Binding RelativeSource={RelativeSource AncestorType={x:Type telerik:GridViewRow}}}">
<i:InvokeCommandAction Command="{Binding DataContext.LoadInvoice, Source={StaticResource ViewContext}}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<telerik:RadGridView.Columns>
<-- Column definitions -->
</telerik:RadGridView.Columns>
<telerik:RadGridView.RowDetailsTemplate>
<-- Row details stuff -->
</telerik:RadGridView.RowDetailsTemplate>
</telerik:RadGridView>
I've tried passing through a selected InvoiceViewModel and all that I get back is null, What can I set the CommandParameter to too get the information I need?
<telerik:RadGridView x:Name="InvoicesGridView"
ItemsSource="{Binding InvoicesForView}" DataContext="{Binding }"
ShowGroupPanel="False" Style="{StaticResource TransparentScrollBarStyle}"
RowIndicatorVisibility="Collapsed"
TextElement.Foreground="White"
TextElement.FontSize="12"
FontWeight="Normal" RowDetailsVisibilityMode="VisibleWhenSelected"
AutoGenerateColumns="False" SelectionMode="Multiple"
ShowColumnHeaders="True" RowHeight="24"
CanUserSelect="True" GroupRenderMode="Flat"
ScrollViewer.VerticalScrollBarVisibility="Visible"
ScrollViewer.CanContentScroll="True" ColumnWidth="*"
VirtualizingStackPanel.VirtualizationMode="Standard"
telerik:GridViewVirtualizingPanel.IsVirtualizing="False" EnableRowVirtualization="False"
CanUserResizeColumns="False">
<telerik:RadGridView.Columns>
<telerik:GridViewToggleRowDetailsColumn />
<-- Other columns -->
</telerik:RadGridView.Columns>
<telerik:RadGridView.RowDetailsTemplate>
<DataTemplate>
<Grid Background="#f8f8f8" TextElement.Foreground="Black" TextElement.FontWeight="Normal" TextElement.FontStyle="Normal" Margin="-1,0" MinHeight="20">
<telerik:RadTabControl >
<telerik:RadTabItem DataContext="{Binding}"/>
<i:Interaction.Behaviors>
<behaviors:RadTabControlTabChangeCommandBehavior>
<behaviors:RadTabControlTabChangeCommandBehavior.TabChangeCommands>
<behaviors:TabChangeCommand TabIndex="0" Command="{Binding Path=DataContext.LoadInvoice, Source={StaticResource ViewContext}}"/>
</behaviors:RadTabControlTabChangeCommandBehavior.TabChangeCommands>
</behaviors:RadTabControlTabChangeCommandBehavior>
</i:Interaction.Behaviors>
</telerik:RadTabControl>
<-- Other stuff -->
</telerik:RadGridView.RowDetailsTemplate>
</telerik:RadGridView>
The above is a nice little work around that worked for me

Unable to scroll rows after binding Listview

Here is my code in XAML
<ListView x:Name="OpportunitySearchResultLV" ItemsSource="{Binding OpportunityCollection}" SelectionMode="Single" AlternationCount="2" ItemContainerStyle="{StaticResource alternatingListViewItemStyle}" SelectedItem="{Binding Path=SelectedOpportunitySearchedItem}" Margin="1" Grid.Row="3" Grid.Column="0" >
<ListView.InputBindings>
<MouseBinding Command="{Binding SelectOpportunitySearchDetailsCommand}" MouseAction="LeftClick"></MouseBinding>
<KeyBinding Command="{Binding SelectOpportunitySearchDetailsCommand}" Key="Up"></KeyBinding>
<KeyBinding Command="{Binding SelectOpportunitySearchDetailsCommand}" Key="Down"></KeyBinding>
<KeyBinding Command="{Binding OpportunitySearchDetailsLeaveCommand}" Key="Tab"></KeyBinding>
</ListView.InputBindings>
<ListView.View>
<GridView ColumnHeaderContainerStyle="{StaticResource NOGridViewHeader}" >
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Viewbox>
<TextBlock Text="{Binding OpportunityTitle}"></TextBlock>
</Viewbox>
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
<msia:Interaction.Triggers>
<msia:EventTrigger EventName="MouseMove">
<msia:InvokeCommandAction Command="{Binding SelectOpportunitySearchDetailsCommand}" />
</msia:EventTrigger>
</msia:Interaction.Triggers>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
now as you can see I am binding (MouseBinding and KeyBinding) but as I am using upkey and downkey I am unable to traverse through the rows in listview.It is stuck to only one row only. Can anyone advise me why this is happening ? My binding is working perfectly and as per expected result also.Moreover I would like to add that I have not found any way to bind GridViewColumn so I am binding (MouseBinding and KeyBinding) to Listview . Is it proper way or there is a better way to bind? Thanking you .Payel Mukherjee Bangalore India

ListViewItem MouseDoubleClick MVVM way

I'm converting my project to use MVVM Light.
So far everything worked fine until I got stuck with binding ListViewItem MouseDoubleClick to a command.
Now it looks like that:
<ListView x:Name="ItemsFromStash" Grid.Column="0" Grid.Row="1"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
ItemsSource="{Binding DropBox.DroppedItems}"
ItemTemplate="{DynamicResource DropItemTemplate}"
SelectedItem="{Binding DropBox.SelectedDropItem}">
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<EventSetter Event="Control.MouseDoubleClick"
Handler="EventSetter_OnHandler"/>
</Style>
</ListView.ItemContainerStyle>
</ListView>
I'd like to make it look somewhat like that:
<ListView x:Name="ItemsFromStash" Grid.Column="0" Grid.Row="1"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
ItemsSource="{Binding DropBox.DroppedItems}"
ItemTemplate="{DynamicResource DropItemTemplate}"
SelectedItem="{Binding DropBox.SelectedDropItem}">
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<Custom:EventToCommand Command=
"{Binding DropBox.RenameItemCommand, Mode=OneWay}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Style>
</ListView.ItemContainerStyle>
</ListView>
But it says:
Property 'Triggers' is not attachable to elements of type 'Style'
I tried moving the command to ListView.MouseDoubleClick, but than the SelectedItem is null sometimes.
How should do it?
The following code works for me on a listbox, it should be the same:
<ListBox x:Name="listbox_name_here"
ItemsSource="{Binding LastEntries}"
SelectedItem="{Binding SelectedExercise, UpdateSourceTrigger=PropertyChanged}"
MinHeight="150" ToolTip="Double click to edit"
>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<Command:EventToCommand Command="{Binding your_command_name_here}"
CommandParameter="{Binding ElementName=listbox_name_here,
Path=SelectedItem}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</ListBox>
Do note that the command parameter is using the listbox (listview in your case) name to bind the target for the selected item.
View:
<ListView x:Name="lw" ItemsSource="{Binding DroppedItems}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<Custom:EventToCommand Command="{Binding DataContext.RenameItemCommand, ElementName=lw}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<ListView.ItemTemplate >
<DataTemplate >
<Label Content="{Binding Field}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Your command:
private ICommand renameItemCommand;
public ICommand RenameItemCommand
{
get
{
if (renameItemCommand == null)
{
renameItemCommand = new RelayCommand(
param => RenameItem()
);
}
return renameItemCommand;
}
}
private void RenameItem()
{
}
One option could be to create a DataTemplate for the ListView items, and include your EventTrigger there. For example,
<ListView x:Name="ItemsFromStash"
ItemsSource="{Binding DropBox.DroppedItems}" ItemTemplate="{DynamicResource DropItemTemplate}"
SelectedItem="{Binding DropBox.SelectedDropItem}">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonUp">
<Custom:EventToCommand Command="{Binding DropBox.RenameItemCommand, Mode=OneWay}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<!-- Place your template controls here -->
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

WPF combobox inside listview

I've got a wpf mvvm application up and running. In one of my views I've got a listbox where one column is a combobox. I thought that I had everything working, but... I ended up here.
When I select a value in the combobox in one row, all rows are changed. I've tried a lot of things and i'm stuck.
Here's my xaml:
<ListView ItemsSource="{Binding Path=Properties.OutputGroups, Mode=TwoWay}">
<ListView.View>
<GridView >
<GridViewColumn Header="Output" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}, Path=DataContext.Outputs}" SelectedValue="{Binding Path=Obj.OutputID, Mode=TwoWay}" IsSynchronizedWithCurrentItem="False" DisplayMemberPath="DisplayName" SelectedValuePath="ID" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Duration">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding Path=Obj.Duration}" BorderThickness="0" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="State" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding Path=Obj.State}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
I'm not positive about this, so I apologize if this is not correct, but according to what I have read on MSDN here, I think it might have to do with the "isSynchronizedWithCurrentItem" property. Try switching this property to "true," and see if that fixes your problem.
Like I said, I'm not positive this is where the problem is, but it seems to me like you are wanting the data to be synchronized with the current item, hence why that property is throwing up a flag to me.
I really hope this helps! (And I truly apologize if it doesn't)

Categories

Resources