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/>
Related
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>
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 /MVVM Pattern
User control with multiple textboxes using validation attributes.
In the following style, everything works as intended- EXCEPT for those with a validation error, the Focused backcolor is not being set, due to the method used in the control template to set the error image.
If I remove the control template, the backcolor is set properly when focused if the validation error is set. With the template, backcolor is always white/default.
Any suggestions on the XAML required to have both - different backcolor when focused and the error image when validation fails?
<Style TargetType="{x:Type TextBox}">
<Setter Property="Margin" Value="1" />
<Setter Property="ToolTip" Value="{Binding Description}"/>
<Style.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Background" Value="LightYellow"/>
</Trigger>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors).CurrentItem.ErrorContent}"/>
<!--adds the error image and border, but also prevents background color change OnFocus-->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid>
<Border
BorderBrush="#d99" x:Name="textBorder" CornerRadius="4"
BorderThickness="2" >
<ScrollViewer Margin="0" x:Name="PART_ContentHost"/>
</Border>
<Image Name="ErrorImage" Width="24" Height="24" Margin="0,0,4,0"
Source="/Images/error.png" HorizontalAlignment="Right">
</Image>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
You should check out the DependencyProperty precedence rules
What happens here is that the ControlTemplate you define overrides the Style.Triggers defined just before.
What you can do to make it work is to set the actual Style with appropriate Triggers directly inside of the ControlTemplate
Otherwise, as you've seen, WPF will just use the default template for a Grid.
The code should look like that:
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors).CurrentItem.ErrorContent}"/>
<!--adds the error image and border, but also prevents background color change OnFocus-->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid>
<Grid.Style>
<Style TargetType="{x:Type Grid}">
<Style.Triggers>
<!-- The trigger about IsFocused should be here!
<Trigger Property="IsFocused" Value="True">
<Setter Property="Background" Value="LightYellow"/>
</Trigger>
</Style.Triggers>
</Style>
</Grid.Style>
<Border
BorderBrush="#d99" x:Name="textBorder" CornerRadius="4"
BorderThickness="2" >
<ScrollViewer Margin="0" x:Name="PART_ContentHost"/>
</Border>
<Image Name="ErrorImage" Width="24" Height="24" Margin="0,0,4,0"
Source="/Images/error.png" HorizontalAlignment="Right">
</Image>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
I want to change the color of a MenuItem at mouseOver. I need also rounded borders, an image and a textBox. When I set the style all is ok only the mouseOverEvent is doing anything, the background doesnot change. My code is:
<Style x:Key="BaseStyle" TargetType="MenuItem">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" Value="#0a99f3" />
</Trigger>
<Trigger Property="IsKeyboardFocusWithin" Value="true">
<Setter Property="Background" Value="#0a99f3" />
</Trigger>
</Style.Triggers>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
<Grid>
<Border Name="MainBorder" BorderThickness="2,2,2,0" CornerRadius="8,8,8,8" Margin="0,0,1,0" BorderBrush="AliceBlue">
<Grid>
<TextBlock Text="Info" Margin="30,10,0,0" FontFamily="Arial" FontSize="14" FontWeight="Bold" />
<Image Width="15" Height="15" Source="menu.PNG" Margin="-100,0,0,0" />
</Grid>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Hope anybody know what I am missing. Thanks!
You're overwritting the Template, but not using the Background Color anywhere in it so the value never gets applied.
Set the Background Color in your MenuItem Template
<ControlTemplate TargetType="{x:Type MenuItem}">
<Grid Background="{TemplateBinding Background}">
You are not binding the Background anywhere in your template so changing that property has no effect.
I know the question sounds a little strange, but I'd like to change the opacity of all the items not selected in an ItemsControl. In other words, I'd like to make more "visible" the selected item, showing the others item more "obfuscated".
I have a custom control "MyCustomControl" derived from ItemsControl, where each item is an instance of a class "MyObject".
I made a style for my custom control where I set the ItemTemplate to be an Image with Source property bound to the property "LargeImage" of "MyObject".
Here comes the problem. When I select an item I'd like to set the opacity of the others element, but I haven't found a way!
Here's my (simplified) XAML code:
<Style TargetType="{x:Type MyCustomControl}" x:Key="MyStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ui:MyCustomControl}">
<Border Height="{TemplateBinding Height}" Width="Auto" Background="{TemplateBinding Background}">
<ItemsPresenter VerticalAlignment="Center" IsHitTestVisible="True"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"></StackPanel>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<Grid>
<Button>
<Image Source="{Binding Path=LargeImage}" Stretch="Uniform"/>
</Button>
</Grid>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
I think a very simple solution would be adding a trigger to the data template that uses the "IsSelected" property, using either a Trigger or a DataTrigger,something like that:
<DataTemplate.Triggers>
<Trigger Property="IsSelected" Value="False">
<Setter Property="Opacity" Value="Yourvalue"/>
</Trigger>
<DataTrigger Binding="{Binding IsSelected}" Value="False">
<Setter Property="Opacity" Value="Yourvalue"/>
</DataTrigger>
</DataTemplate.Triggers>
<ListBox>
<ListBox.ItemContainerStyle>
<Setter Property="IsSelected" Value="{Binding IsSelected}"/>
<Setter Property="Opacity" Value="{Binding IsSelected, Converter={StaticResource YourOpacityConverter}}"/>
</ListBox.ItemContainerStyle>
</ListBox>
The above shows how you could do this with a ListBox, just to avoid confusion with your own types. It assumes your data items (MyObject) have an IsSelected property and that you've put a converter resource in your visual tree somewhere.
You could forgo the converter and instead trigger a state change when IsSelected changes, but you get the idea.