WPF Menuitem Border - wpf

I've run into a problem trying to implement a Menu and can't figure out what is going on. I'm trying to make a single-layer menu using the Menu control. Here is my menu code:
<Menu DockPanel.Dock="Top" Height="22" Name="menu1" VerticalAlignment="Top" Background="#FF325170">
<MenuItem Header="Featured" Style="{StaticResource menuItemStyle}" />
<MenuItem Header="Search" Style="{StaticResource menuItemStyle}" />
</Menu>
And my style for my MenuItems is as follows:
<Style x:Key="menuItemStyle" TargetType="{x:Type MenuItem}">
<Style.Triggers>
<Trigger Property="MenuItem.IsMouseOver" Value="true">
<Setter Property = "Foreground" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
When I mouseover the menu items, there is a Border that appears, and I can't figure out for the life of me how to remove this border. Any suggestions?

For a lot of the built-in WPF control styles, you need to override the ControlTemplate.
Here is the MSDN page that provides the Menu ControlTemplate, with instructions on how to use it -- basically you are inserting local copies of all the styles for the Menu control, which then override the default control look and feel.
To address your problem you should be able to just insert this style:
<Style x:Key="{x:Type Menu}" TargetType="{x:Type Menu}">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Menu}">
<!--Here is where you change the border thickness to zero on the menu-->
<Border BorderThickness="0">
<StackPanel ClipToBounds="True" Orientation="Horizontal"
IsItemsHost="True"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Related

Tabbing focus not working with control template that wraps control

I've tried all kinds of template binding and such to get this to work, but if I use this style on a control, the internal textbox control doesn't show focus.
I'm doing this because I want to set an error template that wraps around the textbox and the spot reserved for displaying units.
Now, typing in the box correct updates the text inside. And clicking on it will show the highlighted border and input caret, but tabbing into it won't.
<Style x:Key="Special" TargetType="{x:Type TextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<DockPanel
LastChildFill="True"
Visibility="Visible">
<Border
Name="PART_UnitContainer"
DockPanel.Dock="Right"
Visibility="Collapsed">
<Label
Content="ft"
Style="{DynamicResource UnitLabel}"
/>
</Border>
<TextBox Name="PART_Control" Text="{Binding Text, RelativeSource={RelativeSource TemplatedParent}}"/>
</DockPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter TargetName="PART_UnitContainer" Property="Visibility" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Initially I set the whole control as no tab stop, and internal one with tabstop, but apparently you also have to set the tab navigation to continue. I didn't when I tried playing with navigation, so I overlooked this setting.
<Style x:Key="Special" TargetType="{x:Type TextBox}">
<Setter Property="KeyboardNavigation.TabNavigation" Value="Continue"/>
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="Template">
<ControlTemplate>
...
<Text IsTabStop="True" Name="PART_Control" ...
...
</ControlTemplate>
</Setter>
</Style>
However, this little trick doesn't work for shift-tab out of an editable combobox. I'll update the answer if I figure it out.
For comboboxes you have to do it differently. You don't set TabNavigation to Continue, and you don't set IsTabStop on internal combobox to true.
See
<Style x:Key="Special" TargetType="{x:Type ComboBox}">
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="Template">
<ControlTemplate>
...
<ComboBox Name="PART_Control" ...
...
</ControlTemplate>
</Setter>
</Style>

WPF - Using Control Template just on one element

My first steps in WPF and C# and i don't get it to work... :(
I have an application with two grids inside one window. I have to change the style of the first grid, so i started reading and reached using ControlTemplate.
My Grid now looks as i wanted it. But i only want that the first grid looks this way. the second one on the same page should have another style.
Is it possible to bind the controltemplate only on one grid. Maybe by name or soemthing identifying?
My ControlTemplate Code for now i have written in window.resources looks:
<Style TargetType="{x:Type TabItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid>
<Border
Name="Border"
Margin="0,0,0,0"
Background="Black"
BorderBrush="Black"
BorderThickness="0,2,0,0"
CornerRadius="0,0,0,0" >
<ContentPresenter x:Name="ContentSite"
VerticalAlignment="Center"
HorizontalAlignment="Center"
ContentSource="Header"
Margin="0,0,0,20"
RecognizesAccessKey="True"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Border" Property="BorderBrush" Value="#FF454E54" />
<Setter TargetName="Border" Property="Background" Value="#FF0A3651" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Border" Property="BorderBrush" Value="White" />
<Setter TargetName="Border" Property="Background" Value="#FF454E54" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
You could give the Style or ControlTemplate an x:Key ( <Style x:Key="key" TargetType="{x:Type TabItem}"> ) and apply it to the element you want by setting the element's Style or Template property like this:
<TabItem Style="{StaticResource key}">
A Style without an x:Key is implicit and will be applied to all elements whose type matches the specified TargetType of the Style.
Instead of writing your template under Window.Resources do it under your Grid.Resources
Try this. All this is doing is setting the style of the TabItem directly.
<TabItem> <!-- This is your TabItem control -->
<TabItem.Style>
<Style TargetType="{x:Type TabItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<!-- ControlTemplate here -->
</Controltemplate
</Setter.Value>
</Setter>
</Style>
</TabItem.Style>
</TabItem>

WPF Wrap panel not working for radio button with content template binding style?

I am new at WPF. I have list of radio button in menu of WPF application. I changed the style of radio button to look like textblock as submenu. Now problem is when I am trying to wrap and image and text inside radio button it's not showing it. but if i remove the style that I added on radio button to look and feel like textblock then wraping is just working fine but then it's display radion button Icon which I not needed.
Please refer to below code :
<StackPanel.Resources>
<Style x:Key="RadioButtonMenuStyle" TargetType="RadioButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RadioButton}">
<TextBlock Text="{TemplateBinding Content}">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Height" Value="36"/>
<Setter Property="Foreground" Value="Black" />
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="TextAlignment" Value="Center"/>
<Setter Property="TextWrapping" Value="Wrap"/>
</TextBlock.Style>
</TextBlock>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</StackPanel.Resources>
------------------------------------------------------------------------
<RadioButton Name="rbttest" GroupName="rbtgroup" Background="{x:Null}" Style="
{StaticResource RadioButtonMenuStyle}" IsChecked="True">
<WrapPanel>
<Image Source="/WpfApplication1;component/Images/Test.ico" Width="16" Height="16"
Margin="0,0,5,0" />
<TextBlock Text="Test" Foreground="Green" />
</WrapPanel>
</RadioButton>
Is the templateBinding Content causing the problem ?
In your template, you are binding TextBlock.Text to RadioButton.Content, but your RadioButton content is actually a UI element (WrapPanel).
Get rid of the TextBlock in the template and replace it with a ContentPresenter. You don't need to set any properties on the presenter; it already knows how to locate the content on the templated parent.

WPF Combobox Validation.ErrorTemplate error

I have a combobox that i need to edit its error template to show a red border when there is a validation error.
I am using the following style
<Style TargetType="{x:Type ComboBox}" >
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<DockPanel>
<Border BorderBrush="Red" BorderThickness="3">
<AdornedElementPlaceholder />
</Border>
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="FontFamily" Value="Segoe UI" />
<Setter Property="FontSize" Value="12" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
The border never shows up when validation errors occur. Any tips what is going wrong?
The Style you posted works. You should check your binding, did you add ValidatesOnDataErrors=True and ValidatesOnExceptions=True to the binding of SelectedValue?
enter code heretry without the dock panel, that is uneuseful since it wraps jus one element. However, sicnecerely I don't wnow if it makes sense to wrap a textbox with a border, since it has already a border! You should try to change directly the colour of its border. You could try to use again the panel but then put the border around the panel ie:
Border BorderBrush="Red" BorderThickness="3"
DockPanel
AdornedElement
This makes more sense because the wrap panel has not its own border.
Use This.
<Style x:Key="textBoxStyle" TargetType="{x:Type telerik:RadMaskedTextBox}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
<Setter Property="Control.BorderBrush" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
I don't like any of the responses here. Simply put, how do you change the border color for the error template for a ComboBox using Blend or not? It shouldn't be acceptable to draw another border around the existing border of the ComboBox. I've figured out how to creat a ControlTemplate in Blend but not a Validation Template.
I've come close with trying to make it appear like I've changed the actual border color, but that's not what I actually want. Suggestions? To complicate it a bit, I'd like to display a red asterisk outside of the right border of the control.
The following code is a close attempt, but it is actually drawing a border inside the ComboBox and if you look close, you can see that the border is 2 pixels wide when combined with the ComboBox border:
<DockPanel Name="myDockPanel">
<AdornedElementPlaceholder>
<Border BorderBrush="Blue" BorderThickness="1" CornerRadius="2" />
</AdornedElementPlaceholder>
<TextBlock Text="*" FontWeight="Bold" FontSize="14" Foreground="Red" DockPanel.Dock="Left" ToolTip="{Binding .CurrentItem}" />
</DockPanel>
I searched around some more and came up with a solution based on another article here: WPF - How to apply style to AdornedElementPlaceholder's AdornedElement?
<!-- This works -->
<ComboBox Name="comboBox1" Style="{StaticResource NewComboBoxStyle}" Validation.ErrorTemplate="{StaticResource comboBoxValidationTemplate}" />
<SolidColorBrush x:Key="MainBorderBrush">#FF91B3FF</SolidColorBrush>
<Style x:Key="NewComboBoxStyle" TargetType="{x:Type ComboBox}" BasedOn="{StaticResource myErrorTemplate}">
<Setter Property="BorderBrush" Value="{DynamicResource MainBorderBrush}" />
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="BorderBrush" Value="Blue" />
</Trigger>
</Style.Triggers>
</Style>
<!-- Sets ToolTip when Validation.HasError is True. -->
<Style TargetType="Control" x:Key="myErrorTemplate">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={x:Static RelativeSource.Self},
Path=(Validation.Errors).CurrentItem.ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
<ControlTemplate x:Key="comboBoxValidationTemplate">
<DockPanel Name="myDockPanel">
<AdornedElementPlaceholder/>
<TextBlock Text="*" FontWeight="Bold" FontSize="14" Foreground="Red" DockPanel.Dock="Left" ToolTip="{Binding .CurrentItem}" />
</DockPanel>
</ControlTemplate>

Trigger in WPF is not working

I have a ListView, with ListView.View as GridView.
Default, the mouseOver is working, ListViewItem get highlighted when I mouseover, and get selected when I click it. But after I modified the ControlTemplate, I get the template I want, but the highlight and select is gone.
I use trigger, but it's not working.
Here is my code.
<Style x:Key="filesListViewItemStyle" TargetType="{x:Type ListViewItem}">
<Setter Property="IsSelected" Value="{Binding FileIsSelected}"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<Grid Height="40">
<GridViewRowPresenter/>
<Line X1="0.0" Y1="0.0" X2="{Binding ActualWidth, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListView}}}" Y2="0.0" StrokeThickness="1" StrokeDashArray="2" Stroke="Gray" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Green"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
In my template, I actually added a line as a separator between 2 rows of ListViewItem.
I just don't get it why the trigger is not working!
The Background property of a Control is only used in the ControlTemplate. You have replaced the template with one that does not use Background, so setting the property has no effect. You can use {TemplateBinding Background} to bind properties to the Background of the Control. Perhaps you want to bind the Background of the Grid to it:
<ControlTemplate TargetType="ListViewItem">
<Grid Height="40" Background="{TemplateBinding Background}">
<GridViewRowPresenter/>

Resources