I have a page that gets a datacontext objet in the behind code.
I would like to set an empty value to the TextList[11] when the Trigger variable loses the 1 value. The Trigger "int" and the TextList "ObservableCollection" are booth situated in the Datacontext object. The TextList is initialized 20pcs element before set the page datacontext. I have to solve it in wpf code, code behind excluded. My English is pretty poor, sorry!
<Page x:Class="LayerTemplates.Templates.example"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:LayerTemplates.Templates"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
Title=""
xmlns:System="clr-namespace:System;assembly=mscorlib">
<Page.Resources>
<DataTemplate x:Key="myDataTemplate" DataType="{x:Type System:String}">
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=Trigger}" Value="1">
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<StringAnimationUsingKeyFrames Storyboard.TargetName="Page.DataContext" Storyboard.TargetProperty="TextList[11]" Duration="1">
<DiscreteStringKeyFrame KeyTime="0" Value=""></DiscreteStringKeyFrame>
</StringAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</Page.Resources>
<Grid>
...
</Grid>
If you just want to hide a text box or label try to use style triggers instead. As you are setting the value of a string to an empty value I think you might be able to use Visibility="Hidden".
In this example I hide the the label by default but whenever the MyIntProperty becomes 1 I change visibility to Visible.
My xaml code looks like this:
<Window x:Class="TestBinding.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<Label Content="{Binding MyTextProperty}">
<Label.Style>
<Style TargetType="Label">
<Setter Property="Visibility" Value="Hidden"/>
<Style.Triggers>
<DataTrigger Binding="{Binding MyIntProperty}" Value="1">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Label.Style>
</Label>
</Grid>
Data binding class and codebehind looks like this:
public class MyViewModel
{
public int MyIntProperty { get; set; } = 1;
public string MyTextProperty { get; set; } = "This is my text";
}
public partial class MainWindow : Window
{
MyViewModel model;
public MainWindow()
{
InitializeComponent();
model = new MyViewModel();
this.DataContext = model;
}
}
Note that in order to get the visibility to update automatically you have let the view model class implement INotifyPropertyChanged for the MyIntProperty.
Related
I am not successful at getting my DataTrigger to work for binding to enum.
Each line in the ListBox is 'S', just as in the default Setter
XAML:
<Window x:Class="BindToEnumTest.MainWindow"
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:BindToEnumTest"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<ListBox Grid.Column="0" x:Name="LBMain" ItemsSource="{Binding}" ScrollViewer.VerticalScrollBarVisibility="Auto">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Grid.Column="0" x:Name="TxtType">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Text" Value="S" />
<Style.Triggers>
<DataTrigger Binding="{Binding Type}" Value="TypeEnum.User">
<Setter Property="Text" Value="U"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Window>
Code:
namespace BindToEnumTest
{
public enum TypeEnum { None, System, User }
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public Collection<TypeEnum> TypeList = new() { TypeEnum.System, TypeEnum.User, TypeEnum.System, TypeEnum.User };
public MainWindow()
{
InitializeComponent();
LBMain.DataContext = TypeList;
}
}
}
I have tried using 'TypeEnum.User' and 'User' in the DataTrigger - no help.
Using Text="{Binding}" in the TextBlock shows 'User' and 'System' in the ListBox, so it seems to be getting the data.
How can I change this trigger to function?
A TypeEnum instance has no Type property, hence the Binding must not specify a property path:
<DataTrigger Binding="{Binding}" Value="{x:Static local:TypeEnum.User}">
Or with built-in type conversion from string to enum:
<DataTrigger Binding="{Binding}" Value="User">
I am trying to turn on or off a style at runtime using a Toggle Switch.
I have added the style to a resource dictionary but im not sure how to make some C# code to load or unload the resource. All of my buttons are using a dynamic resource of "PassiveGlowButton" and when i use a toggle switch i would like it to remove the "PassiveGlowButton" so its using the style of "GlowButton"
The code behind "GlowButton" This is the code i want to apply when the toggle is on. This is in App.Xaml under Application.resources, resourceDictionary:
<ResourceDictionary>
<Style x:Key="GlowButton" TargetType="{x:Type Button}"
BasedOn="{StaticResource AccentedSquareButtonStyle}">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect ShadowDepth="5" Color="WhiteSmoke" BlurRadius="18"/>
</Setter.Value>
</Setter>
<Style.Triggers>
<EventTrigger RoutedEvent="Button.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="Effect.ShadowDepth"
From="3.0" To="0.0" Duration="0:0:1"
AutoReverse="True" RepeatBehavior="Forever"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<!-- Mouse over glow -->
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="Effect.BlurRadius"
From="45.0" To="17.0" Duration="0:0:1"
AutoReverse="True" RepeatBehavior="Forever"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="Effect.BlurRadius"
From="15.0" To="15.0" Duration="0:0:1"
AutoReverse="True" RepeatBehavior="Forever"/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
Update
I have been able to set the style using a button but it will only apply to a button called Testbttn. Is there a way to change it to apply to Button.Style? If i use this method it also looses the storyboard of the button for some reason
Style style = this.FindResource("PassiveGlowButton") as Style;
TestBttn.Style = style;
Update 2: The solution was to create 3 styles, one the button uses from load and then 2 others, one with a blank button and one with the style i wanted.
I have attached the code i used to swap between the styles.
private void ButtonStyle_Checked(object sender, RoutedEventArgs e)
{
Application.Current.Resources["PassiveGlowButton"] = Application.Current.Resources["PassiveGlowButtonOn"];
}
private void ButtonStyle_UnChecked(object sender, RoutedEventArgs e)
{
Application.Current.Resources["PassiveGlowButton"] = Application.Current.Resources["PassiveGlowButtonOff"];
}
There are several ways of doing this.
What you're asking may be best redesigned to use VisualStateManager.
Another option is redesigning the styles into a StyleViewModel. (I recommend using a enum and typing your styles so that the VM can live / reference separate from the styles themselves) If you do this properly you can change the style type and the styles binding will update.
Finally you can use DynamicResource as the style and make a default style resource that's set else where. Styles, when used as a resource, can have the same key in separate dictionaries. The names overlapped so the last one in (or closest to the control requesting it in the hierarchy) will be the one to get used. You can re-arrange the style order or add / remove them but the controls won't update until the next time they are loaded.
Each is a little tricky to implement and although I like VisualStateManager I'm a fan of the binding fix (option 2) myself. There's a difference between the two; so I don't want this to confuse you or start a debate. I'm just illustrating options.
Here's a quick example of binding styles if you do prefer to go that route which will fix your problem IMO.
Example:
Styles
<Application x:Class="Question_Answer_WPF_App.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<Style x:Key="StyleA"
TargetType="Button">
<Setter Property="Background"
Value="Green" />
<Setter Property="Height"
Value="40" />
<Setter Property="Margin"
Value="4" />
</Style>
<Style x:Key="StyleB"
TargetType="Button">
<Setter Property="Background"
Value="Blue" />
<Setter Property="Height"
Value="30" />
</Style>
</Application.Resources>
</Application>
Enum
namespace Question_Answer_WPF_App.ViewModels
{
public enum Styles
{
StyleA,
StyleB
}
}
ViewModel
using System.Windows.Input;
namespace Question_Answer_WPF_App.ViewModels
{
public class StylesViewModel : NotifyModel
{
private Styles selectedStyle;
public StylesViewModel()
{
SelectStyleCommand = new RelayCommand(SelectStyle);
}
public Styles SelectedStyle
{
get { return selectedStyle; }
set
{
selectedStyle = value;
Notify();
}
}
public ICommand SelectStyleCommand { get; }
private void SelectStyle(object obj)
{
if (obj is Styles style) SelectedStyle = style;
}
}
}
Converter
using Question_Answer_WPF_App.ViewModels;
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
namespace Question_Answer_WPF_App.Views
{
public class StyleTypeConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var result = Application.Current.Resources["StyleA"];
if (value is Styles style)
{
switch (style)
{
case Styles.StyleB:
result = Application.Current.Resources["StyleB"];
break;
case Styles.StyleA:
default:
result = Application.Current.Resources["StyleA"];
break;
}
}
return result;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
=> DependencyProperty.UnsetValue;
}
}
View
<UserControl x:Class="Question_Answer_WPF_App.Views.StylesTestView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ViewModels="clr-namespace:Question_Answer_WPF_App.ViewModels"
xmlns:local="clr-namespace:Question_Answer_WPF_App.Views">
<UserControl.Resources>
<ViewModels:StylesViewModel x:Key="StylesViewModel" />
<local:StyleTypeConverter x:Key="StyleTypeConverter" />
</UserControl.Resources>
<StackPanel>
<Button Style="{Binding SelectedStyle, Source={StaticResource StylesViewModel}, Converter={StaticResource StyleTypeConverter}}"
Command="{Binding SelectStyleCommand, Source={StaticResource StylesViewModel}}"
CommandParameter="{x:Static ViewModels:Styles.StyleA}"
Content="Select Style A" />
<Button Style="{Binding SelectedStyle, Source={StaticResource StylesViewModel}, Converter={StaticResource StyleTypeConverter}}"
Command="{Binding SelectStyleCommand, Source={StaticResource StylesViewModel}}"
CommandParameter="{x:Static ViewModels:Styles.StyleB}"
Content="Select Style B" />
</StackPanel>
</UserControl>
Results
This is my xaml code:
<UserControl x:Class="UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<Style TargetType="TextBox" xmlns:sys="clr-namespace:System;assembly=mscorlib">
<Style.Resources>
<VisualBrush x:Key="CueBannerBrush" AlignmentX="Left" AlignmentY="Center" Stretch="None">
<VisualBrush.Visual>
<Label Content="{Binding Path=CueBannerText}" 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>
</UserControl.Resources>
<Grid>
<TextBox TextWrapping="Wrap"/>
</Grid>
</UserControl>
I want to bind set the Label Content by code if I call the control in my project. The way I do it is like this:
Public Class UserControl1
Public Property CueBannerText As String
Get
Return _oText
End Get
Set(value As String)
_oText = value
End Set
End Property
Private _oText As String = "Search"
Public Sub New()
InitializeComponent()
Me.DataContext = Me
End Sub
End Class
If I call my control in the code With this:
<Window x:Class="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"
xmlns:Noru="clr-namespace:NoruTextBox;assembly=NoruTextBox">
<Grid>
<Noru:UserControl1></Noru:UserControl1>
</Grid>
</Window>
my control won't show 'Search' as the TextBox isn't selected or contains anything.
To do what you want, you'll either need to implement the INotifyPropertyChanged Interface in your UserControl code behind, or declare a DependencyProperty instead:
Public Shared CueBannerTextProperty As DependencyProperty = DependencyProperty.
Register("CueBannerText", GetType(String), GetType(TestView),
New PropertyMetadata("Search"))
Public Property CueBannerText() As String
Get
Return DirectCast(GetValue(CueBannerTextProperty), String)
End Get
Set
SetValue(CueBannerTextProperty, value)
End Set
End Property
Disclaimer: I just converted this to VB using an online converter, so I can't confirm its correctness.
Using a DependencyProperty will also enable you to set this value in a Style, Animation (unlikely in this situation), or a Binding:
<Noru:UserControl1 CueBannerText="{Binding SomeValue}" />
Okay! I did a big edition :)
In a UserControl, I need to use interactions DataTrigger like below. The reason for is that I need a storyboard (MyStory) with a bound key-frame value. (Doing so was discussed here before.)
<UserControl x:Class="WpfApplication1.UserControl2"
...
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
xmlns:local="clr-namespace:WpfApplication1">
<UserControl.Resources>
<Style x:Key="MyControlStyle" TargetType="UserControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid>
<Grid.Resources>
<Storyboard x:Key="MyStory">
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="brdBase">
<SplineColorKeyFrame KeyTime="0:0:1" Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:UserControl2}}, Path=SpecialColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</Grid.Resources>
<Border x:Name="brdBase" BorderThickness="1" BorderBrush="Gray">
<TextBox Text="{Binding SpecialText}"/>
</Border>
<i:Interaction.Triggers>
<ei:DataTrigger Binding="{Binding SpecialText}" Value="Fire!">
<ei:ControlStoryboardAction Storyboard="{StaticResource MyStory}" ControlStoryboardOption="Play"/>
</ei:DataTrigger>
</i:Interaction.Triggers>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Grid x:Name="grdRoot" DataContext="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:UserControl2}}}">
<UserControl Style="{DynamicResource MyControlStyle}"/>
</Grid>
</UserControl>
C# code behind:
public partial class UserControl2 : UserControl
{
#region ________________________________________ SpecialColor
public Color SpecialColor
{
get { return (Color)GetValue(SpecialColorProperty); }
set { SetValue(SpecialColorProperty, value); }
}
public static readonly DependencyProperty SpecialColorProperty =
DependencyProperty.Register("SpecialColor",
typeof(Color),
typeof(UserControl2),
new FrameworkPropertyMetadata(Colors.Red));
#endregion
#region ________________________________________ SpecialText
public string SpecialText
{
get { return (string)GetValue(SpecialTextProperty); }
set { SetValue(SpecialTextProperty, value); }
}
public static readonly DependencyProperty SpecialTextProperty =
DependencyProperty.Register("SpecialText",
typeof(string),
typeof(UserControl2),
new FrameworkPropertyMetadata(string.Empty));
#endregion
public UserControl2()
{
InitializeComponent();
}
}
I expect the above code to play MyStory right after SpecialText set to "Fire!". To do so, we can use one of the following ways:
1.
<Grid>
<local:UserControl2 SpecialText="Fire!"/>
</Grid>
2. Typing "Fire!" in the UserControl2 text-box at run-time.
The first way doesn't affect on GUI at design-time. I have some complicated UserControls in my app and really need to solve this issue. There are some DPs that call a storyboard to change layout of the UserControl animatedly. Obviously these storyboards involved with one or more bound key-frames. So I must run my app more and more to check it :(
I have a typical MVVM scenario:
I have a ListBox that is binded to a List of StepsViewModels.
I define a DataTemplate so that StepViewModels are rendered as StepViews.
The StepView UserControl have a set of labels and TextBoxs.
What I want to do is to select the ListBoxItem that is wrapping the StepView when a textBox is focused. I've tried to create a style for my TextBoxs with the following trigger:
<Trigger Property="IsFocused" Value="true">
<Setter TargetName="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}}" Property="IsSelected" Value="True"/>
</Trigger>
But I get an error telling me that TextBoxs don't have an IsSelected property. I now that but the Target is a ListBoxItem.
How can I make it work?
There is a read-only property IsKeyboardFocusWithin that will be set to true if any child is focused. You can use this to set ListBoxItem.IsSelected in a Trigger:
<ListBox ItemsSource="{Binding SomeCollection}" HorizontalAlignment="Left">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Style.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="IsSelected" Value="True" />
</Trigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBox Width="100" Margin="5" Text="{Binding Name}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
As Jordan0Day correctly pointed out there can be indeed big problems using IsKeyboardFocusWithin solution. In my case a Button in a Toolbar which regards to the ListBox was also not working anymore. The same problem with focus. When clicking the button the ListBoxItem does loose the Focus and the Button updated its CanExecute method, which resulted in disabling the button just a moment before the button click command should be executed.
For me a much better solution was to use a ItemContainerStyle EventSetter as described in this post: ListboxItem selection when the controls inside are used
XAML:
<Style x:Key="MyItemContainer.Style" TargetType="{x:Type ListBoxItem}">
<Setter Property="Background" Value="LightGray"/>
<EventSetter Event="GotKeyboardFocus" Handler="OnListBoxItemContainerFocused" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border x:Name="backgroundBorder" Background="White">
<ContentPresenter Content="{TemplateBinding Content}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="backgroundBorder" Property="Background" Value="#FFD7E6FC"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
EventHandler in the code behind of the view:
private void OnListBoxItemContainerFocused(object sender, RoutedEventArgs e)
{
(sender as ListBoxItem).IsSelected = true;
}
One way to achieve that is by implementing a custom behavior using an attached property. Basically, the attached property would be applied to the ListBoxItem using a style, and would hook up to their GotFocus event. That even fires if any descendant of the control gets the focus, so it is suitable for this task. In the event handler, IsSelected is set to true.
I wrote up a small example for you:
The Behavior Class:
public class MyBehavior
{
public static bool GetSelectOnDescendantFocus(DependencyObject obj)
{
return (bool)obj.GetValue(SelectOnDescendantFocusProperty);
}
public static void SetSelectOnDescendantFocus(
DependencyObject obj, bool value)
{
obj.SetValue(SelectOnDescendantFocusProperty, value);
}
public static readonly DependencyProperty SelectOnDescendantFocusProperty =
DependencyProperty.RegisterAttached(
"SelectOnDescendantFocus",
typeof(bool),
typeof(MyBehavior),
new UIPropertyMetadata(false, OnSelectOnDescendantFocusChanged));
static void OnSelectOnDescendantFocusChanged(
DependencyObject d, DependencyPropertyChangedEventArgs e)
{
ListBoxItem lbi = d as ListBoxItem;
if (lbi == null) return;
bool ov = (bool)e.OldValue;
bool nv = (bool)e.NewValue;
if (ov == nv) return;
if (nv)
{
lbi.GotFocus += lbi_GotFocus;
}
else
{
lbi.GotFocus -= lbi_GotFocus;
}
}
static void lbi_GotFocus(object sender, RoutedEventArgs e)
{
ListBoxItem lbi = sender as ListBoxItem;
lbi.IsSelected = true;
}
}
The Window XAML:
<Window x:Class="q2960098.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="MainWindow" Height="350" Width="525" xmlns:my="clr-namespace:q2960098">
<Window.Resources>
<DataTemplate x:Key="UserControlItemTemplate">
<Border BorderBrush="Black" BorderThickness="5" Margin="10">
<my:UserControl1/>
</Border>
</DataTemplate>
<XmlDataProvider x:Key="data">
<x:XData>
<test xmlns="">
<item a1="1" a2="2" a3="3" a4="4">a</item>
<item a1="a" a2="b" a3="c" a4="d">b</item>
<item a1="A" a2="B" a3="C" a4="D">c</item>
</test>
</x:XData>
</XmlDataProvider>
<Style x:Key="MyBehaviorStyle" TargetType="ListBoxItem">
<Setter Property="my:MyBehavior.SelectOnDescendantFocus" Value="True"/>
</Style>
</Window.Resources>
<Grid>
<ListBox ItemTemplate="{StaticResource UserControlItemTemplate}"
ItemsSource="{Binding Source={StaticResource data}, XPath=//item}"
HorizontalContentAlignment="Stretch"
ItemContainerStyle="{StaticResource MyBehaviorStyle}">
</ListBox>
</Grid>
</Window>
The User Control XAML:
<UserControl x:Class="q2960098.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UniformGrid>
<TextBox Margin="10" Text="{Binding XPath=#a1}"/>
<TextBox Margin="10" Text="{Binding XPath=#a2}"/>
<TextBox Margin="10" Text="{Binding XPath=#a3}"/>
<TextBox Margin="10" Text="{Binding XPath=#a4}"/>
</UniformGrid>
</UserControl>
If you create a User Control and then use it as the DataTemplate It seems to work cleaner.
Then you don't have to use the dirty Style Triggers that Don't work 100% of the time.
Edit: Someone else already had the same answer on a different question: https://stackoverflow.com/a/7555852/2484737
Continuing on Maexs' answer, using an EventTrigger instead of an EventSetter removes the need for code-behind:
<Style.Triggers>
<EventTrigger RoutedEvent="GotKeyboardFocus">
<BeginStoryboard>
<Storyboard >
<BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="IsSelected" >
<DiscreteBooleanKeyFrame Value="True" KeyTime="0:0:0"/>
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>