following is the code, which is showing the error i.e
: The content property is more than once
Code :
<Window x:Class="Trigger.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Opacity" Value="0.5" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
<Grid>
<Button x:Name="PropertyTriggerButton" Width="160" Height="40" Margin="20,0,0,0" HorizontalAlignment="Left" Content="IsPressed Property"
Cursor="Hand" FontWeight="Bold" Style="{StaticResource ButtonStyle}" ToolTip="Press To Raise Property Trigger">
</Button>
</Grid>
</Window>
The Window element can host only one child. You need to put the Style in the resources. Something like this will do:
<Window.Resources>
<Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Opacity" Value="0.5" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
Put this right after the starting tag of the Window element or just before the closing tag of the Window element.
The full code should be like this:
<Window x:Class="Trigger.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Opacity" Value="0.5" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<Button x:Name="PropertyTriggerButton" Width="160" Height="40" Margin="20,0,0,0" HorizontalAlignment="Left" Content="IsPressed Property"
Cursor="Hand" FontWeight="Bold" Style="{StaticResource ButtonStyle}" ToolTip="Press To Raise Property Trigger">
</Button>
</Grid>
</Window>
Add style inside Window.Resources
<Window.Resources>
<Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Opacity" Value="0.5" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid >
<Button x:Name="PropertyTriggerButton" Width="160" Height="40" Margin="20,0,0,0" HorizontalAlignment="Left" Content="IsPressed Property"
Cursor="Hand" FontWeight="Bold" Style="{StaticResource ButtonStyle}" ToolTip="Press To Raise Property Trigger">
</Button>
</Grid>
Related
I am working on a WPF application and I would like to change the visibility of a grid if an only if a button has focus. I have the following code to change the background of the button if it has focus. I know how to do this Programmatically, but I'd like to know how to get the same thing done in XAML.
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Background" Value="Aqua" />
</Trigger>
</Style.Triggers>
</Style>
You can name your Button and use a DataTrigger:
<Window
...
>
<Window.Resources>
<Style TargetType="{x:Type Grid}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsFocused, ElementName=butt}" Value="True">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<StackPanel>
<Button x:Name="butt">Hide</Button>
<Grid>
<Label Background="Yellow">Inside Grid</Label>
</Grid>
<Button>Steal focus</Button>
</StackPanel>
</Window>
EDIT
<Window
...
>
<Window.Resources>
<Style x:Key="CollapsedGridStyle" TargetType="{x:Type Grid}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked, ElementName=butt}" Value="True">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<StackPanel>
<ToggleButton x:Name="butt">Hide</ToggleButton>
<Grid x:Name="GridA"
Style="{StaticResource CollapsedGridStyle}">
<Label Background="Yellow">Grid A</Label>
</Grid>
<Grid x:Name="GridB">
<Label Background="Green">Grid B</Label>
</Grid>
</StackPanel>
</Window>
Reworked Question to clarify my needs:
I want to add a preview Text to Textboxes when they're empty, just like some of you may know it from Xamarin.
I have found this answer on SO.
This is the Style from the Answer I linked above.
<TextBlock Grid.Row="5"
Grid.Column="1"
VerticalAlignment="Center"
Text="Username:">
</TextBlock>
<TextBox Grid.Row="5"
Grid.Column="3">
<TextBox.Style>
<Style TargetType="TextBox">
<Style.Resources>
<VisualBrush x:Key="CueBannerBrush" AlignmentX="Left" AlignmentY="Center" Stretch="None">
<VisualBrush.Visual>
<Label Content="Test" Foreground="LightGray" />
</VisualBrush.Visual>
</VisualBrush>
</Style.Resources>
<Style.Triggers>
<Trigger Property="Text" Value="{x:Static sys:String.Empty}">
<Setter Property="Background" Value="{StaticResource CueBannerBrush}" />
</Trigger>
<Trigger Property="Text" Value="{x:Null}">
<Setter Property="Background" Value="{StaticResource CueBannerBrush}" />
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter Property="Background" Value="White" />
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
I get the following result:
Since this is working nicely I want to apply it to every TextBox in that Window.
So my approach was to change this line:
<Label Content="Test" Foreground="LightGray" />
I thought maybe changing it to <Label Content="Test" Foreground="LightGray" /> would do the trick, but it is not working.
I guess it's something with the Tag Property and the Type of it (object instead of string).
Since the first approach is working like charm I don't really see why I should need a custom control for that...
So what I tried then is this:
<Window.Resources>
<Style TargetType="TextBox">
<Style.Resources>
<VisualBrush x:Key="CueBannerBrush" AlignmentX="Left" AlignmentY="Center" Stretch="None">
<VisualBrush.Visual>
<Label Content="{Binding RelativeSource={RelativeSource Self}, Path=Tag}" Foreground="LightGray" />
</VisualBrush.Visual>
</VisualBrush>
</Style.Resources>
<Style.Triggers>
<Trigger Property="Text" Value="{x:Static sys:String.Empty}">
<Setter Property="Background" Value="{StaticResource CueBannerBrush}" />
</Trigger>
<Trigger Property="Text" Value="{x:Null}">
<Setter Property="Background" Value="{StaticResource CueBannerBrush}" />
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter Property="Background" Value="White" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
What am I missing - why isn't that working ?
For the reusable textbox, you need to create a custom control. Also for binding doesnot work well with visual brush, so you need some temp object to store the value. Refer my below code.
<Window x:Class="ChkList_Learning.Window4"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ChkList_Learning"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
Title="Window4" Height="300" Width="300">
<Window.Resources>
<local:Temp x:Key="temp" Value="{Binding ElementName=Hostname, Path=Watermark}"/>
<Style TargetType="{x:Type local:WatermarkTextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
<Style.Resources>
<VisualBrush x:Key="WatermarkBrush" AlignmentX="Left" AlignmentY="Center" Stretch="None">
<VisualBrush.Visual>
<TextBlock Text="{Binding Source={StaticResource temp}, Path=Value}" FontFamily="Segoe UI" FontSize="20" Foreground="LightGray" Padding="5" />
</VisualBrush.Visual>
</VisualBrush>
</Style.Resources>
<Style.Triggers>
<Trigger Property="Text" Value="{x:Static sys:String.Empty}">
<Setter Property="Background" Value="{StaticResource WatermarkBrush}" />
</Trigger>
<Trigger Property="Text" Value="{x:Null}">
<Setter Property="Background" Value="{StaticResource WatermarkBrush}" />
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter Property="Background" Value="White" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<local:WatermarkTextBox x:Name="Hostname" Height="40" FontFamily="Segoe UI" FontSize="20" VerticalContentAlignment="Center" Watermark="Hello, world.">
</local:WatermarkTextBox>
</Grid>
</Window>
public class Temp : Freezable
{
// Dependency Property
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(string),
typeof(Temp), new FrameworkPropertyMetadata(string.Empty));
// .NET Property wrapper
public string Value
{
get { return (string)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
protected override System.Windows.Freezable CreateInstanceCore()
{
return new Temp();
}
}
public class WatermarkTextBox : TextBox
{
static WatermarkTextBox()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(WatermarkTextBox), new FrameworkPropertyMetadata(typeof(WatermarkTextBox)));
}
public static readonly DependencyProperty WatermarkProperty = DependencyProperty.Register("Watermark", typeof(string), typeof(WatermarkTextBox));
public string Watermark
{
get { return (string)GetValue(WatermarkProperty); }
set { SetValue(WatermarkProperty, value); }
}
}
I have a style which works well
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="clr-namespace:System;assembly=mscorlib"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:local="clr-namespace:Downloader.App.ResourceDictionaries.NamedStyles">
<Style x:Key="TextBoxWithDefaultTextStyle" TargetType="TextBox">
<!--Padding for typed text-->
<Setter Property="Padding" Value="5, 2, 5, 0"/>
<Setter Property="Background" Value="White" />
<Setter Property="BorderBrush" Value="#FF858585" />
<Setter Property="BorderThickness" Value="3" />
<Setter Property="Border.CornerRadius" Value="10" />
<Setter Property="Control.Template" Value="{StaticResource TextBoxBaseControlTemplate}"></Setter>
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<DockPanel>
<Border BorderBrush="Brown" BorderThickness="5"
CornerRadius="2">
<AdornedElementPlaceholder x:Name="controlWithError"/>
</Border>
<TextBlock Foreground="Red" FontSize="20" FontFamily="Segoe UI" Margin="3,0,0,0">!</TextBlock>
</DockPanel>
<ControlTemplate.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="Background" Value="Red"/>
<Setter Property="Foreground" Value="White"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
Then I want to put it into separate resource as I do with ordinary template
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="clr-namespace:System;assembly=mscorlib"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:local="clr-namespace:Downloader.App.ResourceDictionaries.NamedStyles">
<Style x:Key="TextBoxWithDefaultTextStyle" TargetType="TextBox">
<!--Padding for typed text-->
<Setter Property="Padding" Value="5, 2, 5, 0"/>
<Setter Property="Background" Value="White" />
<Setter Property="BorderBrush" Value="#FF858585" />
<Setter Property="BorderThickness" Value="3" />
<Setter Property="Border.CornerRadius" Value="10" />
<Setter Property="Control.Template" Value="{StaticResource TextBoxBaseControlTemplate}"></Setter>
<Setter Property="Validation.ErrorTemplate" Value="{StaticResource TextBoxValidationTemplate}"></Setter>
</Style>
</ResourceDictionary>
TextBoxValidationTemplate.xaml:
<AdornedElementPlaceholder x:Name="controlWithError"/>
</Border>
<TextBlock Foreground="Red" FontSize="20" FontFamily="Segoe UI" Margin="3,0,0,0">!</TextBlock>
</DockPanel>
<ControlTemplate.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="Background" Value="Red"/>
<Setter Property="Foreground" Value="White"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
Then I run the application and type invalid data and get the exception:
'{DependencyProperty.UnsetValue}' is not a valid value for property 'ErrorTemplate'.
If I apply the error template directly
<TextBox Text="{Binding UserName, Mode=TwoWay, ValidatesOnDataErrors=True, NotifyOnValidationError=True, UpdateSourceTrigger=PropertyChanged}"
Validation.ErrorTemplate="{StaticResource TextBoxValidationTemplate}"
Style="{StaticResource TextBoxWithDefaultTextStyle}"
Grid.Row="2"
Grid.Column="0"
Margin="5,2,5,2"
Grid.ColumnSpan="2"/>
it works as well so the file is OK
Found it my self. Templates must go first, then styles
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary>
<vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" xmlns:vm="clr-namespace:Downloader.App.ViewModel" />
</ResourceDictionary>
<ResourceDictionary Source="ResourceDictionaries\Templates\TextBoxBaseControlTemplate.xaml" />
<ResourceDictionary Source="ResourceDictionaries\Templates\TextBoxValidationTemplate.xaml" />
<ResourceDictionary Source="ResourceDictionaries\Templates\PasswordBoxControlTemplate.xaml" />
<ResourceDictionary Source="ResourceDictionaries\NamedStyles\TextBoxWithDefaultTextStyle.xaml" />
<ResourceDictionary Source="ResourceDictionaries\NamedStyles\PasswordBoxStyle.xaml" />
<ResourceDictionary Source="ResourceDictionaries\Images\Common.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
I have unusual items like a button, ComboBox, CheckBox, etc., in a "Menu" container. The problem is that the MouseOver border for these controls gets overridden somehow, only when they are in that container. Anywhere else, they are fine.
Every control (CheckBoxes, ComboBoxes, Buttons, Labels, etc) has a custom style. This custom style works fine unless these controls are placed in a "Menu". When that happens I get this blue border highlight for some reason for non MenuItem objects. What can I do to fix the border color without moving or changing other controls?
Here is minimal code that reproduces the problem:
<Window x:Class="MyApp.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:MyApp"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero2" x:Name="myWindow"
mc:Ignorable="d"
Title="MyTitle"
Width="560" Height="180"
MinWidth="560" MinHeight="180"
Background="#FF222222" Foreground="Red" BorderBrush="#FF222222" ResizeMode="NoResize" WindowStyle="None" Opacity="0.75" WindowStartupLocation="CenterOwner">
<Window.Resources>
<sys:Double x:Key="height">40</sys:Double>
<sys:Double x:Key="titleBarSize">36</sys:Double>
<sys:Double x:Key="fontSize">16</sys:Double>
<Color x:Key="backgroundColor">#FF222222</Color>
<Brush x:Key="backgroundColorBrush">#FF222222</Brush>
<Color x:Key="highlightedColor">#FF333333</Color>
<Brush x:Key="highlightedColorBrush">#FF333333</Brush>
<Color x:Key="borderColor">#FF333333</Color>
<Brush x:Key="borderColorBrush">#FF333333</Brush>
<Color x:Key="textColor">#FF999999</Color>
<Brush x:Key="textColorBrush">#FF999999</Brush>
<Brush x:Key="titleBarColorBrush">#FF222222</Brush>
<Thickness x:Key="Tab_Border_Thickness">2,2,2,2</Thickness>
<Thickness x:Key="TabItem_Border_Thickness_Selected">2,2,2,0</Thickness>
<!--Button-->
<Style x:Key="ButtonStyle1" TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
<Setter Property="Background" Value="{StaticResource backgroundColorBrush}"/>
<Setter Property="BorderBrush" Value="{StaticResource backgroundColorBrush}"/>
<Setter Property="Foreground" Value="{StaticResource textColorBrush}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Width" Value="Auto"/>
<Setter Property="Height" Value="{StaticResource height}"/>
<Setter Property="FontSize" Value="{StaticResource fontSize}"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border" BorderBrush="{StaticResource backgroundColorBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{StaticResource backgroundColorBrush}"
SnapsToDevicePixels="true">
<ContentPresenter x:Name="contentPresenter" Focusable="False" RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsDefaulted" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource highlightedColorBrush}"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" TargetName="border" Value="{StaticResource highlightedColorBrush}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource highlightedColorBrush}"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Background" TargetName="border" Value="{StaticResource highlightedColorBrush}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource highlightedColorBrush}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="border" Value="{StaticResource backgroundColorBrush}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource backgroundColorBrush}"/>
<Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource textColorBrush}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<Menu x:Name="menu" HorizontalAlignment="Left" Height="40" VerticalAlignment="Top" Width="560">
<Button x:Name="button1" Content="button 1" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Style="{DynamicResource ButtonStyle1}"/>
</Menu>
<Button x:Name="button2" Content="button 2" HorizontalAlignment="Left" Margin="10,54,0,0" VerticalAlignment="Top" Width="75" Style="{DynamicResource ButtonStyle1}"/>
</Grid>
</Window>
I am attempting to implement HotTracking for a tab control in Wpf. My understanding is this was not included in the wpf tabcontrol and I would like to use it.
For my benefit HotTracking = When mouseover an unselected tab the tab will change color(usually to something between selected and not selected)
I used a bit of my own knowledge and this post How to set MouseOver event/trigger for border in XAML? but I can't seem to make it work.
This is everything.
<Window x:Class="TestingWpF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="1024" Width="1280">
<Window.Resources>
<Style TargetType="{x:Type TabItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid>
<Border
Name="Border"
CornerRadius="6,6,0,0" >
<ContentPresenter x:Name="ContentSite"
VerticalAlignment="Center"
HorizontalAlignment="Center"
ContentSource="Header"
Margin="12,2,12,2"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Border" Property="Background" Value="LightBlue" />
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter TargetName="Border" Property="Background" Value="AliceBlue" />
</Trigger>
<Trigger Property=" Border.IsMouseOver" Value="True">
<Setter Property="Border.Background" Value="Green" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<TabControl Grid.ColumnSpan="2" Grid.RowSpan="2" Height="309" HorizontalAlignment="Left" Name="tabControl1" VerticalAlignment="Top" Width="781" Padding="0">
<TabItem Header="tabItem1" >
</TabItem>
<TabItem Header="tabItem2" >
</TabItem>
</TabControl>
</Grid>
</Window>
I figured it out, my problem was this section
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Border" Property="Background" Value="LightBlue" />
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter TargetName="Border" Property="Background" Value="AliceBlue" />
</Trigger>
<Trigger Property=" Border.IsMouseOver" Value="True">
//Change this line
//<Setter Property="Border.Background" Value="Green" />
//To This
<Setter TargetName="Border" Property="Background" Value="Green" />
</Trigger>
The last Trigger was the one not working. And if you notice I used different properties in the setter. I changesd it to match the other two and it worked