I have problem with creating xaml control. I'm writing new project in VS 2015 in universal app. I want create grid. In this grid I want to have a button. In model I specifi the column (Level) and Row.
this is my code:
<ItemsControl Grid.Row="1" ItemsSource="{Binding Path=TechnologyList}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="10*"/>
<RowDefinition Height="10*"/>
<RowDefinition Height="10*"/>
<RowDefinition Height="10*"/>
<RowDefinition Height="10*"/>
<RowDefinition Height="10*"/>
<RowDefinition Height="10*"/>
<RowDefinition Height="10*"/>
<RowDefinition Height="10*"/>
<RowDefinition Height="10*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="14*"/>
<ColumnDefinition Width="14*"/>
<ColumnDefinition Width="14*"/>
<ColumnDefinition Width="14*"/>
<ColumnDefinition Width="14*"/>
<ColumnDefinition Width="14*"/>
<ColumnDefinition Width="14*"/>
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="Control">
<Setter Property="Grid.Column" Value="{Binding Level}" />
<Setter Property="Grid.Row" Value="{Binding Row}" />
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding Name}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
I get a error in line <Setter Property="Grid.Column" Value="{Binding Level}" />
The error: Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED) was in edytor not in running code.
What is wrong? In "old" WPF everything was OK but in Universal App for Windows 10 I have a error.
Can anyone help me ?
As noted in the section Migration notes on the Setter.Value property page on MSDN, UWP/Windows Runtime does not support bindings in Style Setters.
Windows Presentation Foundation (WPF) and Microsoft Silverlight
supported the ability to use a Binding expression to supply the Value
for a Setter in a Style. The Windows Runtime doesn't support a Binding
usage for Setter.Value (the Binding won't evaluate and the Setter has
no effect, you won't get errors, but you won't get the desired result
either). When you convert XAML styles from WPF or Silverlight XAML,
replace any Binding expression usages with strings or objects that set
values, or refactor the values as shared {StaticResource} markup
extension values rather than Binding-obtained values.
A workaround could be a helper class with attached properties for the source paths of the bindings. It creates the bindings in code behind in a PropertyChangedCallback of the helper property:
public class BindingHelper
{
public static readonly DependencyProperty GridColumnBindingPathProperty =
DependencyProperty.RegisterAttached(
"GridColumnBindingPath", typeof(string), typeof(BindingHelper),
new PropertyMetadata(null, GridBindingPathPropertyChanged));
public static readonly DependencyProperty GridRowBindingPathProperty =
DependencyProperty.RegisterAttached(
"GridRowBindingPath", typeof(string), typeof(BindingHelper),
new PropertyMetadata(null, GridBindingPathPropertyChanged));
public static string GetGridColumnBindingPath(DependencyObject obj)
{
return (string)obj.GetValue(GridColumnBindingPathProperty);
}
public static void SetGridColumnBindingPath(DependencyObject obj, string value)
{
obj.SetValue(GridColumnBindingPathProperty, value);
}
public static string GetGridRowBindingPath(DependencyObject obj)
{
return (string)obj.GetValue(GridRowBindingPathProperty);
}
public static void SetGridRowBindingPath(DependencyObject obj, string value)
{
obj.SetValue(GridRowBindingPathProperty, value);
}
private static void GridBindingPathPropertyChanged(
DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
var propertyPath = e.NewValue as string;
if (propertyPath != null)
{
var gridProperty =
e.Property == GridColumnBindingPathProperty
? Grid.ColumnProperty
: Grid.RowProperty;
BindingOperations.SetBinding(
obj,
gridProperty,
new Binding { Path = new PropertyPath(propertyPath) });
}
}
}
You would use them in XAML like this:
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="local:BindingHelper.GridColumnBindingPath" Value="Level"/>
<Setter Property="local:BindingHelper.GridRowBindingPath" Value="Row"/>
</Style>
</ItemsControl.ItemContainerStyle>
For a simple workaround for absolute positioning (i.e. binding the Canvas.Left and canvas.Top properties), see this answer.
Wanted to add my experience of this BindingHelper idea from #clemens. It's a neat solution but I found that when targetting a ListViewItem the binding wouldn't access the underlying view model. After debugging it, I found that I needed to make sure the binding was relative to the ListViewItem itself and the associated .Content property to enable it to correctly link to the item's view model.
My particular use case was to set the IsTabStop property of the ListViewItem based on a view model value:
private static void BindingPathPropertyChanged(DependencyObject obj,
DependencyPropertyChangedEventArgs e)
{
if (e.NewValue is string propertyPath)
{
var binding = new Binding
{
Path = new PropertyPath($"Content.{propertyPath}"),
Mode = BindingMode.OneWay,
RelativeSource = new RelativeSource
{
Mode = RelativeSourceMode.Self
}
};
BindingOperations.SetBinding(obj, Control.IsTabStopProperty, binding);
}
}
Hope this helps if anyone else has the problem.
Related
I am working on an application that creates textboxes/combo boxes dynamically based on if there is a single replacement for a keyword, or multiple replacements, and adds them to a stackpanel. I have ran into an issue where if the string that is being populated into the textbox is a single digit, ie: "2" the textbox is collapsed. Here is the associated DependencyProperty and constructor for the view model:
#region Properties
public ObservableCollection<string> KeywordValueList
{
get { return (ObservableCollection<string>)GetValue(_KeywordValueListProperty); }
set { SetValue(_KeywordValueListProperty, value); }
}
private static readonly DependencyProperty _KeywordValueListProperty = DependencyProperty.Register("KeywordValueList",
typeof(ObservableCollection<string>),
typeof(KeywordControlViewModel),
new PropertyMetadata(null, null));
public string KeywordValue
{
get { return (string)GetValue(_KeywordValueProperty); }
set { SetValue(_KeywordValueProperty, value); }
}
private static readonly DependencyProperty _KeywordValueProperty = DependencyProperty.Register("KeywordValue",
typeof(string),
typeof(KeywordControlViewModel),
new PropertyMetadata(null, null));
#endregion
#region Constructors
public KeywordControlViewModel(string keyword, object keywordValue)
{
Keyword = keyword;
if (keywordValue is string)
{
KeywordValue = (string)keywordValue;
KeywordValueList = null;
}
else if (keywordValue is ICollection)
{
KeywordValue = null;
ObservableCollection<string> toSet = new ObservableCollection<string>(keywordValue as List<string>);
KeywordValueList = toSet;
}
else
{
KeywordValue = "-Not Set-";
KeywordValueList = null;
}
}
#endregion
This is the relevant portion of the xaml:
<Grid HorizontalAlignment="Stretch">
<Grid.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../Styles/ControlsStyle.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="180" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="25" />
</Grid.RowDefinitions>
<!-- Labels etc on Row 0, generating properly so omitting for space-->
<TextBox Name ="KeyWordTextBox"
Style="{StaticResource InputBoxStyle}"
Text="{Binding KeywordValue}"
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="3"
Visibility="{Binding KeywordValue, TargetNullValue=Hidden}">
<TextBox.ToolTip>
<Label Content="{Binding Keyword, StringFormat='Edit value for {0}'}" />
</TextBox.ToolTip>
</TextBox>
<ComboBox Name="KeyWordComboBox"
ItemsSource="{Binding KeywordValueList}"
Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3" Visibility="{Binding KeywordValueList, TargetNullValue=Hidden}"/>
</Grid>
And the style:
<Style x:Key="InputBoxStyle" TargetType="TextBox">
<Setter Property="Margin" Value="0,0,5,0" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="Height" Value="20" />
</Style>
I have debugged quite a bit and found that if I change the single digit to either a single letter, string of more than one number, or string containing both it shows the textbox as expected. Also, the Visibility value for the textbox in the debugger shows Collapsed, not Hidden -- the TargetNullValue does not seem to be causing this. In fact the textbox does not show either if I change it to Visible. This only started happening when I added the option for a combobox, prior to that the textbox generated properly with a single digit.
Can anyone offer an idea why this may be happening?
I suppose that the code doesn't work because You are binding a string value (and ObservableCollection<string> value in case of combobox) to a Visibility property.
In order to hide controls on null value:
You can write a value converter similar to the one suggested here: https://stackoverflow.com/a/2123905/232530 (but just check if value parameter is null in the Convert method)
or
You can use triggers as suggested here: How to hide the empty TextBlock?.
Please let me know if You need help when using any of those solutions.
There is an UserControl with the following Grid:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
</Grid>
Now I have a Window and there are I would to write something like that:
<Window.Resources>
<Style TargetType="Grid">
<Setter Property="RowDefinitions">
<Value>
<RowDefinition Height="*"/>
<RowDefinition/>
</Value>
</Setter>
</Style>
</Window.Resources>
The key part, which doesn't compile is when I want to change Height from Auto to *. How to do this in legal way?
In general I have to cases. 1) The first row should stretch and the second should be fixed. 2) Vice versa. Maybe a different panel than Grid could be more relevant?
Grid.RowDefinitions and Grid.ColumnDefinitions are no dependency properties, and can't hence be set by a Style.
You may perhaps create a dependency property FirstRowHeight in your UserControl, and bind the Height of the first RowDefinition to that property. Later you may set the FirstRowHeight property in a Style.
<Grid.RowDefinitions>
<RowDefinition Height="{Binding FirstRowHeight,
RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}"/>
<RowDefinition/>
</Grid.RowDefinitions>
The property would look like this:
public static readonly DependencyProperty FirstRowHeightProperty =
DependencyProperty.Register(
"FirstRowHeight", typeof(GridLength), typeof(YourUserControl));
public GridLength FirstRowHeight
{
get { return (GridLength)GetValue(FirstRowHeightProperty); }
set { SetValue(FirstRowHeightProperty, value); }
}
EDIT: In order to support the simple scenario you describe at the end of your question, you may also just have an IsFirstRowFixed dependency property with a property changed callback that sets the row heights in code:
<Grid.RowDefinitions>
<RowDefinition x:Name="row1" Height="*"/>
<RowDefinition x:Name="row2" Height="Auto"/>
</Grid.RowDefinitions>
The property:
public static readonly DependencyProperty IsFirstRowFixedProperty =
DependencyProperty.Register(
"IsFirstRowFixed", typeof(bool), typeof(UserControl2),
new PropertyMetadata((o, e) => ((UserControl2)o).IsFirstRowFixedChanged()));
public bool IsFirstRowFixed
{
get { return (bool)GetValue(IsFirstRowFixedProperty); }
set { SetValue(IsFirstRowFixedProperty, value); }
}
private void IsFirstRowFixedChanged()
{
if (IsFirstRowFixed)
{
row1.Height = GridLength.Auto;
row2.Height = new GridLength(1, GridUnitType.Star);
}
else
{
row1.Height = new GridLength(1, GridUnitType.Star);
row2.Height = GridLength.Auto;
}
}
XAML code :
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid Grid.Row="1" Style="{StaticResource HeaderHeight}"</>
<Grid Grid.Row="1" Style="{StaticResource FooterHeight}"</>
</>
Styles in Resource dictionary
<Style TargetType="Frame" x:Name="HeaderHeight">
<Setter Property="Height" Value="700"></Setter>
</Style>
<Style TargetType="Grid" x:Name="FooterHeight">
<Setter Property="Height" Value="70"></Setter>
</Style>
Description:
I have a custom content control and I am trying to enable some external settings via dependency properties. Basically it's a decorator panel with two grid rows, upper one is the header, the lower one is the content (via ContentPresenter).
There are 3 items that are bound to the template (via TemplateBinding), HeaderHeight, TextSize and Header (each of them has its dependency property of an appropriate type).
Problem:
While two of the bindings work perfectly (even in design-time), the third one does not. The FontSize="{TemplateBinding TextSize}" and the Text="{TemplateBinding Header}" bindings work, but the <RowDefinition Height="{TemplateBinding HeaderHeight}" /> does not work.
The grid splits the rows' heights 50/50, no matter which value I set the HeaderHeight property to. It does not even take the default value from the DP metadata.
Question:
What is the problem with this scenario? Why do the other two bindings work with no problems and this one behaves as if there is no binding at all?
Note:
If I set DataContext = this in the constructor and replace {TemplateBinding HeaderHeight} with {Binding HeaderHeight}, the problem disappears and it works as intended. But I'd like to know why I don't need to do the same thing with other bindings to make them work.
XAML (Themes/Generic.xaml):
<Style TargetType="local:KaiPanel">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:KaiPanel">
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="{TemplateBinding HeaderHeight}" />
<RowDefinition />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Border>
<TextBlock FontSize="{TemplateBinding TextSize}"
Text="{TemplateBinding Header}" />
</Border>
</Grid>
<Grid Grid.Row="1">
<Border>
<ContentPresenter />
</Border>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Content Control (C#):
public class KaiPanel : ContentControl
{
public KaiPanel()
{
this.DefaultStyleKey = typeof(KaiPanel);
}
public static readonly DependencyProperty TextSizeProperty =
DependencyProperty.Register("TextSize", typeof(double), typeof(KaiPanel), new PropertyMetadata(15.0));
public double TextSize
{
get { return (double)GetValue(TextSizeProperty); }
set { SetValue(TextSizeProperty, value); }
}
public static readonly DependencyProperty HeaderProperty =
DependencyProperty.Register("Header", typeof(String), typeof(KaiPanel), new PropertyMetadata(""));
public String Header
{
get { return (String)GetValue(HeaderProperty); }
set { SetValue(HeaderProperty, value); }
}
public static readonly DependencyProperty HeaderHeightProperty =
DependencyProperty.Register("HeaderHeight", typeof(GridLength), typeof(KaiPanel), new PropertyMetadata(new GridLength(40)));
public GridLength HeaderHeight
{
get { return (GridLength)GetValue(HeaderHeightProperty); }
set { SetValue(HeaderHeightProperty, value); }
}
}
Custom Control usage (XAML):
<UserControl ...>
<Grid x:Name="LayoutRoot">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<StackPanel x:Name="buttonsStackPanel" Grid.Column="0" VerticalAlignment="Center">
<!-- Some buttons here -->
</StackPanel>
<Grid Grid.Column="1">
<controls:KaiPanel x:Name="contentPanel">
<navigation:Frame x:Name="contentFrame" Source="KP">
<navigation:Frame.UriMapper>
<uriMapper:UriMapper>
<uriMapper:UriMapping Uri="KP" MappedUri="/Views/Kornelijepetak.xaml" />
<uriMapper:UriMapping Uri="KAI" MappedUri="/Views/KaiNetwork.xaml" />
</uriMapper:UriMapper>
</navigation:Frame.UriMapper>
</navigation:Frame>
</controls:KaiPanel>
</Grid>
</Grid>
</UserControl>
Sadly it seems what you're attempting to do requires more than just a single data binding. RowDefinition isn't a subclass of FrameworkElement, and it doesn't match any of the other criteria specified in the MSDN Silverlight data binding documentation, so it can't be used as the target of a binding.
What you want to do is possible, but unfortunately it involves a little more code.
Firstly, add a field for the main grid (I've called it mainGrid) to your KaiPanel class. Then, override the OnApplyTemplate method in this class to grab the main Grid from the template and keep a reference to it in your mainGrid field:
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
mainGrid = GetTemplateChild("LayoutRoot") as Grid;
SetHeaderRowHeight();
}
This calls a method that updates the height of the first row of the grid. That method is as follows:
private void SetHeaderRowHeight()
{
if (mainGrid != null)
{
mainGrid.RowDefinitions[0].Height = HeaderHeight;
}
}
I admit I'm not 100% sure that OnApplyTemplate is called after the DPs are set. It seems that this is the case (a quick test seemed to confirm this), but all I could find to back this up was this post on the Silverlight forums. If you find that this isn't the case, you'll need to register a PropertyChangedCallback on the HeaderHeight DP that will also call this SetHeaderRowHeight method.
See also http://forums.silverlight.net/forums/t/76992.aspx#183089.
Use RelativeSource and TemplatedParent instead:
<RowDefinition Height="{Binding RelativeSource={RelativeSource TemplatedParent},
Path=HeaderHeight}" />
Here the difference between TemplateBinding and RelativeSource TemplatedParent is explained:
WPF TemplateBinding vs RelativeSource TemplatedParent
I need to do this in XAML :
<Grid x:Name="layoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<SomeUserControl Grid.Row="0" />
<ui:AdditionalView.UseCase1>
<ContentControl>
<TextBlock>aaa</TextBlock>
</ContentControl>
</ui:AdditionalView.UseCase1>
</Grid>
First, and most important, I need to have the block in the Something.UseCase1 form. That is how I ended up using attached properties. I defined the AdditionalView class and defined an attached property called UseCase1 on it.
However this does not render the
<TextBlock>aaa</TextBlock>
at runtime.
How can I achieve this?
Later Edit (1) - I managed to get something to work like so :
<ContentControl Grid.Row="1" Content="{Binding ElementName=layoutRoot, Path=(ui:AdditionalView.UseCase1)}" />
.. but it seems nasty. Any decent way to get this to work?
The AdditionalView class :
public class AdditionalView
{
public static readonly DependencyProperty UseCase1Property = DependencyProperty.RegisterAttached(
"UseCase1",
typeof(object),
typeof(AdditionalView),
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender)
);
public static void SetUseCase1(UIElement element, Boolean value)
{
element.SetValue(UseCase1Property, value);
}
public static object GetUseCase1(UIElement element)
{
return element.GetValue(UseCase1Property);
}
}
I have created a custom WPF control. The control acts as a container with various regions (so it can work like a master page).
The style for this control is loaded at runtime from a separate resource dictionary as follows:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/MyApp.Application;component/Themes/Theme.xaml" x:Name="theme"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
My custom control's style looks as follows...
<Style TargetType="{x:Type shareduc:EditControlMaster}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type shareduc:EditControlMaster}">
<Grid>
<Grid.ColumnDefinitions></Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Border BorderBrush="{DynamicResource xxBorderBrush}"
BorderThickness="0,1,0,1" Background="White" Grid.Row="0">
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition Height="auto"></RowDefinition>
</Grid.RowDefinitions>
<ContentPresenter Grid.Row="0" Grid.Column="0" Grid.RowSpan="2" Margin="10" Content="{TemplateBinding Image}" />
<ContentPresenter Grid.Row="0" Grid.Column="1" Margin="2" Content="{TemplateBinding Title}" />
<ContentPresenter Grid.Row="1" Grid.Column="1" Margin="2" Content="{TemplateBinding Abstract}" />
</Grid>
</Border>
<ContentPresenter Grid.Row="1" Margin="2" Content="{TemplateBinding Content}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The problem is that this style is only loaded at Runtime. So in Design Mode my control does not have any style and does not have any size or layout. How can I give my control a default style for Design Mode?
Update:
I'm making some progress... it appears I can specify a default theme to use in a file called Themes\Generic.xaml. This works fine in a small sample project, but for some reason my VS2008 designer stays blank when I do the same thing in my actual project... Help? :(
Note that my custom control's code looks as follows:
public partial class EditControlMaster : Control
{
static EditControlMaster()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(EditControlMaster),
new FrameworkPropertyMetadata(typeof(EditControlMaster)));
}
public object Title
{
get { return (object)GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
}
public static readonly DependencyProperty TitleProperty =
DependencyProperty.Register("Title", typeof(object),
typeof(EditControlMaster), new UIPropertyMetadata());
public object Image
{
get { return (object)GetValue(ImageProperty); }
set { SetValue(ImageProperty, value); }
}
public static readonly DependencyProperty ImageProperty =
DependencyProperty.Register("Image", typeof(object),
typeof(EditControlMaster), new UIPropertyMetadata());
public object Abstract
{
get { return (object)GetValue(AbstractProperty); }
set { SetValue(AbstractProperty, value); }
}
public static readonly DependencyProperty AbstractProperty =
DependencyProperty.Register("Abstract", typeof(object),
typeof(EditControlMaster), new UIPropertyMetadata());
public object Content
{
get { return (object)GetValue(ContentProperty); }
set { SetValue(ContentProperty, value); }
}
public static readonly DependencyProperty ContentProperty =
DependencyProperty.Register("Content", typeof(object),
typeof(EditControlMaster), new UIPropertyMetadata());
}
Through lots of poking around project files I have figured out what was wrong!
Themes\Generic.xaml contains your control's default Style. This is fine.
Your Assembly.cs file needs to contain the following attribute:
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]
Voila! The VS2008 designer works!
Did you try
public EditControlMaster()
{
DefaultStyleKey = typeof(EditControlMaster);
}
as part of the constructor?
Try moving the style to a standard place.
Add / New Item / Custom Control(WPF) / "MyDummyControl"
now place your style in "Themes/Generic.xaml" that was created
remove "MyDummyControl" files and style
remove your Theme.xaml, and MergedDictionaries
One more thing, in my experience, using DynamicResource in a style defined in themes\generic.xaml (like you did for the Border) does not work (at least, does not work always). You should consider changing that to a StaticResource lookup.