Event trigger for entire listview item - wpf

I have
<ListView ScrollViewer.VerticalScrollBarVisibility="Auto" Grid.Row="1" Grid.Column="0" Margin="2" Name="CoursesListView" ItemsSource="{Binding CourseTags}">
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Border Margin="2" BorderThickness="1" BorderBrush="Red" Background="AntiqueWhite" CornerRadius="2" Cursor="Hand">
<WrapPanel ToolTip="{Binding Description}" HorizontalAlignment="Stretch">
<TextBlock Text="{Binding Name}" FontWeight="Bold" />
<TextBlock Text=" (" />
<TextBlock Text="{Binding NumberOfCourses}" TextDecorations="Underline" Foreground="Blue" />
<TextBlock Text=")" />
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonUp">
<GalaSoft_MvvmLight_Command:EventToCommand Command="{Binding DataContext.ProductTagSelectedCommand, ElementName=LayoutRoot}"
CommandParameter="{Binding Name}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</WrapPanel>
</Border>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
The items are stretched well and have the same width regardless how much text they have. Hand cursor displays correctly as well (wherever I point) The problem is that EventTrigger fires command only when I click on the text blocks. How to make it work throughout all the item?

It's very simple. Just place your EventTrigger inside the Border, not the WrapPanel:
<Border Margin="2" BorderThickness="1" BorderBrush="Red" Background="AntiqueWhite" CornerRadius="2" Cursor="Hand">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonUp">
<GalaSoft_MvvmLight_Command:EventToCommand Command="{Binding DataContext.ProductTagSelectedCommand, ElementName=LayoutRoot}" CommandParameter="{Binding Name}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<WrapPanel ToolTip="{Binding Description}" HorizontalAlignment="Stretch">
<TextBlock Text="{Binding Name}" FontWeight="Bold" />
<TextBlock Text=" (" />
<TextBlock Text="{Binding NumberOfCourses}" TextDecorations="Underline" Foreground="Blue" />
<TextBlock Text=")" />
</WrapPanel>
</Border>

Related

ScrollViewer.CanContentScroll not scrolling ItemsControl item by item

I have an ItemControl on a ScrollViewer. I want to scroll item by item, now is scrolling pixel by pixel.
<ScrollViewer Height="299" Margin="10,10,0,0"
HorizontalScrollBarVisibility="Visible" x:Name="Scroll"
VerticalAlignment="Top"
Grid.Column="0" Grid.Row="1"
PanningMode="HorizontalOnly"
CanContentScroll="True">
<ItemsControl ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=Items, Mode=OneWay}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Width="175" Height="64" Margin="0,0,16,16" HorizontalAlignment="Center" Focusable="False">
<TextBlock Text="{Binding}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
Just set this property on ListBox:
VirtualizingStackPanel.ScrollUnit ="Item"
Another mode is "Pixel", which is default mode.
I found a solution
<ItemsControl ItemsSource="{Binding TypeHeaders}"
x:Name="ActivityItemsControl"
Grid.Column="0" Grid.Row="1">
<ItemsControl.Template>
<ControlTemplate>
<ScrollViewer HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Visible"
CanContentScroll="True"
x:Name="ActivityScrollViewer">
<ItemsPresenter/>
<i:Interaction.Triggers>
<i:EventTrigger EventName="ScrollChanged">
<cmd:EventToCommand PassEventArgsToCommand="True"
Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type Grid}}, Path=DataContext.VmCommands.ActivityScrollChangedCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding Description}" Style="{DynamicResource ZoneTypeHeaderButtonStyle}"
Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}, Path=DataContext.VmCommands.ZoneOverviewControlTypeHeaderClickedCommand}"
CommandParameter="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
You can use ListBox instead of ScrollViewer. I thought you did not want to have a selection style so I changed it.
<ListView ScrollViewer.CanContentScroll="True"
ScrollViewer.VerticalScrollBarVisibility="Hidden"
ScrollViewer.PanningMode="HorizontalOnly"
ScrollViewer.HorizontalScrollBarVisibility="Visible"
ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=Items, Mode=OneWay}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<ContentPresenter />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Border Width="175" Height="64" Margin="0,0,16,16" HorizontalAlignment="Center" Focusable="False">
<TextBlock Text="{Binding }" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

Wpf Dock Panel Dock left and Dock right

I am not able to move buttons inside of a dock panel to the right, I tried few solutions, and after all I put them in stack panels and tried to move them to the right, but acctualy they wont move anywhere, here is how it looks:
And here is my code:
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander IsExpanded="True" Background="Black" Opacity="0.7">
<Expander.Header>
<DockPanel Height="50">
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" DockPanel.Dock="Right"> <Button DockPanel.Dock="Right" Content="Test" Margin="0,0,28,0"/></StackPanel>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" DockPanel.Dock="Left"> <TextBlock FontWeight="Normal" FontFamily="Verdana" FontSize="20" Height="25" Foreground="#83D744" Text="{Binding Path=Name,StringFormat= Order Number:# {0}}" /></StackPanel>
</DockPanel>
</Expander.Header>
<Expander.Content>
<ItemsPresenter />
</Expander.Content>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</DataGrid.GroupStyle>
edit:
This above causes width on dock panel
<DockPanel Height="50" Width="{Binding ActualWidth, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}}">
<Button DockPanel.Dock="Right" Content="Test" Margin="0,0,28,0"/>
<TextBlock FontWeight="Normal" FontFamily="Verdana" FontSize="20" Height="25" Foreground="#83D744" Text="{Binding Path=Name,StringFormat= Order Number:# {0}}" />
</DockPanel>
Try the following method. this works in my project
<DockPanel Height="50">
<grid DockPanel.Dock="Right">
<Button Content="Test" Margin="0,0,28,0"/>
</grid >
<grid DockPanel.Dock="Left">
<TextBlock FontWeight="Normal" FontFamily="Verdana" FontSize="20" Height="25" Foreground="#83D744" Text="{Binding Path=Name,StringFormat= Order Number:# {0}}"/>
</grid>
</DockPanel>
Apply Width="{Binding ActualWidth, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}}" to your DockPanel and see if this solves your problem.

Performance issue with ItemsControl and complex ItemTemplate

I've a performance problem with an ItemsControl. I've virtualized the ItemsControl using the following style
<Style x:Key="VirtualizedItemsControl"
TargetType="{x:Type ItemsControl}">
<Setter Property="VirtualizingStackPanel.IsVirtualizing"
Value="True" />
<Setter Property="ScrollViewer.CanContentScroll"
Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border BorderThickness="{TemplateBinding Border.BorderThickness}"
Padding="{TemplateBinding Control.Padding}"
BorderBrush="{TemplateBinding Border.BorderBrush}"
Background="{TemplateBinding Panel.Background}"
SnapsToDevicePixels="True">
<ScrollViewer Padding="{TemplateBinding Control.Padding}"
Focusable="False">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
My ItemsTemplate is an Expander with another ItemsControl which ItemsTemplate is an Expander with a DataGrid (DataContext is a list in a list).
When my bound data is getting more (like 100 entries in the first list and in each datagrid ~100 entries) the ui is getting really slow if i start to scroll.
I don't know why it's getting so slow.
I change the background color of each DataGrid cell if there are changes. That's why I use DataGridTemplateColumns.
<ItemsControl ItemsSource="{Binding MyList}"
x:Name="_container"
Style="{StaticResource VirtualizedItemsControl}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Expander>
<Expander.Header>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock />
<Button Grid.Column="1"
Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, Path=DataContext.DeleteCommand}"
CommandParameter="{Binding}">
<Image Source="trashcan-delete.png"
HorizontalAlignment="Right" />
</Button>
</Grid>
</Expander.Header>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid Margin="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Label Content="Some text" />
<ComboBox Grid.Column="1"
Margin="5 0"
Width="150"
HorizontalAlignment="Left"
Text="{Binding Name.Property}"
SelectedItem="{Binding SelectedName, UpdateSourceTrigger=PropertyChanged}"
Foreground="Black"
IsEditable="True"
DisplayMemberPath="Name"
ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, Path=DataContext.Children}"
Background="{Binding Name.IsDirty, Converter={StaticResource IsDirtyToColorConverter}}" />
</Grid>
<ItemsControl Grid.Row="1"
ItemsSource="{Binding ParameterBlocks}"
Style="{StaticResource VirtualizedItemsControl}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Expander>
<Expander.Header>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Index, Converter={StaticResource NumberToBlockHeaderConverter}}"
FontWeight="Bold"
Foreground="White" />
<Button Grid.Column="1"
Command="{Binding RelativeSource={RelativeSource AncestorType=Expander, AncestorLevel=2}, Path=DataContext.DeleteBlockCommand}"
CommandParameter="{Binding}">
<Image Source="trashcan-delete.png"
HorizontalAlignment="Right" />
</Button>
</Grid>
</Expander.Header>
<Grid Background="#E5E5E5">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid Margin="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<CheckBox Grid.Column="0"
Content="Some text"
VerticalAlignment="Center"
IsChecked="{Binding IsWaitingEnabled.Property}"
Background="{Binding IsWaitingEnabled.IsDirty, Converter={StaticResource IsDirtyToColorConverter}}">
<Label Grid.Column="1"
Margin="15 0 0 0"
VerticalAlignment="Center"
Content="Some text"
IsEnabled="{Binding IsWaitingEnabled.Property}" />
<Xctk:IntegerUpDown Grid.Column="2"
Minimum="0"
Width="60"
Margin="5 0 0 0"
HorizontalAlignment="Left"
Text="Some text"
IsEnabled="{Binding IsWaitingEnabled.Property}"
</Grid>
<DataGrid ItemsSource="{Binding Channels}"
Style="{StaticResource StandardGridStyle}"
x:Name="BlockGrid"
Grid.Row="1"
CanUserSortColumns="True"
Margin="5 0"
MaxHeight="200"
SelectedItem="{Binding SelectedEntry}"
CanUserAddRows="True">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Some text"
Width="200">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Channel.Property, UpdateSourceTrigger=PropertyChanged}"
Foreground="Black"
Background="{Binding Channel.IsDirty, Converter={StaticResource IsDirtyToColorConverter}}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox Text="{Binding Channel.Property, UpdateSourceTrigger=PropertyChanged}"
Foreground="Black"
IsEditable="True"
ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type Expander}, AncestorLevel=2}, Path=DataContext.SelectedChannelList.Channels}"
IsEnabled="{Binding RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Path=DataContext.IsPasswordProtected, Converter={StaticResource BoolToOppositeBoolConverter}}"
Background="{Binding Channel.IsDirty, Converter={StaticResource IsDirtyToColorConverter}}" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Some text"
Width="150"
Foreground="Black"
Binding="{Binding Value.Property, UpdateSourceTrigger=PropertyChanged}">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<DataTrigger Binding="{Binding Value.IsDirty}"
Value="true">
<Setter Property="Background"
Value="#FFDDA203" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTemplateColumn Header="Some text">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Block.Property}"
Foreground="Black"
Background="{Binding Block.IsDirty, Converter={StaticResource IsDirtyToColorConverter}}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<Xctk:IntegerUpDown Minimum="1"
Maximum="{Binding RelativeSource={RelativeSource AncestorType={x:Type Expander}, AncestorLevel=2}, Path=DataContext.ParameterBlocks, Converter={StaticResource ListToCountConverter}}"
Text="{Binding Block.Property, UpdateSourceTrigger=PropertyChanged}"
Background="{Binding Block.IsDirty, Converter={StaticResource IsDirtyToColorConverter}}">
<I:Interaction.Triggers>
<I:EventTrigger EventName="ValueChanged">
<Commands:EventToCommand Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type Expander}, AncestorLevel=2}, Path=DataContext.BlockChangedCommand}"
CommandParameter="{Binding }" />
</I:EventTrigger>
</I:Interaction.Triggers>
</Xctk:IntegerUpDown>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
<I:Interaction.Behaviors>
<Commands:DataGridScrollToSelectedItemBehavior />
</I:Interaction.Behaviors>
</DataGrid>
<StackPanel Grid.Row="2"
Margin="5"
Orientation="Horizontal"
HorizontalAlignment="Right">
<Button Command="{Binding DeleteEntryCommand}"
Content="Some text"
CommandParameter="{Binding ElementName=BlockGrid, Path=SelectedItems}"
Width="120"
Margin="5 0" />
<Button Content="Some text"
Command="{Binding AddEntryCommand}"
Width="120"
Margin="5 0"
HorizontalAlignment="Right" />
</StackPanel>
</Grid>
</Expander>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Done; see my last comment.
The Expander style was making some trouble.

Accordion control showing item content only after second selection

I have an AccordionControl (WPFToolkit) to which I add items dynamically:
<my:Accordion Grid.Column="1"
ItemsSource="{Binding Path=Tests}"
SelectionMode="ZeroOrOne"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<my:Accordion.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Header}" />
</StackPanel>
</DataTemplate>
</my:Accordion.ItemTemplate>
<my:Accordion.ContentTemplate>
<DataTemplate>
<ContentPresenter Content="{Binding Content}"/>
</DataTemplate>
</my:Accordion.ContentTemplate>
</my:Accordion>
To actually see the Content, I have to select (open) an AccordionItem, close it and open it again. What could be the reason for this behaviour?
EDIT
I have found a way around this using styles instead, still I would be interested why the above does not work. Here the style solution:
<Style x:Key="itemStyle" TargetType="my:AccordionItem">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="{Binding Header}"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="accordionStyle" TargetType="my:Accordion">
<Setter Property="ItemContainerStyle" Value="{StaticResource itemStyle}" />
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<ItemsControl ItemsSource="{Binding MenuItems}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding Path=Text, Mode=OneWay}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<my:Accordion Grid.Column="1" Height="Auto"
Name="accordion1"
ExpandDirection="Left"
SelectionMode="One"
ItemsSource="{Binding Tests}"
Style="{StaticResource accordionStyle}">
</my:Accordion>
EDIT
I have now found the problem: I cannot "Stretch the AccordionControl.
<my:Accordion Grid.Column="1" Height="Auto"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Name="accordion1"
ExpandDirection="Left"
SelectionMode="One"
ItemsSource="{Binding Tests}"
Style="{StaticResource accordionStyle}">
</my:Accordion>
As soon as I do this, it is not working anymore. Does someone know a way around this?

TemplateBinding "Foreground" doesn't work

I have a listbox the item template of which is a listbox. I am trying to set the "Foreground" property of the internal listbox to be the same as that of the main listbox. This is failing. Following is the code snippet. In here Foreground="{TemplateBinding Foreground}" has no effect.
<ListBox x:Name="GroupListBox" Grid.Column="1" Grid.Row="1" Style="{StaticResource ListBoxStyle1}" Visibility="Collapsed"
BorderBrush="Transparent" Background="Transparent" Foreground="{Binding WebForeground}">
<ListBox.ItemTemplate>
<DataTemplate x:Name="test">
<StackPanel Orientation="Horizontal" >
<!--<TextBlock Text="{Binding Rank}" FontFamily="Arial" FontSize="13" TextDecorations="Underline" TextWrapping="Wrap" Width="115" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,15,0,0"/>-->
<ListBox x:Name="SubGroupListBox" ItemsSource="{Binding InnerList }" ItemTemplate="{StaticResource ItemTemplateKey1}"
ItemsPanel="{StaticResource ItemsPanelKey}" Style="{StaticResource ListBoxStyle1}"
BorderBrush="Transparent" Background="Transparent" Foreground="{TemplateBinding Foreground}">
</ListBox>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
This example works for me - it may apply to what you are trying to do:
<ListBox x:Name="GroupListBox" Foreground="Purple">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<ListBox Foreground="{Binding Foreground, RelativeSource={RelativeSource Self}}">
<TextBox Text="{Binding Mode=OneWay}" FontSize="35" Foreground="{Binding Foreground, RelativeSource={RelativeSource Self}}" />
</ListBox>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemsSource>
<x:Array Type="{x:Type sys:String}">
<sys:String>Sample Data</sys:String>
</x:Array>
</ListBox.ItemsSource>
</ListBox>

Resources