ItemsPanel Template has no effect - c#

I'm trying to swap the ItemsPanel in a ListBox for a WrapPanel but the ItemsPanelTemplate on the style doesn't seem to be having an effect. The style is found and applied because the border and background colours change, but inspecting with snoop shows no WrapPanel.
<Style x:Key="CocktailGrid" TargetType="ListBox" BasedOn="{StaticResource {x:Type ListBox}}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="Background" Value="White" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="BorderBrush" Value="Black" />
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="SelectionMode" Value="Single" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<WrapPanel
IsItemsHost="True"
Width="{Binding
Path=ActualWidth,
RelativeSource={RelativeSource
Mode=FindAncestor,
AncestorType=
{x:Type ScrollContentPresenter}}}" />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="80" />
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Image Grid.Row="0" Source="{Binding ImageName}" Height="80" Stretch="Uniform"/>
<TextBlock Grid.Row="1" Text="{Binding Name}" TextWrapping="Wrap" TextTrimming="CharacterEllipsis"/>
</Grid>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
The ListBox is declared as:
<ListBox x:Name="lstCocktails" PreviewKeyDown="dg_PreviewKeyDown" ItemsSource="{Binding Source={StaticResource drinksSource}}" SelectedItem="{Binding SelectedItem,ElementName=root,Mode=TwoWay}" Style="{StaticResource CocktailGrid}"
SelectionMode="Single" MouseDoubleClick="lstCocktails_MouseDoubleClick">
Snoop visual tree:
I've overridden ItemsPanels in other parts of the app but for some reason this one is eluding me

Use this instead of ItemsTemplate
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBox">
<Border Background="{TemplateBinding ListBox.Background}" CornerRadius="5">
<WrapPanel IsItemsHost="True"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
It works

Related

How to design this ListViewItem

I want my ListViewItem to look like this. As you can see when the ListViewItem is selected/has focus the Border should change color.
The Main Problem is that I can't put a Border around the ContenPresenter in the ControlTemplate because than also the TextBox with the "Description"-Binding will be inside the Border. But I only want the TextBox and Icon to be inside the Border that changes Colors and not also the Description ("Nachname", "Vorname").
This is the XAML I have so far. I don't know how to change the border in the ControlTemplate:
<ListView x:Name="SearchFields" Grid.Row="0" Grid.Column="0" ItemsSource="{Binding CustomerSearchFields}" SelectedItem="{Binding selectedSearchField, UpdateSourceTrigger=LostFocus}" Style="{StaticResource MaterialDropShadowStyle}"
BorderThickness="0,0,2,0" Padding="24,24,24,0" HorizontalContentAlignment="Stretch" helper:EnterKeyTraversal.IsEnabled="True" KeyboardNavigation.TabNavigation="Cycle" FontFamily="{StaticResource DefaultFontFamily}"
Background="{StaticResource ColorLightGray2}">
<ListView.Resources>
<DataTemplate DataType="{x:Type model:CustomerSeachFieldViewModel}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="48" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="{Binding Description}" FontSize="{StaticResource FontSizeSmall}" FontWeight="SemiBold" Foreground="{StaticResource ColorDarkGray}" Margin="0,0,0,4" />
<Border x:Name="PART_Border" Grid.Row="1" BorderThickness="1" BorderBrush="{StaticResource ColorGray}">
<Grid Background="White">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="48" />
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" Text="{Binding SearchText}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" FontSize="{StaticResource FontSizeNormal}" Padding="12,15" BorderThickness="0" />
<Border Grid.Column="1" Background="{StaticResource ColorLightGray2}" Margin="8">
<ctrl:IconViewbox IconData="{StaticResource IconPathSearch}" IconSize="16" IsTabStop="False" />
</Border>
</Grid>
</Border>
</Grid>
</DataTemplate>
</ListView.Resources>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="IsTabStop" Value="False" />
<Setter Property="Margin" Value="0,0,0,24" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<ContentPresenter Content="{Binding}" />
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="IsSelected" Value="True" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Trigger.Setters>
<Setter Property="BorderBrush" Value="Fuchsia" />
</Trigger.Setters>
</Trigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
</ListView>
You can add a Trigger to your Border named PART_Border as follow:
<Border x:Name="PART_Border" Grid.Row="1" BorderThickness="1" >
<Border.Style>
<Style TargetType="Border">
<Setter Property="BorderBrush" Value="DarkGray" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListViewItem}}}"
Value="True" >
<Setter Property="BorderBrush" Value="Black"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<Grid Background="White">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="48" />
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0"
Text="{Binding SearchText}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" FontSize="15" Padding="12,15" BorderThickness="0" />
<Border Grid.Column="1" Background="Gray" Margin="8">
<Rectangle Width="20" Height="20" />
</Border>
</Grid>
</Border>
Please note that I replaced some StaticResource mapped to some Colors from your code with standard color in order to test my code.
I also replaced the icon with a Rectangle for the same reason.
Try for your IsSelected trigger:
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="PART_Border" Property="BorderBrush" Value="Fuchsia" />
<Setter TargetName="PART_Border" Property="BorderThickness" Value="1" />
</Trigger>
You could add a Style with a DataTrigger that binds to the IsSelected property of the parent ListViewItem to the Border in your DataTemplate:
<Border x:Name="PART_Border" Grid.Row="1" BorderThickness="1">
<Border.Style>
<Style TargetType="Border">
<Setter Property="BorderBrush" Value="{StaticResource ColorGray}" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=ListViewItem}}"
Value="True">
<Setter Property="BorderBrush" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
Note that you need to set the default value of the property ({StaticResource ColorGray}) using a Style setter for the DataTrigger to be able to set the property when the ListViewItem is selected.

How to set Combobox dropdown list width to the Combobox it belongs to?

See picture below, how to align dropdown list border to the actual combo box?
https://imgur.com/uNO45F2
Here is the code for Combobox, which uses customized ComboBoxItem style,
<ComboBox Grid.Row="0" Grid.Column="0" ItemsSource="{Binding ASDevicesView, Mode=OneWay , UpdateSourceTrigger=PropertyChanged}" AutomationProperties.AutomationId="4314"
SelectedItem="{Binding SDevice}" IsEditable="True" Text="{Binding SearchText}" MaxDropDownHeight="166" ItemContainerStyle="{StaticResource MyComboBoxItemStyle}">
<ComboBox.Style>
<Style TargetType="{x:Type ComboBox}">
<Style.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="IsDropDownOpen" Value="true" />
</Trigger>
</Style.Triggers>
</Style>
</ComboBox.Style>
</ComboBox>
Here is the code for ComboBoxItem style,
<Style x:Key="MyComboBoxItemStyle" BasedOn="{StaticResource {x:Type ComboBoxItem}}" TargetType="{x:Type ComboBoxItem}">
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="RenderOptions.ClearTypeHint" Value="Enabled" />
<Setter Property="Width" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ActualWidth}" />
<Setter Property="Height" Value="40" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBoxItem">
<Grid Background="Transparent" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="36"/>
<ColumnDefinition Width="AUTO"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="AUTO"/>
</Grid.RowDefinitions>
<Image Source="{Binding Icon}" Width="12" Height="12" Margin="3,3,3,3" Grid.Row="0" Grid.Column="0"/>
<TextBlock Text="{Binding DName}" Grid.Row="0" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Center" FontWeight="Bold"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I think the problem is that the ComboBox is not the TemplatedParent of the ComboBoxItem (indeed it was pointed out e.g. in this comment), so better to search it explicitly:
<Setter Property="Width" Value="{Binding
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ComboBox}}, Path=ActualWidth}" />

'MenuButton' TargetType does not match type of element 'Button'

A UserControl has a button with Style="{StaticResource MenuIconByttonStyle}" defined in App.xaml, but using this UserControl in a window xaml gives error :
'MenuButton' TargetType does not match type of element 'Button'
Not sure what MenuButton refers to, as I can't find that defined anywhere.
If I use StaticResource MenuIconButtonStyle2, or FlatToolbarButton, I don't get this error.
Why may this be?
App.xaml :
<Application.Resources>
<Style x:Key="FlatToolbarButton" TargetType="Button">
<Setter Property="Width" Value="16"/>
<Setter Property="Height" Value="16"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="BorderBrush" Value="{x:Null}"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="Margin" Value="0"/>
</Style>
<Style x:Key="MenuIconButtonStyle" TargetType="Button" BasedOn="{StaticResource FlatToolbarButton}" >
<Setter Property="Background" Value="Red"/>
<Setter Property="Foreground" Value="Red"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid Background="#333333">
<Border CornerRadius="0" BorderThickness="0" BorderBrush="#333333">
<Image Source="{StaticResource MenuIcon}" Stretch="UniformToFill"/>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid Background="Aqua">
<Border CornerRadius="0" BorderThickness="1" BorderBrush="Aqua">
<Image Source="{StaticResource MenuIcon}" Stretch="UniformToFill"/>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="MenuIconButtonStyle2" TargetType="Button" BasedOn="{StaticResource FlatToolbarButton}" >
<Setter Property="Background" Value="{StaticResource MenuIconBrush}"/>
</Style>
TradeListUC.xaml:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="18"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<DockPanel Grid.Row="0" Background="#333333" >
<Label x:Name="TitleLabel" FontSize="12" Content="Trade List" Height="16" Width="100"
VerticalAlignment="Top" Padding="4,0,0,0" Foreground="White" />
<StackPanel DockPanel.Dock="Right" HorizontalAlignment="Right" Orientation="Horizontal" >
<TextBox x:Name="SymbolEntryTb" Width="100" Margin="0,0,1,0"
Background="#999999" BorderBrush="#AAAAAA"
HorizontalAlignment="Right" Padding="0,-1,0,0" />
<Button x:Name="MenuBtn" Style="{StaticResource MenuIconButtonStyle}">
</Button>
</StackPanel>
</DockPanel>
MainWindow.xaml :
<TabItem Header="Trades">
<Grid>
<UC:TradeListUC/>
</Grid>
</TabItem>

Alternating Background Color Grid Rows not working

I am trying to implement alternating background Color on my Rows.
I have an ItemsControl with an ItemTemplate in which I use Triggers on the Style Property of the Border.
But I end up with all RoyalBlue Rows instead of alternating with Red.
Can somene assist? Thank you very much!
<Page.Resources>
<DataTemplate x:Key="myTemplate" >
<Grid>
<Border BorderThickness="1" CornerRadius="2" Margin="2" VerticalAlignment="Stretch" Height="20" Width="Auto">
<Border.Style>
<Style TargetType="{x:Type Border}">
<Style.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="Red" />
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter Property="Background" Value="RoyalBlue" />
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Grid.Row="0" Content="{Binding Name}"/>
</Grid >
</Border>
</Grid>
</DataTemplate>
</Page.Resources>
<ScrollViewer >
<StackPanel >
<ItemsControl ItemsSource="{Binding Path=myElements}" ItemTemplate="{StaticResource myTemplate}" AlternationCount="2"/>
</StackPanel>
</ScrollViewer>
ItemsControl.AlternationIndex will be set against direct child of ItemsControl panel (ContentPresenter) so you need to use DataTrigger with RelativeSource binding and because it's an attached property you need to put in brackets like Path=(ItemsControl.AlternationIndex)
<Style TargetType="{x:Type Border}">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ContentPresenter}}, Path=(ItemsControl.AlternationIndex)}" Value="1">
<Setter Property="Background" Value="Red" />
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ContentPresenter}}, Path=(ItemsControl.AlternationIndex)}" Value="0">
<Setter Property="Background" Value="RoyalBlue" />
</DataTrigger>
</Style.Triggers>
</Style>

WPF Tab Control Headers on the left side

I want to make my custom tab control style. Headers should be on the left side and the content on the right side. Just like the standard styles can do it:
The selected element on the image above is the grid inside the active item. As you can see, it perfectly aligns next to the headers.
This is my design. The selected element is also the grid inside the active item, but it is just behind the headers instead of next to them. How can I align this grid next to the headers?
These are my styles for the tab item and tab control:
<Style TargetType="{x:Type TabControl}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabControl}">
<Grid KeyboardNavigation.TabNavigation="Local">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TabPanel
Name="HeaderPanel"
Grid.Row="0"
Panel.ZIndex="1"
Margin="0"
IsItemsHost="True"
KeyboardNavigation.TabIndex="1"
Background="AliceBlue" />
<Border
Name="Border"
Grid.Row="1"
BorderThickness="0"
KeyboardNavigation.TabNavigation="Local"
KeyboardNavigation.DirectionalNavigation="Contained"
KeyboardNavigation.TabIndex="2" >
<ContentPresenter
Name="PART_SelectedContentHost"
Margin="4"
ContentSource="SelectedContent" />
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type TabItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid>
<Border
Name="Border"
Margin="0"
Padding="10,4,4,4"
Background="Transparent"
Height="30"
Width="Auto"
BorderThickness="0">
<ContentPresenter x:Name="ContentSite"
VerticalAlignment="Center"
HorizontalAlignment="Left"
ContentSource="Header"
RecognizesAccessKey="True"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Panel.ZIndex" Value="100" />
<Setter TargetName="Border" Property="Background" Value="#FFFFFFFF" />
<Setter TargetName="Border" Property="BorderBrush" Value="#FF4576a9"></Setter>
<Setter TargetName="Border" Property="BorderThickness" Value="6, 0, 0, 0"></Setter>
<Setter TargetName="Border" Property="Padding" Value="4"></Setter>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Border" Property="Background" Value="Yellow" />
<Setter Property="Foreground" Value="Orange" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Thank you.
In your Custom Template, you need to set Grid.Column instead of Grid.Row since your grid is now 2 cols/1 row instead of 1 col/2 rows
<ControlTemplate TargetType="{x:Type TabControl}">
<Grid ...>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TabPanel
Name="HeaderPanel" Grid.Column="0" ... />
<Border Name="Border" Grid.Column="1" ... >
<ContentPresenter ... />
</Border>
</Grid>
</ControlTemplate>
You need not to create a custom control. You can use TabStripPlacement property of tabcontrol to achieve this functionality.
<TabControl TabStripPlacement="Left">
<TabItem Header="Tab1">
</TabItem>
<TabItem Header="Tab2">
</TabItem>
</TabControl>
You can refer http://www.wpf-tutorial.com/tabcontrol/tab-positions/ or https://msdn.microsoft.com/en-us/library/system.windows.controls.tabcontrol.tabstripplacement(v=vs.110).aspx

Categories

Resources