I have a usercontrol that hosts some content inside a scrollviewer, when the window is resized the vertical scroll is set up to show automatically, this all works fine.
I want a trigger on the ComputedVerticalScrollBarVisibility property, that changes the Padding of the actual usercontrol. This is my code right now, why is it not working?
<UserControl x:Class="Something.CustomizableView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:view="clr-namespace:Something"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Style>
<Style TargetType="{x:Type Control}">
<Setter Property="Padding" Value="20" />
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=TheScroll,Path=ComputedVerticalScrollBarVisibility}" Value="Visible">
<Setter Property="Padding" Value="0"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</UserControl.Style>
Here is my ScrollViewer + ItemsControl
<ScrollViewer x:Name="TheScroll" VerticalScrollBarVisibility="Auto" Grid.Row="1">
<ItemsControl
ItemsSource="{Binding ContentModules}"
ItemTemplateSelector="{StaticResource ContentTemplateSelector}"
Background="White">
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="FrameworkElement.Margin" Value="0 0 0 50" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</ScrollViewer>
Use this style for the scroll viewer, and remove the style from the user control:
<Thickness x:Key="NoScrollPaddingThickness"
Left="20"
Top="20"
Bottom="20"
Right="{StaticResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}">
</Thickness>
<Thickness x:Key="WithScrollPaddingThickness"
Left="20"
Top="20"
Bottom="20"
Right="0">
</Thickness>
<Style TargetType="{x:Type ScrollViewer}">
<Setter Property="Padding"
Value="{StaticResource NoScrollPaddingThickness}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ScrollViewer}">
<Grid x:Name="Grid"
Background="{TemplateBinding Background}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Rectangle x:Name="Corner"
Grid.Column="1"
Fill="{DynamicResource {x:Static SystemColors.ScrollBarBrushKey}}"
Grid.Row="1" />
<ScrollContentPresenter x:Name="PART_ScrollContentPresenter"
CanContentScroll="{TemplateBinding CanContentScroll}"
CanHorizontallyScroll="False"
CanVerticallyScroll="False"
ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
Grid.Column="0"
Margin="{TemplateBinding Padding}"
Grid.Row="0" />
<ScrollBar x:Name="PART_VerticalScrollBar"
AutomationProperties.AutomationId="VerticalScrollBar"
Cursor="Arrow"
Grid.Column="1"
Maximum="{TemplateBinding ScrollableHeight}"
Minimum="0"
Grid.Row="0"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"
Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}"
ViewportSize="{TemplateBinding ViewportHeight}" />
<ScrollBar x:Name="PART_HorizontalScrollBar"
AutomationProperties.AutomationId="HorizontalScrollBar"
Cursor="Arrow"
Grid.Column="0"
Maximum="{TemplateBinding ScrollableWidth}"
Minimum="0"
Orientation="Horizontal"
Grid.Row="1"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"
Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}"
ViewportSize="{TemplateBinding ViewportWidth}" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="ComputedVerticalScrollBarVisibility"
Value="Visible">
<Setter Property="Padding"
Value="{StaticResource WithScrollPaddingThickness}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsEnabled"
Value="false">
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</Trigger>
</Style.Triggers>
</Style>
EDIT
To make it more compact, we can use the style only - we don't really need a template here:
<Thickness x:Key="NoScrollPaddingThickness"
Left="20"
Top="20"
Bottom="20"
Right="{StaticResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}">
</Thickness>
<Thickness x:Key="WithScrollPaddingThickness"
Left="20"
Top="20"
Bottom="20"
Right="0">
</Thickness>
<Style TargetType="{x:Type ScrollViewer}">
<Setter Property="Padding"
Value="{StaticResource NoScrollPaddingThickness}" />
<Style.Triggers>
<Trigger Property="IsEnabled"
Value="false">
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</Trigger>
<Trigger Property="ComputedVerticalScrollBarVisibility"
Value="Visible">
<Setter Property="Padding"
Value="{StaticResource WithScrollPaddingThickness}" />
</Trigger>
</Style.Triggers>
</Style>
Related
I've got a ComboBox that looks like this:
I don't want the value of ... to change when one of the items is selected.
I've tried a ton of different solutions - various bindings on SelectedIndex, SelectedValue, SelectionChanged, playing with IsEditable, IsReadonly, IsHitTestVisible, making ... an actual item, making it placeholder text, etc, etc, etc.
Every time I select an item, the ... updates with the child value. I want it to stay the same.
How can I prevent the combobox from automatically updating the text on selection, but still have it able to select a choice?
If it helps, here's the custom template for that image:
<ResourceDictionary
x:Class="ComboBoxA"
xmlns:local="clr-namespace:MyTemplates"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ControlTemplate x:Key="ComboBoxA" TargetType="{x:Type ComboBox}">
<Grid>
<ToggleButton
ClickMode="Press"
Focusable="false"
IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
Name="ToggleButton"
>
<ToggleButton.Template>
<ControlTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="36" />
</Grid.ColumnDefinitions>
<Border
x:Name="Border"
Grid.ColumnSpan="2"
CornerRadius="0"
BorderThickness="1" />
<Border
Grid.Column="0"
CornerRadius="0"
Margin="1"
Background="Transparent"
BorderThickness="0"
/>
<Path
x:Name="Arrow"
Grid.Column="1"
Fill="#707070"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Visibility="Collapsed"
Data="M0,0 L8,0 L4,4 z"
/>
<TextBlock
Margin="4,6"
Foreground="#282828"
Grid.Column="0"
Text="{Binding Path=(local:ComboBoxAHelper.Placeholder), RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}"
/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="Arrow" Property="Visibility" Value="Visible"/>
<Setter TargetName="Border" Property="BorderBrush" Value="#d9d9d9"/>
</Trigger>
<Trigger Property="ToggleButton.IsChecked" Value="true">
<Setter TargetName="Arrow" Property="Visibility" Value="Visible"/>
<Setter TargetName="Border" Property="BorderBrush" Value="#d9d9d9"/>
</Trigger>
<DataTrigger Binding="{Binding Path=(local:ComboBoxAHelper.ShowBorders), RelativeSource={RelativeSource TemplatedParent}}" Value="True">
<Setter TargetName="Arrow" Property="Visibility" Value="Visible"/>
<Setter TargetName="Border" Property="BorderBrush" Value="#d9d9d9"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</ToggleButton.Template>
</ToggleButton>
<ContentPresenter
Content="{TemplateBinding SelectionBoxItem}"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
HorizontalAlignment="Left"
IsHitTestVisible="False"
Margin="3,3,23,3"
Name="ContentSite"
VerticalAlignment="Center"
/>
<Popup
AllowsTransparency="True"
Focusable="False"
IsOpen="{TemplateBinding IsDropDownOpen}"
Name="Popup"
PopupAnimation="Slide"
>
<Grid Name="DropDown"
MaxHeight="{TemplateBinding MaxDropDownHeight}"
MinWidth="{TemplateBinding ActualWidth}"
SnapsToDevicePixels="True"
>
<Border
Background="White"
BorderBrush="#d9d9d9"
BorderThickness="1"
x:Name="DropDownBorder"
/>
<ScrollViewer Margin="4,6" SnapsToDevicePixels="True">
<StackPanel
IsItemsHost="True"
KeyboardNavigation.DirectionalNavigation="Contained"
/>
</ScrollViewer>
</Grid>
<Popup.Style>
<Style TargetType="Popup">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=(local:ComboBoxAHelper.RightAlignPopup), RelativeSource={RelativeSource TemplatedParent}}" Value="True">
<Setter Property="Placement" Value="Left" />
<Setter Property="VerticalOffset" Value="{Binding ActualHeight, RelativeSource={RelativeSource TemplatedParent}}" />
<Setter Property="HorizontalOffset" Value="{Binding ActualWidth, RelativeSource={RelativeSource TemplatedParent}}" />
</DataTrigger>
</Style.Triggers>
</Style>
</Popup.Style>
</Popup>
</Grid>
</ControlTemplate>
<Style x:Key="ComboBoxAItem" TargetType="{x:Type TextBlock}">
<Setter Property="FontSize" Value="12" />
<Setter Property="Foreground" Value="#282828" />
<Setter Property="Padding" Value="4" />
</Style>
</ResourceDictionary>
...and its corresponding XAML:
<ComboBox
templates:ComboBoxAHelper.Placeholder="..."
templates:ComboBoxAHelper.RightAlignPopup="True"
templates:ComboBoxAHelper.ShowBorders="True"
HorizontalAlignment="Right"
IsReadOnly="True"
IsEditable="False"
SelectedValue="x:Null"
Template="{StaticResource ComboBoxA}"
>
<ComboBoxItem>
<TextBlock Style="{StaticResource ComboBoxAItem}">Close</TextBlock>
</ComboBoxItem>
<ComboBoxItem>
<TextBlock Style="{StaticResource ComboBoxAItem}">Delete</TextBlock>
</ComboBoxItem>
</ComboBox>
The trick was to remove
Content="{TemplateBinding SelectionBoxItem}"
from the template (both in general and also the code posted in the question).
Thanks to #shadow32's answer to my separate question https://stackoverflow.com/a/50805408/385273.
I have a dynamic combobox items added to it. When i select item, it displays properly. but when reloading the control i am assigning selected item to the combobox but it is not displaying.
simpleComboBox.SelectedIndex = simpleComboBox.Items.IndexOf(SelectedItem);
It showing correct index value but values are not displaying.
<Style x:Key="ComboBoxStyle" TargetType="{x:Type ComboBox}">
<Setter Property="Margin" Value="10"/>
<Setter Property="Foreground" Value="{StaticResource ForegroundTextNormalBrush}" />
<Setter Property="FontFamily" Value="{StaticResource TextFontFamily}"/>
<Setter Property="FontSize" Value="{StaticResource FontSize16}"/>
<Setter Property="Background" Value="{StaticResource ControlBackgroundBrush}"/>
<Setter Property="BorderBrush" Value="{StaticResource BorderColorBrush}"/>
<Setter Property="IsEditable" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBox}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="50"/>
</Grid.ColumnDefinitions>
<TextBox Name="PART_EditableTextBox"
Style="{StaticResource ComboBoxTextBoxStyle}"
Height="{TemplateBinding Height}"/>
<ToggleButton Grid.Column="1" Margin="0" Style="{StaticResource ToggleButtonStyle}"
Focusable="False"
IsChecked="{Binding Path=IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
ClickMode="Press">
<TextBlock Grid.Column="1" Style="{StaticResource ToggleButtonTextBlockStyle}"/>
</ToggleButton>
<ContentPresenter Name="ContentSite"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
Content="{TemplateBinding SelectionBoxItem}"
ContentStringFormat="{TemplateBinding SelectionBoxItemStringFormat}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Margin="5,0,0,0"/>
<Popup Name="Popup"
Placement="Bottom"
IsOpen="{TemplateBinding IsDropDownOpen}"
AllowsTransparency="True"
Focusable="False"
PopupAnimation="Fade">
<Grid Name="DropDown"
SnapsToDevicePixels="True"
MinWidth="{TemplateBinding ActualWidth}"
MaxHeight="{TemplateBinding MaxDropDownHeight}">
<Border
x:Name="DropDownBorder"
BorderThickness="3"
CornerRadius="5"
Background="{StaticResource AddControlTextBoxBackgroundBrush}"
BorderBrush="{StaticResource AddControlInnerBorderBrush}"/>
<ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True">
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" />
</ScrollViewer>
</Grid>
</Popup>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate >
<TextBlock Style="{StaticResource SelectedTextBlockStyle}" Text="{Binding}" />
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="ComboBoxItem">
<Setter Property="Foreground" Value="{StaticResource ForegroundTextNormalBrush}" />
<Setter Property="FontFamily" Value="{StaticResource ArialFontFamily}"/>
<Setter Property="FontSize" Value="24"/>
<Setter Property="BorderThickness" Value="0"/>
</Style>
</Setter.Value>
</Setter>
</Style>
Try setting
simpleComboBox.SelectedItem = SelectedItem;
and also set IsSynchronizedWithCurrentItem="True".
This will solve your issue.
I'm currently trying to implement my own stylized ComboBox in WPF. Everything is working fine, except for the scrollviewer. Simply put, the vertical scroll bar does nothing. Here is an image:
As you can see, the vertical scrollbar is scrolled all the way down, but it did not seem to trigger the effect of actually scrolling. I have 12 dummy items in the Combobox. I was reading online that the ScrollViewer style requires three things to work: ScrollContentPresenter, VerticalScrollBar, and HorizontalScrollBar. I have all three declared in my scrollviewer style, which is as follows:
<Style x:Key="VoidwalkerDarkScrollviewer" TargetType="{x:Type ScrollViewer}">
<Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="VerticalContentAlignment" Value="Top" />
<Setter Property="VerticalScrollBarVisibility" Value="Visible" />
<Setter Property="Padding" Value="4" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="BorderBrush">
<Setter.Value>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Offset="0" Color="#FFA3AEB9" />
<GradientStop Offset="0.375" Color="#FF8399A9" />
<GradientStop Offset="0.375" Color="#FF718597" />
<GradientStop Offset="1" Color="#FF617584" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ScrollViewer">
<Border
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="2">
<Grid Background="{TemplateBinding Background}">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ScrollContentPresenter
x:Name="ScrollContentPresenter"
Margin="{TemplateBinding Padding}"
ContentTemplate="{TemplateBinding ContentTemplate}"
Cursor="{TemplateBinding Cursor}" />
<Rectangle
Grid.Row="1"
Grid.Column="1"
Fill="#FFE9EEF4" />
<ScrollBar
x:Name="VerticalScrollBar"
Grid.Row="0"
Grid.Column="1"
Width="18"
Margin="0,-1,-1,-1"
Background="Red"
IsTabStop="False"
Maximum="{TemplateBinding ScrollableHeight}"
Minimum="0"
Orientation="Vertical"
ViewportSize="{TemplateBinding ViewportHeight}"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"
Value="{TemplateBinding VerticalOffset}" />
<ScrollBar
x:Name="HorizontalScrollBar"
Grid.Row="1"
Grid.Column="0"
Height="18"
Margin="-1,0,-1,-1"
IsTabStop="False"
Maximum="{TemplateBinding ScrollableWidth}"
Minimum="0"
Orientation="Horizontal"
ViewportSize="{TemplateBinding ViewportWidth}"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"
Value="{TemplateBinding HorizontalOffset}" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And here is my Combobox style (Omitting extras which are not relevant)
<Style x:Key="VoidwalkerDarkComboBox" TargetType="{x:Type ComboBox}">
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.CanContentScroll" Value="true" />
<Setter Property="MinWidth" Value="120" />
<Setter Property="MinHeight" Value="20" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBox">
<Grid>
<ToggleButton
Name="ToggleButton"
Grid.Column="2"
ClickMode="Press"
Focusable="false"
IsChecked="{Binding Path=IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
Template="{StaticResource ComboBoxToggleButton}" />
<ContentPresenter
Name="ContentSite"
Margin="3,3,23,3"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Content="{TemplateBinding SelectionBoxItem}"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
IsHitTestVisible="False" />
<TextBox
x:Name="PART_EditableTextBox"
Margin="3,3,23,3"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Background="Transparent"
Focusable="True"
Foreground="#d0d0d0"
IsReadOnly="{TemplateBinding IsReadOnly}"
Style="{x:Null}"
Template="{StaticResource ComboBoxTextBox}"
Text="{TemplateBinding Text}"
Visibility="Visible" />
<Popup
Name="Popup"
AllowsTransparency="True"
Focusable="False"
IsOpen="{TemplateBinding IsDropDownOpen}"
Placement="Bottom"
PopupAnimation="Slide">
<Grid
Name="DropDown"
MinWidth="{TemplateBinding ActualWidth}"
MaxHeight="{TemplateBinding MaxDropDownHeight}"
SnapsToDevicePixels="True">
<Border
x:Name="DropDownBorder"
Background="#1b1b1c"
BorderBrush="#3f3f46"
BorderThickness="1" />
<ScrollViewer
Margin="4,6,4,6"
SnapsToDevicePixels="True"
Style="{DynamicResource VoidwalkerDarkScrollviewer}"><!-- IF I REMOVE THIS STYLE EVERYTHING WORKS FINE !-->
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" />
</ScrollViewer>
</Grid>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasItems" Value="false">
<Setter TargetName="DropDownBorder" Property="MinHeight" Value="95" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="LightGray" />
</Trigger>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false" />
</Trigger>
<Trigger SourceName="Popup" Property="Popup.AllowsTransparency" Value="true">
<Setter TargetName="DropDownBorder" Property="CornerRadius" Value="0,0,4,4" />
<Setter TargetName="DropDownBorder" Property="Margin" Value="0" />
</Trigger>
<Trigger Property="IsEditable" Value="true">
<Setter Property="IsTabStop" Value="false" />
<Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Visible" />
<Setter TargetName="ContentSite" Property="Visibility" Value="Hidden" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
As the comment in the style suggests, everything works fine if I simply remove the ScrollViewer style from the combobox...but I need it to complete my dark theme.
Does anyone know what I am missing to make this work?
rewriting ScrollViewer template to change ScrollBar color is an overkill.
ScrollBar is a part of ScrollViewer which is a part of ComboBox. Add a default ScrollBar style in ComboBox style Resources and change color via setter:
<Style TargetType="ComboBox">
<Style.Resources>
<Style TargetType="ScrollBar">
<Setter Property="Background" Value="Red"/>
</Style>
</Style.Resources>
</Style>
I figured it out. Just needed to dig a little deeper online. Here's some working XAML(Some of it may not be needed, but it's for full combobox styling) and a picture to show it)
<ControlTemplate x:Key="ComboBoxToggleButton" TargetType="ToggleButton">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<Border
x:Name="Border"
Grid.ColumnSpan="2"
Background="#3f3f46"
BorderBrush="#3f3f46"
BorderThickness="1" />
<Border
Grid.Column="0"
Margin="1"
Background="#333337"
BorderBrush="#3f3f46"
BorderThickness="0,0,1,0" />
<Path
x:Name="Arrow"
Grid.Column="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="M 0 0 L 4 4 L 8 0 Z"
Fill="#d0d0d0" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Border" Property="Background" Value="LightGray" />
<Setter TargetName="Border" Property="BorderBrush" Value="Gray" />
<Setter Property="Foreground" Value="DarkGray" />
<Setter TargetName="Arrow" Property="Fill" Value="DarkGray" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<ControlTemplate x:Key="ComboBoxTextBox" TargetType="{x:Type TextBox}">
<ScrollViewer
x:Name="PART_ContentHost"
Background="{TemplateBinding Background}"
Focusable="False" />
</ControlTemplate>
<ControlTemplate x:Key="ScrollBackground" TargetType="RepeatButton">
<Border Background="Transparent" />
</ControlTemplate>
<Style x:Key="ScrollThumbStyle" TargetType="Thumb">
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="IsTabStop" Value="false" />
<Setter Property="Focusable" Value="false" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Thumb">
<Rectangle
Width="13"
Fill="#7D7D7D"
RadiusX="5"
RadiusY="5" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- ComboBox style -->
<Style x:Key="VoidwalkerDarkComboBox" TargetType="{x:Type ComboBox}">
<Style.Resources>
<Style TargetType="ScrollBar">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ScrollBar">
<Grid Width="15">
<Border
Width="13"
HorizontalAlignment="Center"
Background="#33555555"
CornerRadius="5" />
<Track
Name="PART_Track"
Width="{TemplateBinding Width}"
HorizontalAlignment="Center"
IsDirectionReversed="true"
Maximum="{TemplateBinding Maximum}"
Minimum="{TemplateBinding Minimum}"
Value="{TemplateBinding Value}">
<Track.DecreaseRepeatButton>
<RepeatButton Command="ScrollBar.LineUpCommand" Template="{StaticResource ScrollBackground}" />
</Track.DecreaseRepeatButton>
<Track.IncreaseRepeatButton>
<RepeatButton Command="ScrollBar.LineDownCommand" Template="{StaticResource ScrollBackground}" />
</Track.IncreaseRepeatButton>
<Track.Thumb>
<Thumb Style="{StaticResource ScrollThumbStyle}" />
</Track.Thumb>
</Track>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Style.Resources>
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.CanContentScroll" Value="true" />
<Setter Property="MinWidth" Value="120" />
<Setter Property="MinHeight" Value="20" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBox">
<Grid>
<ToggleButton
Name="ToggleButton"
Grid.Column="2"
ClickMode="Press"
Focusable="false"
IsChecked="{Binding Path=IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
Template="{StaticResource ComboBoxToggleButton}" />
<ContentPresenter
Name="ContentSite"
Margin="3,3,23,3"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Content="{TemplateBinding SelectionBoxItem}"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
IsHitTestVisible="False" />
<TextBox
x:Name="PART_EditableTextBox"
Margin="3,3,23,3"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Background="Transparent"
Focusable="True"
Foreground="#d0d0d0"
IsReadOnly="{TemplateBinding IsReadOnly}"
Style="{x:Null}"
Template="{StaticResource ComboBoxTextBox}"
Text="{TemplateBinding Text}"
Visibility="Visible" />
<Popup
Name="Popup"
AllowsTransparency="True"
Focusable="False"
IsOpen="{TemplateBinding IsDropDownOpen}"
Placement="Bottom"
PopupAnimation="Slide">
<Grid
Name="DropDown"
MinWidth="{TemplateBinding ActualWidth}"
MaxHeight="{TemplateBinding MaxDropDownHeight}"
SnapsToDevicePixels="True">
<Border
x:Name="DropDownBorder"
Background="#1b1b1c"
BorderBrush="#3f3f46"
BorderThickness="1" />
<ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True">
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" />
</ScrollViewer>
</Grid>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasItems" Value="false">
<Setter TargetName="DropDownBorder" Property="MinHeight" Value="95" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="LightGray" />
</Trigger>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false" />
</Trigger>
<Trigger SourceName="Popup" Property="Popup.AllowsTransparency" Value="true">
<Setter TargetName="DropDownBorder" Property="CornerRadius" Value="0,0,4,4" />
<Setter TargetName="DropDownBorder" Property="Margin" Value="0" />
</Trigger>
<Trigger Property="IsEditable" Value="true">
<Setter Property="IsTabStop" Value="false" />
<Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Visible" />
<Setter TargetName="ContentSite" Property="Visibility" Value="Hidden" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
My best guess is that originally overriding the ScrollViewer itself must have broke something internally...perhaps I left something out. I don't know. Either way, a solution/alternative is just to provide a style for the scrollbars themselves, and ignore the ScrollViewer altogether.
I have the following context menu attached to a rectangle:
<Rectangle x:Name="criteria1" IsHitTestVisible="True">
<Rectangle.ContextMenu>
<ContextMenu>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height=".5*"/>
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".5*"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Grid.Row="0" Content="Amplitude percentage"/>
<TextBox Grid.Column="1" Grid.Row="0" mah:TextBoxHelper.ClearTextButton="True" mah:ControlsHelper.FocusBorderBrush="{DynamicResource AccentColorBrush}" Width="70" >
<TextBox.Text>
<Binding Path="Criteria1AmplitudePercentage" TargetNullValue="{x:Static sys:String.Empty}" UpdateSourceTrigger="LostFocus" ValidatesOnDataErrors="True" />
</TextBox.Text>
</TextBox>
<Label Grid.Column="0" Grid.Row="1" Content="Bandwidth percentage}" />
<TextBox Grid.Column="1" Grid.Row="1" mah:TextBoxHelper.ClearTextButton="True" mah:ControlsHelper.FocusBorderBrush="{DynamicResource AccentColorBrush}" Width="70" >
<TextBox.Text>
<Binding Path="Criteria1BandwidthPercentage" TargetNullValue="{x:Static sys:String.Empty}" UpdateSourceTrigger="LostFocus" ValidatesOnDataErrors="True" />
</TextBox.Text>
</TextBox>
</Grid>
</ContextMenu>
</Rectangle.ContextMenu>
On mouse hover I get this highlighting effect where the background turns dark grey:
How can I remove this highlighting effect?
UPDATE
The context menu appears only via right click. When setting ContextMenu Background="Red" and Grid Background="Red", the menu looks like this:
When the mouse enters or is inside the menu or even if I click inside the text boxes, it looks like this:
EDIT: This is the default ContextMenu style:
<Style x:Key="ContextMenuDefaultStyle" TargetType="{x:Type ContextMenu}">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Background" Value="{DynamicResource MenuPopupBackgroundBrush}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="BorderBrush" Value="{DynamicResource MenuPopupBorderBrush}"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="2"/>
<Setter Property="Grid.IsSharedSizeScope" Value="True"/>
<Setter Property="HasDropShadow" Value="{DynamicResource {x:Static SystemParameters.DropShadowKey}}"/>
<Setter Property="ScrollViewer.PanningMode" Value="Both"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="FontFamily" Value="{DynamicResource {x:Static SystemFonts.MessageFontFamilyKey}}"/>
<Setter Property="FontSize" Value="{DynamicResource {x:Static SystemFonts.MessageFontSizeKey}}"/>
<Setter Property="FontWeight" Value="{DynamicResource {x:Static SystemFonts.MessageFontWeightKey}}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ContextMenu}">
<Border Uid="Border_93">
<Border.Style>
<Style TargetType="{x:Type Border}">
<Setter Property="Tag" Value="{DynamicResource {x:Static SystemParameters.DropShadowKey}}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Tag, RelativeSource={RelativeSource Self}}" Value="True">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Padding" Value="0,0,5,5"/>
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect BlurRadius="4" Opacity="0.8" ShadowDepth="1"/>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Uid="Border_50">
<ScrollViewer CanContentScroll="True" Style="{DynamicResource {ComponentResourceKey ResourceId=MenuScrollViewer, TypeInTargetAssembly={x:Type FrameworkElement}}}" Uid="ScrollViewer_9">
<ItemsPresenter KeyboardNavigation.DirectionalNavigation="Cycle" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Uid="ItemsPresenter_5"/>
</ScrollViewer>
</Border>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ContextMenu Background="Transparent">
Isn't that all you need?
I want to change the behaviour of the editable ComboBox. This is the behaviour I want:
Make the TextBox (PART_EditableTextBox) only visible when IsEditable is true and when the ComboBox is open. I've worked this out in the ControlTemplate.Triggers part:
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsEditable" Value="True" />
<Condition Property="IsDropDownOpen" Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Visible"/>
</MultiTrigger>
The problem is that when the PART_EditableTextBox is hidden, the content is not shown. So the ComboBox stays blank after I've selected an item. This is only true when IsEditable = true.
Below is the complete ComboBox template code.
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Animations.xaml"/>
<ResourceDictionary Source="Brushes.xaml"/>
</ResourceDictionary.MergedDictionaries>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
<ControlTemplate x:Key="EditableComboBoxToggleButton" TargetType="ToggleButton">
<ControlTemplate.Resources>
</ControlTemplate.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<!-- The drop down button on the right -->
<Border Grid.ColumnSpan="2" BorderBrush="#FFFFFFFF" BorderThickness="1,1,1,1" CornerRadius="4,4,4,4">
<Border x:Name="Border" Background="{StaticResource ButtonBaseBrush}" BorderBrush="{StaticResource ButtonInnerBorderBrush}" BorderThickness="1,1,1,1" CornerRadius="4,4,4,4">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="0.507*"/>
<RowDefinition Height="0.493*"/>
</Grid.RowDefinitions>
<Border Opacity="0" HorizontalAlignment="Stretch" x:Name="glow" Width="Auto" Grid.RowSpan="2" CornerRadius="4,4,4,4" Background="{StaticResource ButtonLitBrush}" />
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Width="Auto" Grid.RowSpan="2"/>
<Border HorizontalAlignment="Stretch" Margin="0,0,0,0" x:Name="shine" Width="Auto" CornerRadius="4,4,0,0" Background="{StaticResource ButtonGlowOverlay}" />
</Grid>
</Border>
</Border>
<!-- The white area where the selected item is displayed (also part of the button) -->
<Border
Grid.Column="0"
CornerRadius="2,0,0,2"
Margin="1"
Background="{StaticResource WindowBackgroundBrush}"
BorderBrush="Black"
BorderThickness="1" />
<!-- The down-arrow -->
<Path
x:Name="Arrow"
Grid.Column="1"
Fill="White"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="M 0 0 L 4 4 L 8 0 Z"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="ToggleButton.IsChecked" Value="True">
<Setter Property="Opacity" TargetName="shine" Value="0.4"/>
<Setter Property="Background" TargetName="Border" Value="#DCE38819"/>
<Setter Property="Visibility" TargetName="glow" Value="Hidden"/>
</Trigger>
<Trigger Property="ToggleButton.IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource Timeline1}"/>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard x:Name="Timeline2_BeginStoryboard" Storyboard="{StaticResource Timeline2}"/>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<ControlTemplate x:Key="ComboBoxTextBox" TargetType="TextBox">
<Border x:Name="PART_ContentHost" Focusable="False" Background="{TemplateBinding Background}" />
</ControlTemplate>
<Style x:Key="EditableGlassComboBox" TargetType="ComboBox">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
<Setter Property="MinWidth" Value="120"/>
<Setter Property="MinHeight" Value="20"/>
<Setter Property="Height" Value="34" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBox">
<Grid>
<ToggleButton
Name="ToggleButton"
Template="{StaticResource EditableComboBoxToggleButton}"
IsEnabled="{TemplateBinding IsEnabled}"
Grid.Column="2"
Focusable="false"
IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
ClickMode="Press">
</ToggleButton>
<ContentPresenter
Name="ContentSite"
IsHitTestVisible="False"
Content="{TemplateBinding SelectionBoxItem}"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
Margin="3,3,23,3"
VerticalAlignment="Center"
HorizontalAlignment="Stretch" />
<TextBox x:Name="PART_EditableTextBox"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="Red"
Grid.Column="0"
Style="{x:Null}"
Template="{StaticResource ComboBoxTextBox}"
FontSize="16"
Margin="5,5,23,5"
Focusable="True"
Visibility="Collapsed"
IsReadOnly="{TemplateBinding IsReadOnly}"/>
<Popup
Name="Popup"
Placement="Bottom"
IsOpen="{TemplateBinding IsDropDownOpen}"
AllowsTransparency="True"
Focusable="False"
PopupAnimation="Slide">
<Grid
Name="DropDown"
SnapsToDevicePixels="True"
MinWidth="{TemplateBinding ActualWidth}"
MaxHeight="{TemplateBinding MaxDropDownHeight}">
<Border
x:Name="DropDownBorder"
Background="{StaticResource WindowBackgroundBrush}"
BorderThickness="1"
BorderBrush="{StaticResource ComboItemsBorderBrush}"/>
<ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True">
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" />
</ScrollViewer>
</Grid>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasItems" Value="false">
<Setter TargetName="DropDownBorder" Property="MinHeight" Value="95"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/>
</Trigger>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</Trigger>
<Trigger SourceName="Popup" Property="Popup.AllowsTransparency" Value="true">
<Setter TargetName="DropDownBorder" Property="CornerRadius" Value="4"/>
<Setter TargetName="DropDownBorder" Property="Margin" Value="0,2,0,0"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsEditable" Value="True" />
<Condition Property="IsDropDownOpen" Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Visible"/>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
</Style.Triggers>
</Style>
I've solved my problem by completely ignoring the ComboBox and creating my own UserControl that has a TextBox and a Popup with a ListBox. In code behind I've added filtering and popup up / closing the popup at the right time.
You have to put a TextBlock or a ContentPresenter behind the TextBox (bound to the same value) so when you hide the TextBox the TextBlock becomes visible and shows the selected value.
The easiest way to accomplish this is to but them in the same Grid:
<Grid>
<ContentPresenter Content="{TemplateBinding Text}"/>
<TextBox x:Name="PART_EditableTextBox"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="Red"
Grid.Column="0"
Style="{x:Null}"
Template="{StaticResource ComboBoxTextBox}"
FontSize="16"
Margin="5,5,23,5"
Focusable="True"
Visibility="Collapsed"
IsReadOnly="{TemplateBinding IsReadOnly}"/>
</Grid>