I have an ItemsControl, the ItemsPanel is made by a DockPanel.
Inside of the DockPanel, I can have one, two, or three buttons. The problem arises from the width of the buttons: I want the three elements with the same size, but the elements take the size that they need (the last element take the excess width because LastChildFill is true).
Can I give the buttons the same width without providing their size manually?
<ItemsControl ItemTemplate="{StaticResource Template1}" ItemsSource="{Binding Path=options, Mode=OneWay}" ItemsPanel="{StaticResource Panel1}" HorizontalContentAlignment="Stretch"/>
<ItemsPanelTemplate x:Key="Panel1">
<DockPanel Height="Auto" Width="Auto" LastChildFill="True"/>
</ItemsPanelTemplate>
<DataTemplate x:Key="BasicasTemplateOpciones" DataType="{x:Type local:MyOption}">
<Grid HorizontalAlignment="Stretch">
<Button DataContext="{Binding}" HorizontalContentAlignment="Stretch" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" >
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Center">
<StackPanel Orientation="Horizontal">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Stretch"/>
<TextBlock HorizontalAlignment="Right" VerticalAlignment="Stretch"/>
</StackPanel>
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
</Grid>
</DataTemplate>
A UniformGrid with a single row will do what you want:
<ItemsPanelTemplate x:Key="Panel1">
<UniformGrid Rows="1" />
</ItemsPanelTemplate>
Example:
<StackPanel Orientation="Vertical">
<StackPanel.Resources>
<ItemsPanelTemplate x:Key="Panel1">
<UniformGrid Rows="1" />
</ItemsPanelTemplate>
<Style TargetType="ItemsControl" x:Key="ICStyle">
<Style.Resources>
<Style TargetType="Button">
<Setter Property="Margin" Value="2" />
</Style>
</Style.Resources>
<Setter Property="ItemsPanel" Value="{StaticResource Panel1}" />
</Style>
</StackPanel.Resources>
<ItemsControl Style="{StaticResource ICStyle}">
<Button>Foo</Button>
</ItemsControl>
<ItemsControl Style="{StaticResource ICStyle}">
<Button>Foo</Button>
<Button>Bar</Button>
</ItemsControl>
<ItemsControl Style="{StaticResource ICStyle}">
<Button>Foo</Button>
<Button>Bar</Button>
<Button>Baz</Button>
</ItemsControl>
</StackPanel>
Related
I'm making a calendar as an exercise, and I get the Listbox Items to generate correctly. However, I don't want any spaces in between the borders. I have set HorizontalContentAlignment to stretch, and that didn't fix it.
<Grid>
<ListBox x:Name="monthCalendarListbox"
Grid.RowSpan="2"
BorderThickness="0"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="5"
Columns="7"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Black"
BorderThickness="1">
<StackPanel Background="Transparent"
HorizontalAlignment="Stretch">
<Label Content="{Binding DayNumber}"/>
<Label Content="{Binding Message}"
VerticalAlignment="Center"
HorizontalAlignment="Center"/>
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
EDIT:
It looks like ListBoxItem was getting a transparent border thrown in in addition to some padding (mentioned in the comments). So no more spacing but now I have double thick borders where the ListBoxItems meet. Any idea how to fix that?
<Grid>
<ListBox x:Name="monthCalendarListbox"
BorderThickness="0"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Style.Resources>
<SolidColorBrush x:Key="x:Static SystemColors.HighlightBrushKey" Color="Transparent"/>
<SolidColorBrush x:Key="x:Static SystemColors.ControlBrushKey" Color="Transparent"/>
<SolidColorBrush x:Key="x:Static SystemColors.HighlightTextBrushKey" Color="Black"/>
</Style.Resources>
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="BorderThickness" Value="1"/>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="5"
Columns="7"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Background="Transparent">
<Label Content="{Binding DayNumber}"/>
<Label Content="{Binding Message}"
VerticalAlignment="Center"
HorizontalAlignment="Center"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
I have an ItemsControl, the ItemsPanel is made by a DockPanel.
Inside of the DockPanel, I can have one, two, or three buttons. The problem arises from the width of the buttons: I want the three elements with the same size, but the elements take the size that they need (the last element take the excess width because LastChildFill is true).
Can I give the buttons the same width without providing their size manually?
<ItemsControl ItemTemplate="{StaticResource Template1}" ItemsSource="{Binding Path=options, Mode=OneWay}" ItemsPanel="{StaticResource Panel1}" HorizontalContentAlignment="Stretch"/>
<ItemsPanelTemplate x:Key="Panel1">
<DockPanel Height="Auto" Width="Auto" LastChildFill="True"/>
</ItemsPanelTemplate>
<DataTemplate x:Key="BasicasTemplateOpciones" DataType="{x:Type local:MyOption}">
<Grid HorizontalAlignment="Stretch">
<Button DataContext="{Binding}" HorizontalContentAlignment="Stretch" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" >
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Center">
<StackPanel Orientation="Horizontal">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Stretch"/>
<TextBlock HorizontalAlignment="Right" VerticalAlignment="Stretch"/>
</StackPanel>
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
</Grid>
</DataTemplate>
A UniformGrid with a single row will do what you want:
<ItemsPanelTemplate x:Key="Panel1">
<UniformGrid Rows="1" />
</ItemsPanelTemplate>
Example:
<StackPanel Orientation="Vertical">
<StackPanel.Resources>
<ItemsPanelTemplate x:Key="Panel1">
<UniformGrid Rows="1" />
</ItemsPanelTemplate>
<Style TargetType="ItemsControl" x:Key="ICStyle">
<Style.Resources>
<Style TargetType="Button">
<Setter Property="Margin" Value="2" />
</Style>
</Style.Resources>
<Setter Property="ItemsPanel" Value="{StaticResource Panel1}" />
</Style>
</StackPanel.Resources>
<ItemsControl Style="{StaticResource ICStyle}">
<Button>Foo</Button>
</ItemsControl>
<ItemsControl Style="{StaticResource ICStyle}">
<Button>Foo</Button>
<Button>Bar</Button>
</ItemsControl>
<ItemsControl Style="{StaticResource ICStyle}">
<Button>Foo</Button>
<Button>Bar</Button>
<Button>Baz</Button>
</ItemsControl>
</StackPanel>
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>
I want to display a Line of Text via an ItemsControl beside a RichTextBox. Therefore I created this ControlTemplate:
<RichTextBox Margin="5,0,5,0">
<RichTextBox.Resources>
<Style TargetType="{x:Type Paragraph}">
<Setter Property="Margin" Value="5,0,5,0"/>
<Setter Property="LineHeight" Value="30"/>
<Setter Property="LineStackingStrategy" Value="BlockLineHeight"/>
</Style>
</RichTextBox.Resources>
<RichTextBox.Template>
<ControlTemplate>
<StackPanel Orientation="Horizontal">
<ItemsControl ItemsSource="{Binding Lines}" Margin="5,0,5,0">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ToggleButton Content="{Binding}" Height="{Binding BIND_ME_TO_LineHeigh_OF_PARAGRAPH" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Border Name="Border" CornerRadius="2" Padding="2" Background="White" BorderBrush="Black" BorderThickness="0" >
<ScrollViewer Margin="0" x:Name="PART_ContentHost"/>
</Border>
</StackPanel>
</ControlTemplate>
</RichTextBox.Template>
To make the Items in the ItemsControl the same size as the paragraph's line I want to bind the ToggleButton's height to the LineHeight of the Paragraph which I defined in the Style for the Pararaph ( ). How can I do that?
Thanks
I know a ControlTemplate is suppose to replace the default one entirely and this seems to work when not using a HierarchicalDataTemplate. However using a HierarchicalDataTemplate my control template seems to be partially used - the TreeViewItem is the control I specified containing an image etc. BUT still appears as a node with the default expander to show its children - not specified in my Template (I want my children to always be shown, but thats beside the point). It looks like this:
<TreeView>
<TreeView.Resources>
<Style x:Key="MyNodeStyle" TargetType="TreeViewItem">
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="IsExpanded" Value="true"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TreeViewItem">
<StackPanel Orientation="Vertical" HorizontalAlignment="Center">
<Border CornerRadius="8" BorderThickness="1" Padding="2" Margin="4, 6" BorderBrush="{StaticResource itemBorderBrush}" Background="{StaticResource itemBackgroundBrush}" x:Name="border">
<DockPanel LastChildFill="False">
<StackPanel Orientation="Vertical" DockPanel.Dock="Top" Height="80">
<TextBlock Text="{Binding Path=DisplayValue}" HorizontalAlignment="Center" FontWeight="Bold"/>
<Image Source="MyNode.png" Stretch="None"/>
<TextBlock Text="{Binding Path=Notes}" TextWrapping="Wrap" Width="150"/>
</StackPanel>
</DockPanel>
</Border>
<ItemsPresenter />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" IsItemsHost="True" HorizontalAlignment="Center" />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
<HierarchicalDataTemplate DataType="{x:Type src:MyNode}" ItemsSource="{Binding Path=Children}" >
<TreeViewItem Style="{StaticResource MyNodeStyle}"/>
</HierarchicalDataTemplate>
</TreeView.Resources>
<!-- Arrange the root items horizontally. -->
<TreeView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel IsItemsHost="True" Orientation="Horizontal" HorizontalAlignment="Center" />
</ItemsPanelTemplate>
</TreeView.ItemsPanel>
</TreeView>
For some reason only when using a HierarchicalDataTemplate the ItemsPanel and Setter does not seem to be applied and the children are presented in the default expander. How did that expander get there when I am using my own ControlTemplate!?##$
I don't think you should put the TreeViewItem inside your HierarchicalDataTemplate.
Try this:
<HierarchicalDataTemplate DataType="{x:Type src:MyNode}" ItemsSource="{Binding Path=Children}" >
<StackPanel Orientation="Vertical" DockPanel.Dock="Top" Height="80">
<TextBlock Text="{Binding Path=DisplayValue}" HorizontalAlignment="Center" FontWeight="Bold"/>
<Image Source="MyNode.png" Stretch="None"/>
<TextBlock Text="{Binding Path=Notes}" TextWrapping="Wrap" Width="150"/>
</StackPanel>
</HierarchicalDataTemplate>
Now, your template becomes:
<ControlTemplate TargetType="TreeViewItem">
<StackPanel Orientation="Vertical" HorizontalAlignment="Center">
<Border CornerRadius="8" BorderThickness="1" Padding="2" Margin="4, 6" x:Name="border">
<DockPanel LastChildFill="False">
<ContentPresenter ContentSource="Header" />
</DockPanel>
</Border>
<ItemsPresenter />
</StackPanel>
</ControlTemplate>
Is that how you intended it to look?
Edit: the original expanders are probably there because you only use your style for child items - make your style the ItemContainerStyle for the treeview:
<Window.Resources>
<Style x:Key="MyNodeStyle" TargetType="TreeViewItem">
....
<TreeView ItemContainerStyle="{StaticResource MyNodeStyle}">