I have defined a datatemplate that has a trigger that should simply change the background color if the item is selected. For some reason it doesn't seem to be working.
<DataTemplate x:Key="existingDeviceTemplate" >
<StackPanel Orientation="Horizontal">
<Border Name="bd" Background="Green" BorderThickness="1" Padding="5">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Path=Name}" Width="200"/>
<Button Grid.Column="1" Content="Settings" Click="cmdSettings_Clicked"/>
<Button Grid.Column="2" Content="Delete" Click="cmdDelete_Clicked"/>
</Grid>
</Border>
</StackPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsSelected}" Value="true" >
<Setter TargetName="bd" Property="Background" Value="Red"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
Try to bind to the IsSelected property of the ListBoxItem:
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}" Value="true">
<Setter TargetName="bd" Property="Background" Value="Red" />
</DataTrigger>
</DataTemplate.Triggers>
If your list control is a ListView you have to replace x:Type ListBoxItem with x:Type ListViewItem.
Does your binded model had a property named IsSelected?
my guess is that you mean the rows' IsSelected property.
If thats the case you need to put a RelativeSource binding with FindAncestor to the ListItem
Related
The following xaml code is the four resources I am using. I want to merge two style resources and two data templates into a style resource and a data template, respectively. It would be very happy if all of them could be merged into one resource.
Thanks for help!
<Style x:Key="ServiceStatusImageStyle" TargetType="{x:Type Image}">
<Style.Triggers>
<DataTrigger Binding="{Binding ServiceStatus}" Value="true">
<Setter Property="Source" Value="/Resources/Images/StartedService.png"/>
</DataTrigger>
<DataTrigger Binding="{Binding ServiceStatus}" Value="false">
<Setter Property="Source" Value="/Resources/Images/StopedService.png"/>
</DataTrigger>
</Style.Triggers>
</Style>
<Style x:Key="DrawModeImageStyle" TargetType="{x:Type Image}">
<Style.Triggers>
<DataTrigger Binding="{Binding bScrollViewMode}" Value="true">
<Setter Property="Source" Value="/Resources/Images/scrollview24.png"/>
</DataTrigger>
<DataTrigger Binding="{Binding bScrollViewMode}" Value="false">
<Setter Property="Source" Value="/Resources/Images/zoomview24.png"/>
</DataTrigger>
</Style.Triggers>
</Style>
<DataTemplate x:Key="ServiceStatusDataTemplate" DataType="{x:Type local:MainWindowViewModel}">
<Grid Width="220" Height="60">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="35"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Width="30" Height="30" Margin="5,0,0,0" Style="{StaticResource ServiceStatusImageStyle}"/>
<TextBlock Grid.Column="1" FontSize="25" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5,0,0,0"
Foreground="White" Text="{Binding ServiceStatusString}">
</TextBlock>
</Grid>
</DataTemplate>
<DataTemplate x:Key="DrawModeDataTemplate" DataType="{x:Type local:MainWindowViewModel}">
<Grid Width="220" Height="60">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="35"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Width="30" Height="30" Margin="5,0,0,0" Style="{StaticResource DrawModeImageStyle}"/>
<TextBlock Grid.Column="1" FontSize="25" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5,0,0,0"
Foreground="White" Text="{Binding ViewModeName}">
</TextBlock>
</Grid>
</DataTemplate>
I want to select dynamically a ControlTemplate based on a Property of a ViewModel. How do I achieve it.
I have 2 ControlTemplates in the View, and a boolean property on a ViewModel. Based on that property, I have to select and display one of my ControlTempale in the View.
<Window.Resources>
<ControlTemplate x:Key="simpleErrorTemplate">
<TextBox Margin="10,10,10,5" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" Text="T1" />
</ControlTemplate>
<ControlTemplate x:Key="detailedErrorTemplate">
<StackPanel>
<TextBox Margin="10,10,10,5" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" Text="T2" />
<TextBox Margin="10,10,10,5" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" Text="T3" />
<TextBox Margin="10,10,10,5" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" Text="T4" />
</StackPanel>
</ControlTemplate>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="50" />
</Grid.RowDefinitions>
<ContentControl Grid.Row="0" DataContext="{Binding Report}">
<ContentControl.Style>
<Style TargetType="ContentControl">
<Setter Property="Template" Value="{StaticResource simpleErrorTemplate}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsTyping}" Value="True">
<Setter Property="Template" Value="{StaticResource detailedErrorTemplate}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
<CheckBox Margin="10,0,0,0" Grid.Row="1" x:Name="ChkShowDetails" IsChecked="{Binding IsTyping, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">Show Details</CheckBox>
</Grid>
So based on the value of IsTyping, I want to display my ControlTemplate.
If I directly bind the element to the Control template, it will work, but this is not my requirement.
Bind the data trigger to the correct DataContext, i.e. the same that the CheckBox is bound to:
<DataTrigger Binding="{Binding DataContext.IsTyping, RelativeSource={RelativeSource AncestorType=ContentControl}}" Value="True">
<Setter Property="Template" Value="{StaticResource detailedErrorTemplate}"/>
</DataTrigger>
I think you can do something much simpler
What you need it to use the ContentControl's ContentTemplateSelector to achieve what you want.
The ContentTemplateSelector is a custom class that will switch the template depending on your data.
This will give you the idea : http://www.wpftutorial.net/datatemplates.html
I have a problem with nested template bindings.
Having an ItemsControl with a template, which works great. This template contains a tooltip as well (which shows perfectly).
<Button.ToolTip>
<TextBlock Text="{Binding Path=DetailPaneText}" />
</Button.ToolTip>
But inside the itemscontrol template, I have a ToggleButton with another template inside it. And I can't seem to show the text over there as well since the binding isn't correct.
Code inside the toggle button
<StackPanel Background="#293344" Width="200" x:Name="DetailTab" Margin="0">
<TextBlock FontSize="12" Text="" Foreground="White" />
</StackPanel>
What kind of binding or syntax should I put in between the Text tags? I tried several options but none of them seemed to work yet. Currently out of guesses.
Thanks
Complete code snippet
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="0" >
<Button Command="{x:Static CobraInfrastructure:Commands.NavigateFromBreadcrumb}" CommandParameter="{Binding Path=Current}" Tag="{Binding DetailPaneText}" x:Name="TextBlock_Detail" Style="{DynamicResource BreadcrumbButton}">
<Button.Resources>
<Style BasedOn="{StaticResource {x:Type ToolTip}}" TargetType="ToolTip">
<Setter Property="Background" Value="#F8F8F8" />
<Setter Property="BorderBrush" Value="{x:Null}" />
<Setter Property="Padding" Value="15" />
<Setter Property="MinWidth" Value="300" />
<Setter Property="MinHeight" Value="150" />
<Setter Property="VerticalAlignment" Value="Top" />
</Style>
</Button.Resources>
<Button.ToolTip>
<TextBlock Text="{Binding Path=DetailPaneText}" />
</Button.ToolTip>
<Grid Margin="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<TextBlock x:Name="HyphenTextBlock" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Text="{Binding Path=EntityTitle}" FontSize="12" FontWeight="Bold" Foreground="White" Grid.Row="0" Grid.Column="0"/>
<TextBlock VerticalAlignment="Stretch" Text="{Binding Path=Text, NotifyOnTargetUpdated=True, Mode=OneWay}" FontSize="10" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"/>
</Grid>
</Button>
<ToggleButton Focusable="False" Style="{DynamicResource BreadcrumbOpenButton}" VerticalAlignment="Stretch" HorizontalAlignment="Center" Tag="{Binding Path=DetailPaneText}">
<ToggleButton.Template>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<StackPanel Orientation="Horizontal">
<Border Width="13" Background="#293344">
<fa:FontAwesome Icon="CaretRight" Foreground="White" FontSize="18" VerticalAlignment="Center" HorizontalAlignment="Center" />
</Border>
<StackPanel Background="#293344" Width="200" x:Name="DetailTab" Margin="0">
<TextBlock FontSize="12" Text="" Foreground="White" />
</StackPanel>
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Width" TargetName="DetailTab" Value="200"/>
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter Property="Width" TargetName="DetailTab" Value="1"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</ToggleButton.Template>
</ToggleButton>
</StackPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsVisible}" Value="False">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
<DataTrigger Binding="{Binding IsOverview}" Value="True">
<Setter Property="Style" TargetName="TextBlock_Detail" Value="{DynamicResource LinkButton}" />
<Setter Property="FontWeight" TargetName="TextBlock_Detail" Value="Bold" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
You should reference on TemplatedParent in Binding:
<StackPanel Background="#293344" Width="200" x:Name="DetailTab" Margin="0">
<TextBlock FontSize="12" Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DataContext.DetailPaneText}" Foreground="White" />
</StackPanel>
If you trying to bind a tooltip text of a button to the Text property of textblock, you may bind it using the ElementName.
First name your button using x:Name
<Button x:Name="XButton">
<Button.ToolTip>
<TextBlock Text="{Binding Path=DetailPaneText}" />
</Button.ToolTip>
</Button>
Bind it to text block text using the ElementName.
<StackPanel Background="#293344" Width="200" x:Name="DetailTab" Margin="0">
<TextBlock FontSize="12" Text="{Binding ElementName=XButton, Path=ToolTip.Text}" />
</StackPanel>
The thing I want to make When mouseover in grid Border Visibilty property value must change.
I have a grid with a 3 ColumnDefinition.
The code is
<Grid x:Name="grid1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5*"/>
<ColumnDefinition Width="27*"/>
<ColumnDefinition Width="93*"/>
</Grid.ColumnDefinitions>
<Border Grid.Column="0" Background="Blue" Visibility="Hidden">
<Border.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding IsMouseOver , RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Grid}}}" Value="True">
<Setter Property="Border.Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
<Image Grid.Column="1" />
<TextBlock Grid.Column="2" />
</Grid>
When mouseover the grid nothing is happen.so This codes not working
one thing is that you should not use IsReadOnly property in DataTrigger when MouseOver is required.
another one is that local value Visibility="Hidden" has higher priority than DataTrigger setter <Setter Property="Border.Visibility" Value="Visible" /> and will not be changed even if condition is true
a fix for both (initial value of Visibility is defined in a setter)
<Border Grid.Column="0" Background="Blue">
<Border.Style>
<Style>
<Setter Property="Border.Visibility" Value="Hidden" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Grid}}}" Value="False">
<Setter Property="Border.Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
you should also set Grid Background to non-null value (e.g. <Grid x:Name="grid1" Background="Transparent">) for mouse movements to be registered in grid ({x:Null} vs. Transparent?)
When I bind my collection to the following window and usercontrol, the styles do not work.
When I press a button on the window, the styles kick in.
What is stopping my styles from firing at initial bind?
<Grid>
<ItemsControl Name="LbItems" ItemsSource="{Binding MyData}">
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type viewModel:SomeViewModel}">
<control:SomeView Margin="5" />
</DataTemplate>
<DataTemplate DataType="{x:Type viewModel:AnotherViewModel}">
<control:AnotherView Margin="5" />
</DataTemplate>
</ItemsControl.Resources>
</ItemsControl>
</Grid>
And I have a user control as follows:
<UserControl.Resources>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={x:Static
RelativeSource.Self}, Path=DataContext.Selected}" Value="False">
<Setter Property="Foreground">
<Setter.Value>
Red
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={x:Static
RelativeSource.Self}, Path=DataContext.Selected}" Value="True">
<Setter Property="Foreground">
<Setter.Value>
DarkSeaGreen
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</UserControl.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Button Command="{Binding SelectCommand}" Content="+" HorizontalAlignment=
"Left" VerticalAlignment="Top" Width="25" Grid.Column="0"/>
<TextBlock HorizontalAlignment="Left" Margin="5" TextWrapping="Wrap" Text=
"{Binding Endorsement.Name}" VerticalAlignment="Top" Grid.Column="1" />
<Button Command="{Binding DeselectCommand}" Content="-" HorizontalAlignment=
"Right" VerticalAlignment="Top" Width="25" Grid.Column="2"/>
</Grid>
When the page loads and when the 'Selected' is set is two different times; hence selected is null when the page loads and nothing happens. Anticipate the null situation such as an added style
<DataTrigger Binding="{Binding RelativeSource={x:Static
RelativeSource.Self}, Path=DataContext.Selected}" Value="{x:Null}">
...
You shouldn't have to do this in your DataTrigger binding:
Binding="{Binding RelativeSource={x:Static
RelativeSource.Self}, Path=DataContext.Selected}"
A binding by default is referencing the DataContext so the equivalent simpler form is this:
Binding="{Binding Path=Selected}"
I don't think that will solve your problem though (but if it does that's great). One way around it is to define a default value in the style for your Foreground if neither trigger fires:
<UserControl.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="Red" />
<Style.Triggers>
...
This assumes that all your items are deselected upon load. Hope this helps.
Cheers,
Eric