Collapse GroupBox border without collapsing content - c#

Is it possible to collapse the border of a GroupBox control in XAML (i.e. bind to a property in the VM) without also collapsing the content?
I don't just want to remove the border, which can be achieved by setting BorderThickness to 0 and Header to an empty string. I also want the GroupBox content to stretch out over where the border was.
<DataTemplate DataType="{x:Type config:ElementGroup}">
<DataTemplate.Resources>
<Style TargetType="{x:Type GroupBox}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=HideBorder}" Value="True">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
<Setter Property="Foreground" Value="{StaticResource TextColor}" />
<Setter Property="Header" Value="{Binding Path=ItemLabel}" />
<Setter Property="Margin" Value="5,0,5,0" />
</Style>
</DataTemplate.Resources>
<GroupBox>
<ItemsControl ItemsSource="{Binding Path=ElementList}" Visibility="Visible">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="{Binding Path=Columns}" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</GroupBox>
</DataTemplate>

Change your GroupBox Style to this:
<Style TargetType="{x:Type GroupBox}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=HideBorder}" Value="True">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GroupBox">
<ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
ContentStringFormat="{TemplateBinding ContentStringFormat}"
Margin="{TemplateBinding Padding}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
<Setter Property="Foreground" Value="{StaticResource TextColor}" />
<Setter Property="Header" Value="{Binding Path=ItemLabel}" />
<Setter Property="Margin" Value="5,0,5,0" />
</Style>

Collapsing a GroupBox, i.e. setting its Visibility property to Hidden or Collapse, will also collapse its Content.
If you don't want this, you could define another ItemsControl that you display when the GroupBox gets collapsed:
<DataTemplate DataType="{x:Type config:ElementGroup}">
<DataTemplate.Resources>
<Style TargetType="{x:Type GroupBox}">
<Setter Property="Foreground" Value="{StaticResource TextColor}" />
<Setter Property="Header" Value="{Binding Path=ItemLabel}" />
<Setter Property="Margin" Value="5,0,5,0" />
</Style>
</DataTemplate.Resources>
<Grid>
<GroupBox x:Name="gb">
<ItemsControl ItemsSource="{Binding Path=ElementList}" Visibility="Visible">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="{Binding Path=Columns}" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</GroupBox>
<ItemsControl x:Name="ic" ItemsSource="{Binding Path=ElementList}" Visibility="Collapsed">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="{Binding Path=Columns}" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=HideBorder}" Value="True">
<Setter TargetName="gb" Property="Visibility" Value="Collapsed" />
<Setter TargetName="ic" Property="Visibility" Value="Visible" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>

Related

How do I prevent switching between items using arrows in ListBox?

There is a ListBox in which there are several ListBoxItems. I want to move items using the arrows (up, down, left, right). When I add one element and then select it, it moves wonderfully, but when there are several elements, it turns out that when you click the arrows, they jump from one element to another and it turns out that I start moving another element. How can I prevent switching between elements using arrows? Attaching the code:
<ListBox x:Name="drawing"
Grid.Row="0"
ItemsSource="{Binding Path=Figures}"
SelectedItem="{Binding Path=SelectedFigure_M}"
SelectionMode="Single"
Background="Transparent"
Height="{Binding HeightDrawing}"
Width="{Binding WidthDrawing}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
MouseMove="drawing_MouseMove"
MouseLeftButtonDown="drawing_MouseLeftButtonDown"
MouseLeftButtonUp="drawing_MouseLeftButtonUp"
PreviewMouseWheel="drawing_MouseWheel"
KeyDown="drawing_KeyDown"
SelectionChanged="drawing_SelectionChanged">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplateSelector>
<local:FigureTemplateSelector EllipseTemplate="{StaticResource EllipseTemplate}"
LineTemplate="{StaticResource LineTemplate}"
RectangleTemplate="{StaticResource RectangleTemplate}"
TextTemplate="{StaticResource TextTemplate}"/>
</ListBox.ItemTemplateSelector>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Canvas.Left"
Value="{Binding X}" />
<Setter Property="Canvas.Top"
Value="{Binding Y}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border Name="Border"
BorderThickness="1"
Padding="1">
<ContentPresenter Name="Content" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected"
Value="true">
<Setter TargetName="Border"
Property="BorderBrush"
Value="Transparent" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
I answer my own question: First, you must prohibit switching between elements using the up, down, left, and right arrows. Required in the ListBox.ItemContainerStyle add a Setter:
<Setter Property="KeyboardNavigation.DirectionalNavigation" Value="None" />
Second: Required in the ListBox.ItemContainerStyle add a Setter that disables the IsTabStop function:
<Setter Property="IsTabStop" Value="False" />
The full code will look like this:
<ListBox x:Name="drawing"
Grid.Row="0"
ItemsSource="{Binding Path=Figures}"
SelectedItem="{Binding Path=SelectedFigure_M}"
SelectionMode="Single"
Background="Transparent"
Height="{Binding HeightDrawing}"
Width="{Binding WidthDrawing}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
MouseMove="drawing_MouseMove"
MouseLeftButtonDown="drawing_MouseLeftButtonDown"
MouseLeftButtonUp="drawing_MouseLeftButtonUp"
PreviewMouseWheel="drawing_MouseWheel"
KeyDown="drawing_KeyDown"
SelectionChanged="drawing_SelectionChanged">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplateSelector>
<local:FigureTemplateSelector EllipseTemplate="{StaticResource EllipseTemplate}"
LineTemplate="{StaticResource LineTemplate}"
RectangleTemplate="{StaticResource RectangleTemplate}"
TextTemplate="{StaticResource TextTemplate}"/>
</ListBox.ItemTemplateSelector>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Canvas.Left"
Value="{Binding X}" />
<Setter Property="Canvas.Top"
Value="{Binding Y}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border Name="Border"
BorderThickness="0.5"
Padding="1">
<ContentPresenter Name="Content" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected"
Value="true">
<Setter TargetName="Border"
Property="BorderBrush"
Value="Transparent" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="IsTabStop"
Value="False" />
<Setter Property="KeyboardNavigation.DirectionalNavigation"
Value="None" />
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
Source

Is there a way to fit a border into a ListView Item?

I prepared a table view with the ListView method.
Codes here :
<Grid>
<ScrollViewer>
<ListView x:Name="ListViewTableBorder" ItemsSource="{Binding TableName}">
<ListView.ItemTemplate>
<DataTemplate>
<Border Style="{StaticResource sales_border}">
<TextBlock Name="tablename" Text="{Binding tablename}" MinHeight="100" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White" FontSize="20"/>
</Border>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="5"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
</ScrollViewer>
</Grid>
Since I divide the screen into 5 columns, the ListViewItems automatically adjust the width. What can I do to make the borders inside the ListViewItems populate?
Border Style here :
<Style x:Key="sales_border" TargetType="Border">
<Setter Property="Background" Value="#0a7d38"/>
<Setter Property="CornerRadius" Value="8"/>
<Setter Property="Margin" Value="5,5,0,0"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Width" Value="Auto"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#00d052"/>
</Trigger>
</Style.Triggers>
</Style>

How can I change background behind border (ListView.ItemTemplete->datatemplete) when I hover or click?

My problem is when I click or hover in ListViewItem which also show the silver background:
enter image description here
this is my code xaml:
<ListView
Margin="0,30,0,0"
Height="600"
ScrollViewer.VerticalScrollBarVisibility="Hidden"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
Name="ListViewFC" ItemsSource="{Binding ListWords, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
SelectedItem="{Binding SelectedItem, Mode=TwoWay}" >
<ListView.ItemTemplate>
<DataTemplate>
<Border
Width="340"
x:Name="Border"
Height="80"
Background="Pink"
CornerRadius="15"
BorderThickness="1"
>
<Grid>
<TextBlock
VerticalAlignment="Center"
x:Name="txtContent"
Foreground="Black"
Text="{Binding Question1,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"
TextWrapping="NoWrap"
Margin="30 0 0 0"
FontSize="15"
/>
</Grid>
</Border>
<DataTemplate.Triggers>
<DataTrigger
Binding="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type ListViewItem}}, Path=IsSelected}" Value="True">
<Setter TargetName="Border" Property="Background" Value="White" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I want that When I hover or click It don't show the silver background.
pls, help me .Thanks.
Add this inside your ListView:
<ListView.Resources>
<Style BasedOn="{StaticResource TextBlockStyle}" TargetType="{x:Type TextBlock}" />
<Style BasedOn="{StaticResource ListViewItemStyle}" TargetType="{x:Type ListViewItem}" />
</ListView.Resources>
Then add this outside of your ListView (this displays a background of gold on hover):
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Gold" />
</Trigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
The default ControlTemplate of the ListView contains a Border with Padding of 2X. Hence you have to change its template something like this
<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>

Change listbox item style when selected in WPF

I'm not entirely sure what I'm doing incorrect but it appears that my style trigger is not being recognized. I want to change the color of the Stroke when the listbox item is selected.
<ListBox ItemsSource="{Binding CityList}" DisplayMemberPath="Name" SelectionMode="Extended"
VirtualizingPanel.IsVirtualizing="true"
VirtualizingPanel.VirtualizationMode="Recycling"
Background="Brown">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Canvas.Left" Value="{Binding Longitude, Converter={StaticResource longValueConverter}, ConverterParameter={StaticResource mapWidth}}"/>
<Setter Property="Canvas.Top" Value="{Binding Latitude, Converter={StaticResource latValueConverter}, ConverterParameter={StaticResource mapHeight}}"/>
<Setter Property="BorderThickness" Value="3" />
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Grid>
<Ellipse x:Name="indicator"
Fill="#FF000000"
Height="10"
Width="10"
Stroke="Transparent"
StrokeThickness="2"/>
</Grid>
</DataTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="indicator" Property="Stroke" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<Canvas IsItemsHost="True"
Width="{StaticResource mapWidth}"
Height="{StaticResource mapHeight}"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
You can't use TargetName in a Style Setter.
Instead of setting the ContentTemplate property, you may set the Template property and add the Trigger to the ControlTemplate.Triggers collection:
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Grid>
<Ellipse x:Name="indicator"
Fill="#FF000000"
Height="10"
Width="10"
Stroke="Transparent"
StrokeThickness="2"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="indicator" Property="Stroke" Value="Red"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
You may also add a ContentPresenter to the Grid in the ControlTemplate, which would display the elements of the ItemTemplate (if you later decide to declare one).

WPF ItemsControl and Togglebuttons weird behaviour

I've been working on a WPF application but encountered some weird behaviour when using ItemsControl to display a list of togglebuttons with binding. It works just fine when it is displaying a collection of 1 element, but when I have two elements it behaves very strange. It will not show the image of both togglebuttons at once if they are in the same state (i.e. toggled on).
The relevant XAML. I have checked that the property behind is updated correctly, but let me know if there is any code that is needed.
<ItemsControl x:Name="ServiceItemsControl" Grid.Row="0" ItemsSource="{Binding DraftMessage.Services}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ToggleButton IsChecked="{Binding Path=Selected}">
<ToggleButton.Style>
<Style TargetType="ToggleButton">
<Setter Property="Focusable" Value="False"/>
<!--Setter Property="BorderThickness" Value="0"/-->
<Setter Property="Opacity" Value="1"/>
<Setter Property="Content">
<Setter.Value>
<Image Source="{Binding Path=Service.OtherLogo}" Width="25" Height="25"/>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Content">
<Setter.Value>
<Image Source="{Binding Path=Service.Logo}" Width="25" Height="25"/>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
</ToggleButton>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
You need to use a DataTrigger on the Image to change its Source property when the ToggleButton.IsChecked value is changed instead. Try this:
<DataTemplate>
<ToggleButton IsChecked="{Binding Path=IsSelected}">
<Image Width="25" Height="25">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="{Binding Service.OtherLogo}" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked,
RelativeSource={RelativeSource AncestorType={x:Type
ToggleButton}}}" Value="True">
<Setter Property="Source" Value="{Binding Service.Logo}" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
<ToggleButton.Style>
<Style TargetType="ToggleButton">
<Setter Property="Focusable" Value="False"/>
<!--Setter Property="BorderThickness" Value="0"/-->
<Setter Property="Opacity" Value="1"/>
</Style>
</ToggleButton.Style>
</ToggleButton>
</DataTemplate>

Categories