Textbox style setter breaks functionality - c#

for some reason in my code behind (WPF), the "setter" section makes the text box not function anymore. I can't type in it or add any functionality to it. When I remove the setter section, the text box works. I've seen other people online do it this exact way and it works for them but I'm not sure what I'm doing wrong.
Here's what I have in the main window.
<TextBox Style="{DynamicResource inputBox}" Margin="0,50,125,0"/>
And here's what I have in the code behind
<Style x:Key="inputBox" TargetType="TextBox">
<Setter Property="Padding" Value="3"/>
<Setter Property="Height" Value="35"/>
<Setter Property="Width" Value="65"/>
<Setter Property="FontSize" Value="10"/>
<Setter Property="TextWrapping" Value="Wrap"/>
<Setter Property="Text" Value=""/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Top"/>
<!--This setter somehow breaks the text box-->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Border Background="Transparent" CornerRadius="5" BorderThickness="1" BorderBrush="Black">
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Thanks

Your template only shows the border. Not the content. It needs a PART_ContentHost Do yourself a favor and copy the existing template and edit that. You can do this on the XAML designer. For example, here is what it looks like when I copy it on mine:
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Border x:Name="border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="True">
<ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" TargetName="border" Value="0.56"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.MouseOver.Border}"/>
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.Focus.Border}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>

Related

WPF Content Presenter weird horizontal alignment behaviour

I'm trying to center a content a Content Presenter in a button, It centers perfectly in the designer But when ran it will either go off center by a bit or will get cut off. What's confusing me is that I have another style that does relatively the same thing but works perfectly.
Here's the style;
<Style x:Key="MainButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="0,1"/>
<Setter Property="RenderOptions.BitmapScalingMode" Value="NearestNeighbor"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid x:Name="Chrome" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
<Grid.BindingGroup>
<BindingGroup/>
</Grid.BindingGroup>
<Border x:Name="border" CornerRadius="3,3,3,3" BorderBrush="LightGray" BorderThickness="1" Background="#FFF3F3F3" Padding="0">
<ContentPresenter
HorizontalAlignment="Center"
VerticalAlignment="Stretch"
TextElement.FontWeight="Light" Height="Auto" Margin="153.636,0.52,156,1.52" Width="Auto" UseLayoutRounding="False" SnapsToDevicePixels="False" >
</ContentPresenter>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" TargetName="border" Value="#330CB3EE"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" TargetName="border" Value="#FF0CB3EE"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" TargetName="Chrome" Value="0.25"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Remove the Margin from the Content Presenter:
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Stretch"
TextElement.FontWeight="Light"
Height="Auto"
Width="Auto"
UseLayoutRounding="False"
SnapsToDevicePixels="False" >
This Margin was probably added by the designer, matching the layout of the control in the designer.

WPF Material Design Raised Button Hovered state

I'm trying to recreate a material design look & feel for a button. For the focused (hovered) state the guidelines say to make a 12 % #000000 shade over the button. I was wondering how this could be achieved in WPF.
I've been looking around a good option would be to add a non-hittable rectangle over the button with a 12 % opacity and a color of #000000. I want to implement this as a style, but I have no idea how to do that.
My style looks like this at moment:
<Style x:Key="MaterialRaisedButton" TargetType="ToggleButton">
<Setter Property="Padding" Value="8 0"/>
<Setter Property="Margin" Value="8 6 8 6"/>
<Setter Property="Height" Value="36"/>
<Setter Property="MinWidth" Value="64"/>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="Background" Value="{StaticResource MaterialSecondaryColorBrush}"/>
<Setter Property="Effect" Value="{StaticResource z-depth2}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Grid>
<Rectangle RadiusX="4" RadiusY="4" Fill="#000000" Opacity="0.12"/>
<Border CornerRadius="4" Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource Material12Black}"/>
</Trigger>
</Style.Triggers>
</Style>
If there are any other methods of doing this, I'm all ear as well :)
In the fill of the rectangle you can specify opacity in the hex color like #00000000, the first two values are the opacity. So 12% would be #1e000000. The following will show .5 opacity rectangle when mouse is over other wise opacity is 0.
<Rectangle.Style>
<Style TargetType="{x:Type Rectangle}">
<Setter Property="Opacity" Value="0"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" Value=".5"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="false">
<Setter Property="Opacity" Value="0"/>
</Trigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
</Rectangle>
Update:
If anybody wants to reuse the code for a material-like button, the code is below. I used the ripple effect from this stackoverflower along with the shadows from this source. Hopefully this can help others recreating Material design without the toolkit :)
<Style x:Key="MaterialRaisedButton2" TargetType="Button">
<Setter Property="Padding" Value="8 0"/>
<Setter Property="Margin" Value="8 6 8 6"/>
<Setter Property="Height" Value="36"/>
<Setter Property="MinWidth" Value="64"/>
<Setter Property="Foreground" Value="{StaticResource NormalTextBrush}"/>
<Setter Property="Background" Value="{StaticResource MaterialSecondaryColorBrush}"/>
<Setter Property="Effect" Value="{StaticResource z-depth2}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<cons:RippleEffectDecorator Height="{TemplateBinding Height}" Width="{TemplateBinding Width}" Background="{TemplateBinding Background}" HighlightBackground="#1e000000" Grid.Row="0" Grid.Column="0" Panel.ZIndex="0">
<Grid>
<Rectangle RadiusX="4" RadiusY="4" Fill="#1e000000" Panel.ZIndex="1">
<Rectangle.Style>
<Style TargetType="{x:Type Rectangle}">
<Setter Property="Opacity" Value="0"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" Value="0.12"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="false">
<Setter Property="Opacity" Value="0"/>
</Trigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
</Rectangle>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</cons:RippleEffectDecorator>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" Value="#1FFFFFFF"/>
<Setter Property="Foreground" Value="#42FFFFFF"/>
</Trigger>
</Style.Triggers>
</Style>

Border Color For Toggle Button Does not change?

I have the following style
<Style TargetType="{x:Type ToggleButton}" x:Key="ListToggleButton">
<Setter Property="FontSize" Value="15" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Foreground" Value="#FF232A2E"/>
<Setter Property="Background" Value="White"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border Background="{TemplateBinding Background}" BorderBrush="#FFECECEC" BorderThickness="0,0,0,1">
<Grid>
<ContentPresenter x:Name="MyContentPresenter" Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,0,0,0" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="False">
<Setter Property="Background" Value="#FF232A2E"/>
<Setter Property="BorderBrush" Value="#FFECECEC"/>
<Setter Property="BorderThickness" Value="0,0,0,1"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Background" Value="#FFF5F5F5"/>
<Setter Property="BorderBrush" Value="#FF25a0da"/>
<Setter Property="BorderThickness" Value="0,0,0,2"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I want to change the border color when I checked the button, background changes but border no !
What I miss
Thanks in advance
You need to specify a name for the border, and specify it under TargetName in the Setter. When you omit TargetName, it will set the value of the property of the owner of the trigger (in this case the ToggleButton itself). Background setter is working because the border's background is template-bound to the togglebutton's background property.
<Style TargetType="{x:Type ToggleButton}" x:Key="ListToggleButton">
<Setter Property="FontSize" Value="15" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Foreground" Value="#FF232A2E"/>
<Setter Property="Background" Value="White"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border x:Name="ButtonBorder" Background="{TemplateBinding Background}" BorderBrush="#FFECECEC" BorderThickness="0,0,0,1">
<Grid>
<ContentPresenter x:Name="MyContentPresenter" Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,0,0,0" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="False">
<Setter Property="Background" Value="#FF232A2E"/>
<Setter Property="BorderBrush" Value="#FFECECEC" TargetName="ButtonBorder"/>
<Setter Property="BorderThickness" Value="0,0,0,1" TargetName="ButtonBorder"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Background" Value="#FFF5F5F5"/>
<Setter Property="BorderBrush" Value="#FF25a0da" TargetName="ButtonBorder"/>
<Setter Property="BorderThickness" Value="0,0,0,2" TargetName="ButtonBorder"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Setting BorderBrush of Button with a custom template and triggers

I'm trying to change the borderbrush property of a button in a custom template. Changing the background on mouseover using this method works just fine, but the BorderBrush? Nada.
Here's my code:
<Style x:Key="ImageButtonStyle" TargetType="Button">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Margin" Value="2"/>
<Setter Property="Background" Value="LightGray"/>
<Setter Property="BorderBrush" Value="Blue"/>
<Setter Property="BorderThickness" Value="3"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" Margin="1,0,0,-9">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,1,1,0" Height="94" Width="101"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="border" Property="BorderBrush" Value="Red"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Edit: Actually not even the blue borderbrush set at the beggining shows up so that may be of relevance.
Here's where the style is used if of any importance.
<Button Margin="191,10,138,109" Style="{StaticResource ImageButtonStyle}">
<Image/>
</Button>
You create style setting BorderThickness to 3 but then override default visual tree so this thicknes is not taken into acount. Add this
BorderThickness="{TemplateBinding BorderThickness}"
in order to see it.

Changing from a TextBox to a ComboBox

I have a custom stye applied to textboxes in my WPF page, however I have now changed TextBoxes to editable ComboBoxes and need to apply the style to fit the new editable ComboBoxes. This is the current code:
<Style TargetType="ComboBox">
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="BorderBrush" Value="Silver"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="AllowDrop" Value="true"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBoxBase}">
<Border Name="Border" Padding="1" Background="#FFFFFF" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" >
<ScrollViewer Margin="0" x:Name="PART_ContentHost"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Border" Property="Background" Value="#EEEEEE"/>
<Setter TargetName="Border" Property="BorderBrush" Value="#EEEEEE"/>
<Setter Property="Foreground" Value="#888888"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The above is what I have managed to change, however I am unsure of what else needs to be changed. The editable ComboBox is essentially a textbox with a drop down, so I assumed that it would remain pretty much the same. The TextBoxBase seems to be the biggest issue.
After creating a new sample project, the problem seems to be a bug with Windows 8.

Categories

Resources