How to give Expander Full Width of Column in a Grid - c#

I have an Expander and it should receive the full width of the column but I cant get it to work.
I tried to add the Horizontal(Content)Alignment = stretch on the TextBlock and on the Expander itself even on the Grid, but it is not working.
What I need is that the Expander takes about 90% of the width and the rest are assigned to the buttons as in the following example:
I want to display e.g. a name and when you press on it, expands down and shows additional information
and if the buttons are pressed, then the commands behind the buttons will be executed (no commands are binded in the example).
<ListView
ItemsSource="{Binding log}"
SelectionMode="Multiple"
Style="{StaticResource ListViewStyle}">
<ListView.ItemTemplate>
<DataTemplate>
<Border BorderThickness="0,0,0,1" BorderBrush="Gray">
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100*" />
<ColumnDefinition Width="5*" />
<ColumnDefinition Width="5*" />
</Grid.ColumnDefinitions>
<Expander Grid.Column="0"
HorizontalAlignment="Stretch"
IsExpanded="{Binding Mode=TwoWay, Path=IsSelected, RelativeSource={RelativeSource AncestorType=ListBoxItem, Mode=FindAncestor}}"
Style="{StaticResource ExpanderStyle}">
<Expander.Header>
<TextBlock Text="{Binding Name}" Foreground="White"
HorizontalAlignment="Stretch" />
</Expander.Header>
<TextBlock
VerticalAlignment="Center"
FontSize="16"
Foreground="White"
Text="{Binding Description}" />
</Expander>
<Button Grid.Column="1"
Style="{StaticResource IconButton}">
<Button.Background>
<ImageBrush ImageSource="../icons/edit.png"
Stretch="None" />
</Button.Background>
</Button>
<dialogButton:ConfirmButton Grid.Column="2"
Question="{x:Static language:Strings.confirm}"
Style="{DynamicResource IconButton}"
Margin="0,0,10,0">
<dialogButton:ConfirmButton.Background>
<ImageBrush ImageSource="../icons/delete.png"
Stretch="None" />
</dialogButton:ConfirmButton.Background>
</dialogButton:ConfirmButton>
</Grid>
</Border>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Styles
<Style x:Key="ExpanderDownHeaderStyle" TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border Padding="{TemplateBinding Padding}">
<Grid Background="Transparent" SnapsToDevicePixels="False">
<ContentPresenter HorizontalAlignment="Stretch" Margin="0" RecognizesAccessKey="True" SnapsToDevicePixels="True" VerticalAlignment="Center"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ExpanderStyle" TargetType="{x:Type Expander}">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Expander}">
<Border Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="3" SnapsToDevicePixels="true">
<DockPanel>
<ToggleButton x:Name="HeaderSite" ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" ContentTemplateSelector="{TemplateBinding HeaderTemplateSelector}" DockPanel.Dock="Top" FontStyle="{TemplateBinding FontStyle}" FontStretch="{TemplateBinding FontStretch}" FontWeight="{TemplateBinding FontWeight}" FocusVisualStyle="{StaticResource ExpanderHeaderFocusVisual}" FontFamily="{TemplateBinding FontFamily}" Foreground="{TemplateBinding Foreground}" FontSize="{TemplateBinding FontSize}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" IsChecked="{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" MinHeight="0" MinWidth="0" Margin="1" Padding="{TemplateBinding Padding}" Style="{StaticResource ExpanderDownHeaderStyle}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
<ContentPresenter x:Name="ExpandSite" DockPanel.Dock="Bottom" Focusable="false" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Visibility="Collapsed"/>
</DockPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="true">
<Setter Property="Visibility" TargetName="ExpandSite" Value="Visible"/>
</Trigger>
<Trigger Property="ExpandDirection" Value="Down">
<Setter Property="DockPanel.Dock" TargetName="ExpandSite" Value="Bottom"/>
<Setter Property="DockPanel.Dock" TargetName="HeaderSite" Value="Top"/>
<Setter Property="Background" Value="Transparent" />
<Setter Property="Style" TargetName="HeaderSite" Value="{StaticResource ExpanderDownHeaderStyle}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I also tried things from the following Threads
wpf - Header of Expander fit contents width?
Problem here is that the Buttons are pushed out of the view
Best Solution would be if the Expander just takes the width of the column so that I can adjust the widths of the element by the Grid.ColumnDefinition.

The issue is that the item container, a ListViewItem does not stretch its content by default. You have to create an item container style in order to set the HorizontalContentAlignment to Stretch.
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.ItemContainerStyle>

Related

WPF How to change the IsSubmenuOpen color without disabling MenuItem dialogue box

I am trying to copy the IntelliJ Titlebar Menu in Windows as a learning exercise.
The default color changes of a WPF MenuItem seem to be:
Low Opacity blue background when "IsMouseOver" and not "IsSubmenuOpen"
Low Opacity blue background when "IsSubmenuOpen"
I would like to change this behavior to this (which can be observed in IntelliJ):
No color change when "IsMouseOver" and not "IsSubmenuOpen"
Dark blue background when "IsSubmenuOpen"
White foreground when "IsSubmenuOpen"
I have found code in this answer which is capable of doing this, but it also seems to disable the ability of the MenuItem to open its drop down box to reveal its children.
<Style x:Key="TitleBarMenuItem" TargetType="{x:Type MenuItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter Content="{TemplateBinding Header}" Margin="35 5 10 5" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSubmenuOpen" Value="True">
<Setter Property="Foreground" Value="White"/>
<Setter Property="Background" Value="#2675BF"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
How can I get these color changes without disabling the MenuItem functionality?
The problem you have there is that there's no popup for the sub menu. You're missing something like:
<Popup x:Name="Popup"
Placement="Right"
HorizontalOffset="-4"
IsOpen="{TemplateBinding IsSubmenuOpen}"
AllowsTransparency="True"
Focusable="False"
PopupAnimation="Fade">
<Border x:Name="SubmenuBorder"
SnapsToDevicePixels="True"
Background="{DynamicResource MenuPopupBrush}"
BorderThickness="1">
<Border.BorderBrush>
<SolidColorBrush Color="{DynamicResource BorderMediumColor}" />
</Border.BorderBrush>
<ScrollViewer CanContentScroll="True"
Style="{StaticResource MenuScrollViewer}">
<StackPanel IsItemsHost="True"
KeyboardNavigation.DirectionalNavigation="Cycle" />
</ScrollViewer>
</Border>
</Popup>
Note that "IsItemsHost".
If you take a look at the templates for menu and menuitem you will notice it is very complicated stuff.
The approach I prefer is to work with content. You can put pretty much anything you like in a menuitem header.
One app I have does so with hard coded xaml. That's easier to understand than binding anyhow. Part of it looks like:
<MenuItem Header="_Layers" Style="{x:Null}">
<MenuItem>
<MenuItem.Header>
<CheckBox IsChecked="{Binding ShowBackground, Mode=TwoWay}">
_Background
</CheckBox>
</MenuItem.Header>
<MenuItem>
<MenuItem.Header>
<StackPanel Width="160">
<TextBlock Text="Opacity" />
<Slider Value="{Binding BackgroundOpacity, Mode=TwoWay}" />
</StackPanel>
</MenuItem.Header>
</MenuItem>
</MenuItem>
<MenuItem>
<MenuItem.Header>
<CheckBox IsChecked="{Binding AppSettings.ShowElevationMap, Mode=TwoWay}">
_Elevation Map
</CheckBox>
</MenuItem.Header>
<MenuItem>
<MenuItem.Header>
<StackPanel Width="160">
<TextBlock Text="Opacity" />
<Slider
Value="{Binding AppSettings.ElevationOpacity, Mode=TwoWay}" />
</StackPanel>
</MenuItem.Header>
Layers is a top level menu item. These are templated different to their children. ( Did I mention menus are complicated ).
I offset the content so I don't need to worry about the icon column in the grid.
The styling I have might be useful to get you started.
You said this was a learning exercise so just doing it for you is presumably not exactly going to exercise your learning.
<ItemsPanelTemplate x:Key="MenuItemPanelTemplate">
<StackPanel Margin="-20,0,0,0" Background="White"/>
</ItemsPanelTemplate>
<Style TargetType="MenuItem" x:Key="MenuItemNoIcon">
<Setter Property="ItemsPanel" Value="{StaticResource MenuItemPanelTemplate}"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
</Style>
<Style TargetType="{x:Type MenuItem}" x:Key="{x:Type MenuItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
<Border x:Name="templateRoot" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{x:Static SystemColors.MenuBarBrush}"
SnapsToDevicePixels="True">
<Grid Margin="-1, 2, 0, 2">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="MenuItemIconColumnGroup" Width="0"/>
<ColumnDefinition Width="0"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="0"/>
<ColumnDefinition SharedSizeGroup="MenuItemIGTColumnGroup" Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ContentPresenter ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}"
Grid.Column="2" ContentStringFormat="{TemplateBinding HeaderStringFormat}" ContentSource="Header" HorizontalAlignment="Left" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center"/>
<TextBlock Grid.Column="4" Margin="{TemplateBinding Padding}" Opacity="0.7" Text="{TemplateBinding InputGestureText}" VerticalAlignment="Center"/>
<Path x:Name="RightArrow" Grid.Column="5" Width="10" Data="M0,0L4,3.5 0,7z" Fill="#FF212121" Margin="8,0,2,0" VerticalAlignment="Center"/>
<Popup x:Name="PART_Popup" AllowsTransparency="True" Focusable="False" HorizontalOffset="-2"
IsOpen="{Binding IsSubmenuOpen, RelativeSource={RelativeSource TemplatedParent}}"
PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}" Placement="Right" VerticalOffset="-3">
<Border x:Name="SubMenuBorder" BorderBrush="#FF999999" BorderThickness="1" Background="#FFF0F0F0" Padding="2">
<ScrollViewer x:Name="SubMenuScrollViewer" Style="{DynamicResource {ComponentResourceKey ResourceId=MenuScrollViewer, TypeInTargetAssembly={x:Type FrameworkElement}}}">
<Grid RenderOptions.ClearTypeHint="Enabled">
<ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Cycle"
Grid.IsSharedSizeScope="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" KeyboardNavigation.TabNavigation="Cycle"/>
</Grid>
</ScrollViewer>
</Border>
</Popup>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSuspendingPopupAnimation" Value="True">
<Setter Property="PopupAnimation" TargetName="PART_Popup" Value="None"/>
</Trigger>
<Trigger Property="IsHighlighted" Value="True">
<Setter Property="Background" TargetName="templateRoot" Value="Transparent"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="#FF26A0DA"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="TextElement.Foreground" TargetName="templateRoot" Value="#FF707070"/>
<Setter Property="Fill" TargetName="RightArrow" Value="#FF707070"/>
</Trigger>
<DataTrigger Binding="{Binding Items.Count, RelativeSource={RelativeSource Self}}" Value="0">
<Setter Property="Visibility" TargetName="RightArrow" Value="Collapsed"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

How to access the custom control in window 'non-client' area in WPF?

I want to implement the custom window as follow:
When use this window style to custom the window,I don't know how to access the 'CheckBox'(the double arrows in circle) by its name in window's 'non-client' area.
Please give some advice?
WPF Window Overview.
<Style x:Key="MetroWindowStyle" TargetType="{x:Type Window}">
<!--<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/>-->
<!--<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>-->
<Setter Property="Background" Value="Transparent"></Setter>
<Setter Property="WindowStyle" Value="None" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<Grid>
<Border x:Name="MainBorder" BorderThickness="0">
<Border.Background>
<ImageBrush ImageSource="Resources/default_background.jpg" Opacity="0.9"/>
</Border.Background>
<DockPanel LastChildFill="True">
<Border x:Name="PART_TITLEBAR"
Margin="0,0,0,0" Height="40" DockPanel.Dock="Top"
Background="Transparent" MouseLeftButtonDown="PART_TITLEBAR_MouseLeftButtonDown">
<DockPanel LastChildFill="False">
<TextBlock Margin="4,0,0,4" VerticalAlignment="Center"
Foreground="White" TextWrapping="NoWrap"
Text="{TemplateBinding Title}" FontSize="16" />
<Button x:Name="PART_CLOSE" DockPanel.Dock="Right"
VerticalAlignment="Center" Margin="5"
Height="20" Width="20"
Style="{DynamicResource MetroWindowButtonStyle}"
Click="PART_CLOSE_Click">
<Path Data="F1M54.0573,47.8776L38.1771,31.9974 54.0547,16.1198C55.7604,14.4141 55.7604,11.6511 54.0573,9.94531 52.3516,8.23962 49.5859,8.23962 47.8802,9.94531L32.0026,25.8229 16.1224,9.94531C14.4167,8.23962 11.6511,8.23962 9.94794,9.94531 8.24219,11.6511 8.24219,14.4141 9.94794,16.1198L25.8255,32 9.94794,47.8776C8.24219,49.5834 8.24219,52.3477 9.94794,54.0534 11.6511,55.7572 14.4167,55.7585 16.1224,54.0534L32.0026,38.1745 47.8802,54.0534C49.5859,55.7585 52.3516,55.7572 54.0573,54.0534 55.7604,52.3477 55.763,49.5834 54.0573,47.8776z"
Stretch="Uniform" Fill="#FFAAAAAA" Width="10" Margin="0,0,0,0" ></Path>
</Button>
<Button x:Name="PART_MAXIMIZE_RESTORE"
DockPanel.Dock="Right" Margin="5"
HorizontalAlignment="Center" VerticalAlignment="Center"
Height="20" Width="20" Style="{DynamicResource MetroWindowButtonStyle}"
Click="PART_MAXIMIZE_RESTORE_Click">
<Path Data="M4.3685131,23.127279L4.3685131,47.283243 47.117023,47.283243 47.117023,23.127279z M0,10.684L53.755001,10.684 53.755001,51.668001 0,51.668001z M8.5679998,0L58.668022,0 64,0 64,5.6864691 64,45.317999 58.668022,45.317999 58.668022,5.6864691 8.5679998,5.6864691z"
Stretch="Uniform" Fill="#FFAAAAAA" Width="10" Margin="0,0,0,0" ></Path>
</Button>
<Button x:Name="PART_MINIMIZE"
HorizontalAlignment="Center"
VerticalAlignment="Center" Margin="5"
DockPanel.Dock="Right"
Height="20" Width="20" Style="{DynamicResource MetroWindowButtonStyle}"
Click="PART_MINIMIZE_Click" VerticalContentAlignment="Bottom">
<Button.Content>
<Path Data="M0,20L53.333,20 53.333,8.888 0,8.888z"
Stretch="Uniform" Fill="#FFAAAAAA" Width="10" Margin="0,0,0,5"></Path>
</Button.Content>
</Button>
<CheckBox Template="{StaticResource ResourceKey=collapsCheckBox}" x:Name="MyCheckBox"
Height="30" Width="30"
Foreground="White"
VerticalContentAlignment="Bottom"
DockPanel.Dock="Right" Margin="3 6 3 10"
Click="ButtonBase_OnClick"/>
</DockPanel>
</Border>
<AdornerDecorator DockPanel.Dock="Bottom">
<ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
ContentStringFormat="{TemplateBinding ContentStringFormat}"/>
</AdornerDecorator>
</DockPanel>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="ResizeMode" Value="CanResizeWithGrip">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
<Grid>
<AdornerDecorator>
<ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}"/>
</AdornerDecorator>
<ResizeGrip x:Name="WindowResizeGrip" HorizontalAlignment="Right" IsTabStop="False" Visibility="Collapsed" VerticalAlignment="Bottom"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="ResizeMode" Value="CanResizeWithGrip"/>
<Condition Property="WindowState" Value="Normal"/>
</MultiTrigger.Conditions>
<Setter Property="Visibility" TargetName="WindowResizeGrip" Value="Visible"/>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="MetroWindowButtonStyle" TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle">
<Setter.Value>
<Style>
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2" SnapsToDevicePixels="True" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
<Setter Property="Background" Value="{x:Null}"/>
<Setter Property="BorderBrush" Value="#FF707070"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsDefaulted" Value="True">
<Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" TargetName="border" Value="#FFBEE6FD"/>
<Setter Property="BorderBrush" TargetName="border" Value="#FF3C7FB1"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" TargetName="border" Value="#FFC4E5F6"/>
<Setter Property="BorderBrush" TargetName="border" Value="#FF2C628B"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" TargetName="border" Value="#FFF4F4F4"/>
<Setter Property="BorderBrush" TargetName="border" Value="#FFADB2B5"/>
<Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="#FF838383"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Add command binding in checkbox in your template something like:
Template="{StaticResource ResourceKey=collapsCheckBox}" x:Name="MyCheckBox" Height="30" Width="30"
Foreground="White"
VerticalContentAlignment="Bottom"
DockPanel.Dock="Right" Margin="3 6 3 10"
Command="myapp:YourCommandClasd.GetCommandInstance" >
And declare in xaml:
<CommandBinding
Command="myapp:YourCommandClass.GetCommandInstance" Executed="To_Be_Executed" />
</Window.CommandBindings>
You can declare "To_Be_Executed" method in xaml.cs file which will be fired.
myapp should be declared as namespace in xaml code.
YourCommandClass.GetCommandInstance : can be a property which returns a RoutedUICommand object.
Sorry for the code ,I write it on phone.

Removing outer border of toggle button wpf

So I have looked through numerous questions where people want to mess with borders of their buttons. I am using a toggle button (WPF) and it seems like there is an 'inner' border and an 'outer' border. I can manage to change the inner boarder to red, but I have no clue how to change the color of the outer border, or even get rid of it. I have gotten rid of the chrome button or whatever that comes with the aero theme, but I still cannot change this border. This is the picture of what I am getting for toggle buttons:
As you can see there is white in the borders. Here is my code for that style:
<Style x:Key="Style1" TargetType="{x:Type ToggleButton}">
<Setter Property="Background" Value="Black"/>
<Setter Property="BorderBrush" Value="Red"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Button BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true" Foreground="White">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Button>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocused" Value="true">
</Trigger>
<Trigger Property="IsChecked" Value="true">
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#ADADAD"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I am using it like this:
<ListBox SelectionMode="Single" Name="touchPanel" Grid.Row="2" Grid.Column="3" Width="Auto" Height="Auto" VerticalAlignment="Top" Background="Black" BorderThickness="0">
<RadioButton Width="60" Height="60" Name="mouseTouchSelection" IsChecked="True" Content="Mouse" Style="{DynamicResource RadioButtonStyle1}" />
<RadioButton Width="60" Height="60" Name="panTouchSelection" BorderThickness="0" Content="Pan" Style="{DynamicResource RadioButtonStyle1}" />
<RadioButton Width="60" Height="60" Name="rotateTouchSelection" Content="Rotate" Style="{DynamicResource RadioButtonStyle1}"/>
<RadioButton Width="60" Height="60" Name="zoomBoxTouchSelection" Content="Box Zoom" Style="{DynamicResource RadioButtonStyle1}" />
</ListBox>
But what I would like the buttons to look like is:
I achieved the above buttons by just overriding the default button style, but I can't seem to do it with the Toggle Button. I tried overriding Radio Button also, and I had the same problem. What am I missing? Can I somehow use the Button style instead of the toggle button style? I am just starting to learn Styles, so don't be to harsh! Appreciate all input though!
The Button in your controltemplate is creating the extra borders. If you replace Button with a Border you can style the togglebutton borders. Is there a reason you're using a Button? You can use triggers to provide the button behavior if needed. See below:
<Style x:Key="Style1" TargetType="{x:Type ToggleButton}">
<Setter Property="Background" Value="Black"/>
<Setter Property="BorderBrush" Value="Red"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border Name="Border" BorderThickness="1" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true" >
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="ToggleButton.IsMouseOver" Value="true">
<Setter TargetName="Border" Property="Background" Value="{StaticResource DarkBrush}" />
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="Border" Property="Background" Value="{StaticResource PressedBrush}"/>
</Trigger>
<Trigger Property="IsChecked" Value="true">
<Setter TargetName="Border" Property="Background" Value="{StaticResource CheckedBrush}" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#ADADAD"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I have only tested it with Buttons, RadioButtons, and ToggleButtons, but the problem arises when trying to nest buttons withing a listbox. So I switched the code from:
<ListBox SelectionMode="Single" Name="touchPanel" Grid.Row="2" Grid.Column="3" Width="Auto" Height="Auto" VerticalAlignment="Top" Background="Black" BorderThickness="0">
<RadioButton Width="60" Height="60" Name="mouseTouchSelection" IsChecked="True" Content="Mouse" Style="{DynamicResource RadioButtonStyle1}" />
<RadioButton Width="60" Height="60" Name="panTouchSelection" BorderThickness="0" Content="Pan" Style="{DynamicResource RadioButtonStyle1}" />
<RadioButton Width="60" Height="60" Name="rotateTouchSelection" Content="Rotate" Style="{DynamicResource RadioButtonStyle1}"/>
<RadioButton Width="60" Height="60" Name="zoomBoxTouchSelection" Content="Box Zoom" Style="{DynamicResource RadioButtonStyle1}" />
</ListBox>
to:
<StackPanel Grid.Column="3" Grid.Row="2">
<RadioButton Width="60" Height="60" Name="mouseTouchSelection" IsChecked="True" Content="Mouse" Style="{DynamicResource RadioButtonStyle1}" />
<RadioButton Width="60" Height="60" Name="panTouchSelection" BorderThickness="0" Content="Pan" Style="{DynamicResource RadioButtonStyle1}" />
<RadioButton Width="60" Height="60" Name="rotateTouchSelection" Content="Rotate" Style="{DynamicResource RadioButtonStyle1}"/>
<RadioButton Width="60" Height="60" Name="zoomBoxTouchSelection" Content="Box Zoom" Style="{DynamicResource RadioButtonStyle1}" />
</StackPanel>
and I got the visual results I wanted (we will see if they work properly).

wpf - can't display TreeView items

I have the following code which supposed to display a TreeView (the original code is more complicated, thus the complex control hirerchy):
<TreeView ItemsSource="{Binding TreeRoot}"
HorizontalAlignment="Left">
<TreeView.Resources>
<DataTemplate x:Key="CTemplate">
<Border >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<ToggleButton
Grid.Column="1"
x:Name="Expander"
HorizontalAlignment="Right"
ClickMode="Press"/>
<TextBlock Text="{Binding Name}"
Grid.Column="0" />
</Grid>
</Border>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=HasItems, RelativeSource={RelativeSource AncestorType={x:Type TreeViewItem}}}" Value="False">
<Setter TargetName="Expander" Property="Visibility" Value="Hidden"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
<Style TargetType="{x:Type TreeViewItem}" x:Key="aaa">
<Setter Property="ItemsSource" Value="{Binding Children}"/>
<Setter Property="IsExpanded" Value="{Binding Path=IsExpanded,Mode=TwoWay}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TreeViewItem}">
<StackPanel>
<Border Name="Bd"
Background="{TemplateBinding Background}">
</Border>
<ItemsPresenter x:Name="ItemsP" />
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="false">
<Setter TargetName="ItemsP"
Property="Visibility"
Value="Collapsed"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type TreeView}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TreeView}">
<Border BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<DockPanel>
<ItemsPresenter/>
</DockPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemContainerStyle" Value="{StaticResource aaa}" />
<Setter Property="ItemTemplate" Value="{CTemplate}" />
</Style>
</TreeView.Resources>
</TreeView>
Could you please help me figure out why my items are not displayed?
(The page appears empty)
Thanks,
Li
You don't have anything showing the Header of the TreeViewItem:
<Style TargetType="{x:Type TreeViewItem}" x:Key="aaa">
...
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TreeViewItem}">
<StackPanel>
<Border Name="Bd" Background="{TemplateBinding Background}">
<ContentPresenter x:Name="PART_Header"
ContentSource="Header"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
<ItemsPresenter x:Name="ItemsP" />
</StackPanel>
...
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Above I added the ContentPresenter.

WPF - Implement ItemTemplate for an ItemsPresenter?

I've been working on a SplitButton control for WPF and its basically done, but I'm trying to go through all the possible properties that can be set on it and make sure they are actually implemented. I mostly have only two properties left to implement which is the ItemTemplate and ItemTemplateSelector (and AlternationCount, okay so 3 properties).
I was able to get the HeaderTemplate and HeaderTemplateSelector working by binding the ContentTemplate and ContentTemplateSelector to them on a ContentPresenter. This is for the button part of the control though. For the drop-drop part of the control I'm using a Popup, Border, and ItemsPresenter. The problem is that I can't figure how to set the ItemTemplate and ItemTemplateSelector properties for the ItemsPresenter.
Any ideas?
Update:
The full source code for the SplitButton is now available at:
http://anothersplitbutton.codeplex.com/
Here's the Luna.NormalColor.xaml file:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:WpfSplitButton="clr-namespace:WpfSplitButton"
xmlns:mwt="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Luna"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- SplitButtonHeader Style -->
<Style x:Key="{x:Type WpfSplitButton:SplitButtonHeader}"
TargetType="{x:Type WpfSplitButton:SplitButtonHeader}">
<Style.Resources>
<Style x:Key="ButtonFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2"
StrokeThickness="1"
Stroke="Black"
StrokeDashArray="1 2"
SnapsToDevicePixels="True" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Style.Resources>
<Style.Setters>
<Setter Property="FocusVisualStyle"
Value="{StaticResource ButtonFocusVisual}" />
<Setter Property="HorizontalContentAlignment"
Value="Center" />
<Setter Property="PastLeftDetection"
Value="True" />
<Setter Property="VerticalContentAlignment"
Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<mwt:ButtonChrome x:Name="Chrome"
BorderBrush="{TemplateBinding Border.BorderBrush}"
RenderDefaulted="{TemplateBinding Button.IsDefaulted}"
RenderMouseOver="{TemplateBinding UIElement.IsMouseOver}"
RenderPressed="{TemplateBinding ButtonBase.IsPressed}"
SnapsToDevicePixels="True">
<Grid Background="{TemplateBinding ButtonBase.Background}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ContentPresenter Content="{TemplateBinding ContentControl.Content}"
ContentTemplate="{TemplateBinding ButtonBase.ContentTemplate}"
ContentTemplateSelector="{TemplateBinding ButtonBase.ContentTemplateSelector}"
HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
Margin="{TemplateBinding Control.Padding}"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}" />
<Border x:Name="PART_DropDownInitiator"
Background="Transparent"
BorderBrush="{Binding Path=BorderBrush, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type WpfSplitButton:SplitButtonHeader}}}"
BorderThickness="1,0,0,0"
Grid.Column="1"
HorizontalAlignment="Stretch"
Margin="0,0,0,0"
Padding="4,0,4,0"
VerticalAlignment="Stretch">
<Path Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type WpfSplitButton:SplitButtonHeader}}}"
VerticalAlignment="Center">
<Path.Style>
<Style>
<Setter Property="Path.Fill"
Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}" />
<Style.Triggers>
<Trigger Property="WpfSplitButton:SplitButton.IsMouseOver"
Value="True">
<Setter Property="Path.Fill"
Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" />
</Trigger>
</Style.Triggers>
</Style>
</Path.Style>
<Path.Data>
<PathGeometry>
<PathGeometry.Figures>
<PathFigureCollection>
<PathFigure IsClosed="True"
StartPoint="0,0">
<PathFigure.Segments>
<PathSegmentCollection>
<LineSegment Point="8,0" />
<LineSegment Point="4,5" />
</PathSegmentCollection>
</PathFigure.Segments>
</PathFigure>
</PathFigureCollection>
</PathGeometry.Figures>
</PathGeometry>
</Path.Data>
</Path>
</Border>
</Grid>
</mwt:ButtonChrome>
<ControlTemplate.Triggers>
<Trigger Property="UIElement.IsKeyboardFocused"
Value="True">
<Setter TargetName="Chrome"
Property="mwt:ButtonChrome.RenderDefaulted"
Value="True" />
</Trigger>
<Trigger Property="ToggleButton.IsChecked"
Value="True">
<Setter TargetName="Chrome"
Property="mwt:ButtonChrome.RenderPressed"
Value="True" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
<!-- SplitButton -->
<Style x:Key="{x:Type WpfSplitButton:SplitButton}"
TargetType="{x:Type WpfSplitButton:SplitButton}">
<Style.Resources>
<LinearGradientBrush x:Key="ButtonNormalBackgroundFill"
EndPoint="0.5,1"
StartPoint="0.5,0">
<LinearGradientBrush.GradientStops>
<GradientStop Color="#FFFFFFFF"
Offset="0" />
<GradientStop Color="#FFF0F0EA"
Offset="0.9" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<SolidColorBrush x:Key="ButtonBorder"
Color="#FF003C74" />
</Style.Resources>
<Setter Property="AutoUpdateHeader"
Value="True" />
<Setter Property="Background"
Value="{StaticResource ButtonNormalBackgroundFill}" />
<Setter Property="BorderBrush"
Value="{StaticResource ButtonBorder}" />
<Setter Property="BorderThickness"
Value="1" />
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
<Setter Property="HorizontalContentAlignment"
Value="Center" />
<Setter Property="Padding"
Value="4,4,4,4" />
<Setter Property="VerticalContentAlignment"
Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type WpfSplitButton:SplitButton}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<WpfSplitButton:SplitButtonHeader x:Name="PART_Header"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Content="{TemplateBinding Header}"
ContentTemplate="{TemplateBinding HeaderTemplate}"
ContentTemplateSelector="{TemplateBinding HeaderTemplateSelector}"
Cursor="{TemplateBinding Cursor}"
Foreground="{TemplateBinding Foreground}"
Grid.Row="0"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
Padding="{TemplateBinding Padding}"
VerticalAlignment="Stretch"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" />
<Popup x:Name="PART_Popup"
AllowsTransparency="True"
Grid.Row="1"
IsOpen="{Binding Path=IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
MinWidth="{Binding Path=ActualWidth, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type WpfSplitButton:SplitButton}}}"
Placement="Bottom"
PlacementTarget="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type WpfSplitButton:SplitButton}}}"
PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}"
StaysOpen="False">
<mwt:SystemDropShadowChrome Color="Transparent">
<Border x:Name="DropDownBorder"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Border>
</mwt:SystemDropShadowChrome>
</Popup>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsEnabled"
Value="False">
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
Update 2
I tried switching out the ItemsPresenter with a ItemsControl, but I can't seem to get the ItemTemplate property to do anything. Here's the changed section of code:
<ItemsControl DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type WpfSplitButton:SplitButton}}}"
AlternationCount="{TemplateBinding AlternationCount}"
IsTabStop="{TemplateBinding IsTabStop}"
IsTextSearchEnabled="{TemplateBinding IsTextSearchEnabled}"
ItemContainerStyle="{TemplateBinding ItemContainerStyle}"
ItemContainerStyleSelector="{TemplateBinding ItemContainerStyleSelector}"
ItemBindingGroup="{TemplateBinding ItemBindingGroup}"
ItemsPanel="{TemplateBinding ItemsPanel}"
ItemsSource="{Binding Path=Items}"
ItemStringFormat="{TemplateBinding ItemStringFormat}"
ItemTemplateSelector="{TemplateBinding ItemTemplateSelector}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="HELLO" />
</DataTemplate>
</ItemsControl.ItemTemplate>
Have you considered using an ItemsControl instead of the ItemsPresenter? This would give you the ItemTemplate and ItemTemplateSelector property as well as the AlternationCount property.
Update:
I got it to work just fine using the ItemsControl like you posted above using the following line to bind to the ItemsTemplate Property in your Classic.xaml file:
ItemTemplate="{TemplateBinding ItemsTemplate, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type WpfSplitButton:SplitButton}}}"
Then in your MainWindow's Resources i just added the following template:
<DataTemplate x:Key="Test">
<MenuItem Header="{Binding}" />
</DataTemplate>
Then i set the ItemTemplate Property on the SplitButton:
ItemTemplate="{StaticResource Test}"
So just hook up your ItemSource and you are good to go... i just used a simple string[] in the code behind...
Hope this helps!

Categories