I have CanContentScroll property set to True in the parent Scrollviewer. This ScrollViewer is applicable to the entire Window. Now, this ScrollViewer has ItemsControl as its child. Each item in the ItemsControl is templated as an Expander and the content of this Expander contains another ItemsControl embedded in the child ScrollViewer. If I remove the child ScrollViewer, the Window content is scrollable, however, if I put it back in, I'm unable to Scroll.
I need the child ScrollViewer because I am limiting the height of the Expander content. When I scroll, the event is not being fired to the parent ScrollViewer in the Visual Tree. How and by using which event I can bubble it to the parent ScrollViewer in the Visual Tree?
This is my code:
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:behaviors="clr-namespace:AttributeSelector" xmlns:sys="clr-namespace:System;assembly=mscorlib"
MinHeight="350" MinWidth="525" MaxWidth="1200" MaxHeight="900" WindowStartupLocation="CenterScreen" SizeToContent="WidthAndHeight">
<sys:Boolean x:Key="BooleanTrue">True</sys:Boolean>
<sys:Boolean x:Key="BooleanFalse">False</sys:Boolean>
<behaviors:TextToHighlightedTextBlockConverter x:Key="TextToHighlightedTextBlockConverter" />
<behaviors:GroupNameToICollectionViewConverter x:Key="GroupNameToICollectionViewConverter" />
<LinearGradientBrush x:Key="LinearGradientBrush" StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Color="White" Offset="0"/>
<GradientStop Color="#E3E3E3" Offset="1"/>
<!--<GradientStop Color="#C0C0C0" Offset="1"/>-->
</LinearGradientBrush>
<Style x:Key="MainBorderStyle" TargetType="{x:Type Border}">
<Setter Property="Background" Value="{StaticResource ResourceKey=LinearGradientBrush}" />
<Setter Property="BorderBrush" Value="LightGray" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="CornerRadius" Value="5" />
<Setter Property="SnapsToDevicePixels" Value="True" />
</Style>
</Window.Resources>
<DockPanel LastChildFill="True" Margin="10">
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="10">
<!-- 3-4 TextBlocks/TextBoxes defined here -->
</StackPanel>
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" CanContentScroll="True">
<ItemsControl ItemsSource="{Binding UniqueGroups}" ScrollViewer.CanContentScroll="True"
ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel IsItemsHost="True" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Margin="5" Style="{StaticResource ResourceKey=MainBorderStyle}">
<Expander x:Name="GroupExpander" Header="{Binding}" IsExpanded="True" Margin="5">
<Expander.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" Background="Transparent" Margin="10,0,0,0"
FontWeight="DemiBold" FontSize="16" FontStretch="Expanded"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Expander}}, Path=ActualWidth}"/>
</DataTemplate>
</Expander.HeaderTemplate>
<Expander.Content>
<ScrollViewer Margin="20,5,10,5" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" CanContentScroll="True">
<ItemsControl ItemsSource={Binding SubItems} ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel MaxHeight="300" Orientation="Vertical" UseLayoutRounding="True" IsItemsHost="True" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.GroupStyle>
<GroupStyle>
<GroupStyle.Panel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal" IsItemsHost="True" />
</ItemsPanelTemplate>
</GroupStyle.Panel>
</GroupStyle>
</ItemsControl.GroupStyle>
</ItemsControl>
</ScrollViewer>
</Expander.Content>
</Expander>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</DockPanel>
Related
how do make a letter pop out of the border?
I want to express it like this picture
I wrote a letter in the text on Border,
The letters are covered like in the picture.
Can you make this stick out like the picture below?
How can solve this?
this is my xaml code
<Window x:Class="TestProject.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TestProject"
Width="800"
Height="600"
Title="ItemsControl 엘리먼트 : Template/ItemsPanel/ItemTemplate/ItemContainerStyle 속성 사용하기"
FontFamily="나눔고딕코딩"
FontSize="16">
<Window.Resources>
<local:TaskCollection x:Key="TaskCollectionKey" />
</Window.Resources>
<Grid>
<ItemsControl
HorizontalAlignment="Center"
VerticalAlignment="Center"
ItemsSource="{Binding Source={StaticResource TaskCollectionKey}}">
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<Border
BorderBrush="Black"
BorderThickness="3"
CornerRadius="15">
<ItemsPresenter />
</Border>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<DataTemplate.Resources>
<Style TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Center" />
</Style>
</DataTemplate.Resources>
<Grid>
<Ellipse
Stroke="Black"
StrokeThickness="3"
Fill="Gold" />
<StackPanel
HorizontalAlignment="Center"
VerticalAlignment="Center">
<TextBlock
Margin="5"
Text="{Binding Path=Priority}" />
<TextBlock
Margin="5"
Text="{Binding Path=TaskName}" />
</StackPanel>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Control.Margin" Value="10" />
<Setter Property="Control.Width" Value="100" />
<Setter Property="Control.Height" Value="100" />
<Style.Triggers>
<Trigger
Property="Control.IsMouseOver" Value="True">
<Setter Property="Control.ToolTip"
Value="{Binding RelativeSource={x:Static RelativeSource.Self},
Path=Content.Description}" />
</Trigger>
</Style.Triggers>
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</Grid>
</Window>
If you put the textblock in a canvas, that will not clip.
<StackPanel
HorizontalAlignment="Center"
VerticalAlignment="Center">
<TextBlock
Margin="5"
Text="{Binding Path=Priority}" />
<Canvas>
<TextBlock
Text="{Binding Path=TaskName}" />
</Canvas>
</StackPanel>
i have the following xaml where if Status is OK then label background is green, and if ERROR label background in red, this works fine for the parent label, but when i add a child i also want that to adopt the parent background color? is there a way to allow the datatrigger to act for both parent and child labels ?
heres the xaml
<Window x:Class="wpfdemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:wpfdemo"
mc:Ignorable="d"
Title="MainWindow" Height="50" Width="50" SizeToContent="WidthAndHeight" ResizeMode="NoResize" Topmost="True" AllowsTransparency="True" WindowStyle="None" Background="Transparent">
<ItemsControl ItemsSource="{Binding Path=Parents}" Grid.IsSharedSizeScope="True">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type local:Parent}">
<Grid>
<Grid.ContextMenu>
<ContextMenu>
<MenuItem Header="Click Me" Click="Button_Click" />
</ContextMenu>
</Grid.ContextMenu>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="ParentColumn" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<!-- Parent label -->
<Label Content="{Binding Path=Name}"
x:Name="Label" HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" BorderBrush="Black" BorderThickness="1" FontFamily="Verdana" Foreground="White"/>
<!-- Errors -->
<ItemsControl ItemsSource="{Binding Path=Errors}"
Grid.Column="1">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type local:Child}">
<Label Content="{Binding Path=Name}"
HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" BorderBrush="Black" BorderThickness="1" FontFamily="Verdana" Foreground="White"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Grid>
<DataTemplate.Triggers>
<!-- Parent is ok -->
<DataTrigger Binding="{Binding Path=Status}"
Value="OK">
<Setter TargetName="Label" Property="Background" Value="#BF008000" />
</DataTrigger>
<!-- Parent is error -->
<DataTrigger Binding="{Binding Path=Status}"
Value="ERROR">
<Setter TargetName="Label" Property="Background" Value="#BFFFFF00" />
<Setter TargetName="Label" Property="Foreground" Value="Black" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Thanks
TargetName is control's name,not type.
try :
<DataTemplate >
<Label x:Name="ChildLabel" Content="{Binding Path=Name}"/>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=DataContext.Status,RelativeSource={ RelativeSource Mode=TemplatedParent}}" Value="OK">
<Setter TargetName="ChildLabel" Property="Background" Value="#BF008000" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
I have currently a ListBox in a DockPanel (that represents a wonderful Diaballik game) and at the end I want to be able to show up a label Victory over the grid made by the boxes like in the picture :
<DockPanel>
<ListBox DockPanel.Dock="Top" ItemsSource="{Binding Cases}" SelectedItem="{Binding SelectedCase, Mode=TwoWay}" HorizontalAlignment="Center" VerticalAlignment="Top" SnapsToDevicePixels="True">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="{Binding Size}"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Padding" Value="0"/>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid >
<Ellipse Fill="{Binding Color}" Width="50" Height="50" Visibility="{Binding HasPawn, Converter={StaticResource bool2visibility}}"/>
...
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Label Content="VICTORY" /> <!-- How can this go over the list box ? -->
</DockPanel>
You could do something like this (the behaviour of a Grid is such that it will just "stack" the items "on top" of each other):
<DockPanel>
<Grid DockPanel.Dock="Top">
<ListBox ItemsSource="{Binding Cases}" SelectedItem="{Binding SelectedCase, Mode=TwoWay}" HorizontalAlignment="Center" VerticalAlignment="Top" SnapsToDevicePixels="True">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="{Binding Size}"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Padding" Value="0"/>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid >
<Ellipse Fill="{Binding Color}" Width="50" Height="50" Visibility="{Binding HasPawn, Converter={StaticResource bool2visibility}}"/>
...
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Label Content="VICTORY" HorizontalAlignment="Center" VerticalAlignment="Center" /> <!-- How can this go over the list box ? -->
</Grid>
</DockPanel>
I'm trying to group my ObservableCollection using CollectionViewSource, it seems to work for items but it's not showing the bind property value for GroupBox.
Here is what I'm trying:
I've List<Object> containing properties Description, Season. I want to group by Season. Here is my xml:
<mah:MetroWindow x:Class="eCatalog_Launcher.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:eCatalog_Launcher"
xmlns:mah="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
xmlns:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks"
mc:Ignorable="d"
Title="eCatalog Launcher"
WindowState="Maximized"
Loaded="MetroWindow_Loaded"
Closing="MetroWindow_Closing">
<Window.Resources>
<CollectionViewSource x:Key="catalogsBySeasons"
Source="{Binding Path=Catalogs, Mode=TwoWay}">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="Season" />
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
</Window.Resources>
<ScrollViewer>
<ItemsControl ItemsSource="{Binding Source={StaticResource catalogsBySeasons}}">
<ItemsControl.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<GroupBox Header="{Binding Season}">
<ItemsPresenter />
</GroupBox>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ItemsControl.GroupStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<mah:Tile Title="{Binding Description}"
Tag="{Binding}"
Style="{StaticResource SmallTileStyle}"
Click="Tile_Click">
<iconPacks:PackIconMaterial Width="32"
Height="32"
Margin="0, -30, 0, 0"
Kind="{Binding Kind}">
</iconPacks:PackIconMaterial>
</mah:Tile>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</StackPanel>
It's showing the Season value as GroupBox Heading.
Is there anything wrong?
You should bind to the Name property of the group:
<ControlTemplate TargetType="{x:Type GroupItem}">
<GroupBox Header="{Binding Name}">
<ItemsPresenter />
</GroupBox>
</ControlTemplate>
This should display the actual value of the Season property that you group by.
I'm new to WPF and I'm trying to visualize images with rectangles drawn over the faces in each image.
I have information about the width, height, top left X and Y co-ordinates (in pixels wrt the original image) of each rectangle in each image.
My C#:
public class FaceRectangle
{
Rectangle rect;
public FaceRectangle(int topX, int topY, int width, int height)
{
rect = new Rectangle(topX, topY, width, height);
}
public int X { get { return rect.X; } }
public int Y { get { return rect.Y; } }
public int Width { get { return rect.Width; } }
public int Height { get { return rect.Height; } }
...
}
public class Photo
{
public BitmapImage Img { get; set; }
public string Filename { get; private set; }
public ObservableCollection<FaceRectangle> Faces { get; private set; }
...
}
public class PhotoCollection : ObservableCollection<Photo>
{
...
}
After looking through related questions, this is the XAML I have - but I'm having trouble overlaying the rectangles on the image and adjusting their size and posiiton to match the image. How should I go about achieving this?
UPDATED XAML
<Window x:Class="TempFaceViewer.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
xmlns:er="clr-namespace:TempFaceViewer"
xmlns:scm="clr-namespace:System.ComponentModel;assembly=System">
<Window.Resources>
<Style TargetType="{x:Type ListBoxItem}" x:Key="ImageListItem">
<Style.Resources>
<!-- Background of selected item when focussed -->
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Gray" />
</Style.Resources>
</Style>
<!-- Main photo catalog view -->
<Style TargetType="{x:Type ListBox}" x:Key="PhotoListBoxStyle">
<Setter Property="Foreground" Value="White" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBox}" >
<WrapPanel Margin="5" IsItemsHost="True" Orientation="Horizontal"
ItemHeight="95"
ItemWidth="95"
VerticalAlignment="Top" HorizontalAlignment="Stretch" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- Image Template -->
<DataTemplate DataType="{x:Type er:Photo}">
<Grid VerticalAlignment="Center" HorizontalAlignment="Center" Margin="6">
<!-- Drop Shadow -->
<Border HorizontalAlignment="Stretch" VerticalAlignment="Stretch" CornerRadius="4" Background="#44000000">
<Border.RenderTransform>
<TranslateTransform X="5" Y="5" />
</Border.RenderTransform>
<Border.BitmapEffect>
<BlurBitmapEffect Radius="8" />
</Border.BitmapEffect>
</Border>
<!-- Image Template -->
<Border Padding="4" Background="White" BorderBrush="#22000000" BorderThickness="1">
<Image Source="{Binding Img}" />
</Border>
</Grid>
</DataTemplate>
</Window.Resources>
<Grid DataContext="{Binding Source={StaticResource Photos}}">
<Grid.RowDefinitions>
<RowDefinition Height="100*" />
<RowDefinition Height="100*" />
</Grid.RowDefinitions>
<DockPanel Grid.Column="0" Grid.Row="0" Margin="0,0,0,10" Height="160">
<ScrollViewer VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Auto">
<ListBox
IsSynchronizedWithCurrentItem="True"
Name="PhotosListBox"
Style="{StaticResource PhotoListBoxStyle}"
Margin="5"
SelectionMode="Extended"
ItemsSource="{Binding}"
SelectedIndex="0"
ItemContainerStyle="{StaticResource ImageListItem}"
>
</ListBox>
</ScrollViewer>
</DockPanel>
<Viewbox Grid.Column="0" Grid.Row="1">
<Grid>
<Image Source="{Binding Img}" />
<ItemsControl ItemsSource="{Binding Faces}" HorizontalAlignment="Left" VerticalAlignment="Top">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas IsItemsHost="True" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="er:FaceRectangle">
<Rectangle Width="{Binding Width}" Height="{Binding Height}" Stroke="Red" StrokeThickness="1" />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Canvas.Left" Value="{Binding X}" />
<Setter Property="Canvas.Top" Value="{Binding Y}" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</Grid>
</Viewbox>
</Grid>
</Window>
Thanks!
Set your canvas top/left properties in ItemContainerStyle instead and put both the background image and the ItemsControl in a Grid so that they're overlapping, aligned and using the same scale (pixels). If you wrap this grid in a ViewBox then everything will scale together as needed:
<Viewbox>
<Grid>
<Image Source="{Binding Img}" />
<ItemsControl ItemsSource="{Binding Faces}" HorizontalAlignment="Left" VerticalAlignment="Top">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas IsItemsHost="True" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="er:FaceRectangle">
<Rectangle Width="{Binding Width}" Height="{Binding Height}" Stroke="Red" StrokeThickness="1" />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Canvas.Left" Value="{Binding X}" />
<Setter Property="Canvas.Top" Value="{Binding Y}" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</Grid>
</Viewbox>
UPDATE: You'll have to post any other code on the page. I've tried putting it in a grid as you describe and it works fine, there's nothing else in my window other than this:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="100*" />
<RowDefinition Height="100*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100*" />
<ColumnDefinition Width="100*" />
</Grid.ColumnDefinitions>
<Viewbox Grid.Column="0" Grid.Row="1">
<Grid>
<Image Source="{Binding Img}" />
<ItemsControl ItemsSource="{Binding Faces}" HorizontalAlignment="Left" VerticalAlignment="Top">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas IsItemsHost="True" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="er:FaceRectangle">
<Rectangle Width="{Binding Width}" Height="{Binding Height}" Stroke="Red" StrokeThickness="1" />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Canvas.Left" Value="{Binding X}" />
<Setter Property="Canvas.Top" Value="{Binding Y}" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</Grid>
</Viewbox>
</Grid>
I suspect you've got resources elsewhere (i.e. Styles, DataTemplates etc) that are changing the default behavior, trying running my code in an isolated app.