When a standard WPF button is clicked, it gets highlighted in blue (probably using the blue color from whatever Windows theme is set), and it stays highlighted until you interact with any other control. For my application, it is confusing for the user.
Is there a simple way turn this off and get the button back to its normal style?
I am using .NET 4.
What happens is that the button accepts the input focus after it has been clicked, just like any other control does when you click on it.
And the way that Windows indicates that a control has the input focus (at least under the Aero theme) is with a subtle blue highlight.
For a button control in particular, when it has the input focus, simply pressing the Enter key will "push" that button. That's why maintaining the highlight is very important, so that the user knows what to expect.
The better solution is to set the focus to a different control in your window immediately after the user has clicked on the button. That way, it will no longer be automatically highlighted and no action will be automatically triggered when the user presses the Enter key. (This is the real usability problem that you're trying to solve, even if you don't know it yet. Nothing is more confusing than a button inadvertently getting clicked when the user is actually trying to type something.)
You could prevent the button from ever getting the focus altogether by setting its Focusable property to false, but I would very much recommend against this. Once you've done this, there will be no way for the user to "press" the button using only the keyboard. Well-designed applications should always be accessible to users who either prefer not to or who are unable to use the mouse.
Try to set Focusable to false. The button will be clickable but will not remain focused.
This is the default look for Aero buttons when they have focus. You can either set Focusable="False" or use a custom Style, that doesn't render it differently when the button has focus. Something like:
xmlns:theme="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
<Style x:Key="BaseButtonStyle" TargetType="{x:Type ButtonBase}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ButtonBase}">
<theme:ButtonChrome Name="Chrome" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" RenderDefaulted="{TemplateBinding Button.IsDefaulted}"
RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}"
SnapsToDevicePixels="true">
<ContentPresenter Margin="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</theme:ButtonChrome>
<ControlTemplate.Triggers>
<!--
Do not show blue when focused
<Trigger Property="IsKeyboardFocused" Value="true">
<Setter TargetName="Chrome" Property="RenderDefaulted" Value="true" />
</Trigger>-->
<Trigger Property="ToggleButton.IsChecked" Value="true">
<Setter TargetName="Chrome" Property="RenderPressed" Value="true" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#ADADAD" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="{x:Type ToggleButton}" BasedOn="{StaticResource BaseButtonStyle}" TargetType="{x:Type ToggleButton}" />
<Style x:Key="{x:Type RepeatButton}" BasedOn="{StaticResource BaseButtonStyle}" TargetType="{x:Type RepeatButton}" />
<Style x:Key="{x:Type Button}" BasedOn="{StaticResource BaseButtonStyle}" TargetType="{x:Type Button}" />
You'd need to add a reference to PresentationFramework.Aero.dll
That is simply the focussed state. To turn it off you will have to change the focussed state. It's easiest by using Blend.
I do not recommend setting Focusable to false because it interferes with using the keyboard
<Style x:Key="TouchButton" TargetType="{x:Type Button}">
<Setter Property="IsTabStop" Value="false"/>
<Setter Property="Focusable" Value="false"/>
<Setter Property="ClickMode" Value="Press"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="Border" CornerRadius="2" BorderThickness="1" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}">
<ContentPresenter Margin="2" HorizontalAlignment="Center" VerticalAlignment="Center" RecognizesAccessKey="True"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Button.IsMouseOver" Value="True">
<Setter TargetName="Border" Property="Background" Value="Red"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I needed to do something similar, but in code at runtime, it looked like this
//You can get this XAML by using System.Windows.Markup.XamlWriter.Save(yourButton.Template)";
const string controlXaml = "<ControlTemplate TargetType=\"ButtonBase\" " +
"xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" " +
"xmlns:s=\"clr-namespace:System;assembly=mscorlib\" " +
"xmlns:mwt=\"clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero\">" +
"<mwt:ButtonChrome Background=\"{TemplateBinding Panel.Background}\" " +
"BorderBrush=\"{TemplateBinding Border.BorderBrush}\" " +
"RenderDefaulted=\"{TemplateBinding Button.IsDefaulted}\" " +
//"RenderMouseOver=\"{TemplateBinding UIElement.IsMouseOver}\" " +
"RenderPressed=\"{TemplateBinding ButtonBase.IsPressed}\" Name=\"Chrome\" SnapsToDevicePixels=\"True\">" +
"<ContentPresenter RecognizesAccessKey=\"True\" " +
"Content=\"{TemplateBinding ContentControl.Content}\" " +
"ContentTemplate=\"{TemplateBinding ContentControl.ContentTemplate}\" " +
"ContentStringFormat=\"{TemplateBinding ContentControl.ContentStringFormat}\" " +
"Margin=\"{TemplateBinding Control.Padding}\" " +
"HorizontalAlignment=\"{TemplateBinding Control.HorizontalContentAlignment}\" " +
"VerticalAlignment=\"{TemplateBinding Control.VerticalContentAlignment}\" " +
"SnapsToDevicePixels=\"{TemplateBinding UIElement.SnapsToDevicePixels}\" /></mwt:ButtonChrome>" +
"<ControlTemplate.Triggers>" +
"<Trigger Property=\"UIElement.IsKeyboardFocused\">" +
"<Setter Property=\"mwt:ButtonChrome.RenderDefaulted\" TargetName=\"Chrome\"><Setter.Value><s:Boolean>True</s:Boolean></Setter.Value></Setter>" +
"<Trigger.Value><s:Boolean>True</s:Boolean></Trigger.Value></Trigger>" +
"<Trigger Property=\"ToggleButton.IsChecked\">" +
"<Setter Property=\"mwt:ButtonChrome.RenderPressed\" TargetName=\"Chrome\"><Setter.Value><s:Boolean>True</s:Boolean></Setter.Value></Setter>" +
"<Trigger.Value><s:Boolean>True</s:Boolean></Trigger.Value></Trigger>" +
"<Trigger Property=\"UIElement.IsEnabled\"><Setter Property=\"TextElement.Foreground\"><Setter.Value><SolidColorBrush>#FFADADAD</SolidColorBrush></Setter.Value></Setter>" +
"<Trigger.Value><s:Boolean>False</s:Boolean></Trigger.Value></Trigger></ControlTemplate.Triggers>" +
"</ControlTemplate>";
var xamlStream = new MemoryStream(System.Text.Encoding.Default.GetBytes(controlXaml));
var _buttonControlTemplate = (ControlTemplate)System.Windows.Markup.XamlReader.Load(xamlStream);
var yourButton = new Button() { Template = _buttonControlTemplate };
You can see that i comment the ""RenderMouseOver" line
My first hope was using FrameworkElementFactory but i needed to create all the default template.... ALL BY HAND! ;)
Using
System.Windows.Markup.XamlWriter.Save(myButton.Template)
It give me the template i wanted and then removing the Render section was easy.
I found 2 steps solution. The solution is little funny but working .
My referance posts are;
How to remove global FocusVisualStyle to all the Controls?
and
C# WPF application .NET 4.5 Set Mouse Position
One DLL must be imported , because WPF is not directly supporting mouse cursor move.
add System.Runtime.InteropServices to namespace
Add two line to the MainWindow or whatever your window's code
[DllImport("User32.dll")]
private static extern bool SetCursorPos(int X, int Y);
Add these 2 lines to your click event .
SetCursorPos(0, 0);
ButtonName.FocusVisualStyle = null;
It works for me .
I've resolved this situation, in my case, by using MultiTrigger, and to set the states like this:
<MultiTrigger.Conditions>
<Condition Property="IsFocused" Value="True"/>
<Condition Property="IsPressed" Value="False"/>
</MultiTrigger.Conditions>
TO more information see this link.
Related
This will probably be very simple for most of you, I am new to XAML and WPF.
I have an app that startes att full screen, I did this by adding
WindowState="Maximized"
WindowStyle="None"
I want to have a button that simply eliminates this part. I have a "Full screen" button in the xaml and by click he is calling a "FullScreen_Click" function in my code.
I just need to know what to write in the code that will eliminate the full screen if it is on full screen mode and restore it to full screen when it is not.
Try this:
private void FullScreen_Click(object sender, RoutedEventArgs e)
{
WindowState = WindowState == WindowState.Maximized ? WindowState.Normal : WindowState.Maximized;
}
This will toggle between WindowState.Maximized and WindowState.Normal each time the Button is clicked.
For a xaml only technique just for reference to see a xaml example in comparison (but I would do #mm8's route, it's simpler);
1. Bind your property to that of another like:
<Window WindowState="{Binding Tag, ElementName=toggleState}" .... />
2. Use a `ToggleButton` or similar control and `Triggers`
.
<!-- like this PoC -->
<Grid>
<Grid.Resources>
<Style x:Key="cwWindowState_PoC" TargetType="{x:Type ToggleButton}">
<Setter Property="Tag" Value="Maximized"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Grid>
<Border Background="{TemplateBinding Background}"/>
<ContentPresenter x:Name="MyContentPresenter"
Content="{TemplateBinding Tag}"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Tag" Value="Normal" />
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter Property="Tag" Value="Maximized" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Grid.Resources>
<ToggleButton x:Name="toggleState" Content="Click Me"
Background="Green"
Style="{StaticResource cwWindowState_PoC}"/>
</Grid>
Could also use DataTrigger but that requires interaction triggers instead of just a property setter from a template.
I was asked to create a Radio and CheckBox variation were visually similar to a button.
With this behavior:
When the button is clicked, it change to state checked, the background is changed, when clicked again the state is changed to unchecked and the background turn into the original brush.
At first my strategy was to create a user control. But since my control will be almost equal to a button, make sense to me use inheritance.
So my question is
Is possible to create a user control that inherit from button? If so, is that a good approach? How can I do it?
One possible approach is to use ToggleButton, but completely change its appearance when IsChecked become true:
<ToggleButton>
<ToggleButton.Style>
<Style TargetType="ToggleButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<!-- IsChecked == false template -->
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Trigger.Setters>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<!-- IsChecked == true template -->
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger.Setters>
</Trigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
</ToggleButton>
Use 2 different templates (e.g. <TextBlock Text="On" /> and <TextBlock Text="Off" />) to see how it works.
You can use the WPF toggle button.
I am a relatively new user of WPF and have run into a problem regarding dynamic Button generation and Buttons' default hover properties.
I am currently working on an application where a significant number of buttons are being generated on a Canvas in the code behind. The contents of each button are unique images referenced by an array of objects containing Uri strings. This array is populated by reading in a file containing these Uri strings, so the number and placement of buttons on this canvas vary based on which file is being read.
For the most part, the appearance of the Canvas when the application runs is what was intended, however hovering over any of the Buttons replaces the image with the default blue background for the duration that the mouse overlaps.
Here is an example of the code that I am using to generate the buttons:
exampleButton = new Button { Content = "Name", Width = 50, Height = 65, Background = new ImageBrush(new BitmapImage(new Uri(#object.UriString, UriKind.Relative))) };
exampleButton.Style = exampleStyle;
exampleCanvas.Children.Add(exampleButton);
Please understand that I have omitted pieces of code irrelevant to my question.
Here is an example of the style that was used, also in the code behind:
exampleStyle = new Style(typeof(Button));
exampleStyle.Setters.Add(new Setter(Button.ForegroundProperty, Brushes.Transparent));
exampleStyle.Setters.Add(new Setter(Button.BorderBrushProperty, Brushes.Transparent));
Together these achieve the effect I am trying to create, barring hover behavior.
So far I have tried appending ControlTemplate overrides into the style declaration but am unsure of how that translates from XAML to the C# code behind. I have also tried creating and binding button templates created in the XAML but I haven't had success in finding explanations or tutorials that apply to my situation.
Any help to accomplish this via the code behind would be greatly appreciated. Of course, if I'm doing this really unconventionally and there is a more standard way of doing things I am all ears.
EDIT:
This is the XAML I am using to declare the style that my dynamically generated buttons are using.
<Style x:Key="MySuperButtonStyle" TargetType="{x:Type Button}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="Width" Value="50" />
<Setter Property="Height" Value="65" />
<Setter Property="Foreground" Value="Transparent" />
<Setter Property="BorderBrush" Value="Black" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="Black"/>
</Trigger>
</Style.Triggers>
</Style>
Using this call to assign the style in the code behind:
exampleButton.Style = (Style)FindResource("MySuperButtonStyle");
This is happening because the default Button control style has a trigger that changes the Background property of the button when the mouse hovers over it. You need to use a custom style for the button:
<Style x:Key="MySuperButtonStyle" TargetType="{x:Type Button}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="Width" Value="50" />
<Setter Property="Height" Value="65" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Here the width and the height are set using the style, so you no longer need to set those properties in code. The control template has been changed so it consists only of a Border element with the content inside of it. There are no triggers at all, so the button won't change its appearance when clicked or hovered over.
In your code all you need to do is obtain a reference to this style then assign that to the Style property when you are creating the button.
Having said all this, in WPF you rarely need to create controls in code. Instead you should really be using the MVVM (Model-View-ViewModel) pattern and data binding. You probably shouldn't be creating styles and setters in code either.
I have a list box whose selection colour is default plain Solid Blue colour. I read this article "How To Change WPF ListBox SelectedItem Color?" here. I want to create style given in it to code behind. so that i can assign this style to my Listbox ItemContainerStyle property.
like
Style s = ......
MyListBox.ItemContainerStyle = s;
I want to make this in code behind because if user changes theme of my software then this style (Selection Colours) should recreate itself to match the changed theme colours.
<Style x:Key="SimpleListBoxItem" TargetType="ListBoxItem">
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border Name="Border" Padding="2" SnapsToDevicePixels="true">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="Border" Property="Background" Value="{StaticResource AuthorGradient}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I think you don't have a code behind version of this code, you just have to apply you're existing template to your listbox like below.
if your target is a template.
(NameOfListBox.SelectedItem as ListBoxItem).ContentTemplate = this.Resources["NameOfTemplate"] as DataTempate;
(NameOfListBox.SelectedItem as ListBoxItem).UpdateLayout();
if your target is a style.
(NameOfListBox.SelectedItem as ListBoxItem).Style= this.Resources["NameOfStyle"] as DataTempate;
(NameOfListBox.SelectedItem as ListBoxItem).UpdateLayout();
example
(lstMetaDataCards.SelectedItem as ListBoxItem).ContentTemplate = this.Resources["MetaDataCardAtEditState"] as DataTemplate;
(lstMetaDataCards.SelectedItem as ListBoxItem).UpdateLayout();
I'm using a the TreeView control and it scrolls automatically to left-align TreeViewItem when one of them is clicked. I've gone looking at my Styles and ControlTemplates, but I haven't found anything. Is there a default ControlTemplate that causes this? I want to disable it.
The items scroll because the ScrollViewer calls BringIntoView() on them. So one way to avoid scrolling is to suppress the handling of the RequestBringIntoView event. You can try that out quickly by subclassing TreeView and instantiating this control instead:
public class NoScrollTreeView : TreeView
{
public class NoScrollTreeViewItem : TreeViewItem
{
public NoScrollTreeViewItem() : base()
{
this.RequestBringIntoView += delegate (object sender, RequestBringIntoViewEventArgs e) {
e.Handled = true;
};
}
protected override DependencyObject GetContainerForItemOverride()
{
return new NoScrollTreeViewItem();
}
}
protected override DependencyObject GetContainerForItemOverride()
{
return new NoScrollTreeViewItem();
}
}
after spending some hours on this problem i found a solution that works for me.
brians solution to prevent the RequestBringIntoView event on a TreeViewItem from bubbling was the first step. unfortunately this also stops a treeviewitem to be shown if you change the selected item programmatically by
yourtreeview.SelectedItem = yourtreeviewitem
so, for me the solution is to modify the controltemplate of the treeview as follows:
<Style x:Key="{x:Type TreeView}" TargetType="TreeView">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TreeView">
<Border Name="Border" BorderThickness="0" Padding="0" Margin="1">
<ScrollViewer Focusable="False" CanContentScroll="False" Padding="0">
<Components:AutoScrollPreventer Margin="0">
<ItemsPresenter/>
</Components:AutoScrollPreventer>
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
the "autoscrollpreventer" is:
using System;
using System.Windows;
using System.Windows.Controls;
namespace LiveContext.Designer.GUI.Components {
public class AutoScrollPreventer : StackPanel
{
public AutoScrollPreventer() {
this.RequestBringIntoView += delegate(object sender, RequestBringIntoViewEventArgs e)
{
// stop this event from bubbling so that a scrollviewer doesn't try to BringIntoView..
e.Handled = true;
};
}
}
}
hope it helps..
It looks like I found a good clue on MSDN:
Sounds like this is an interaction
with the scrollviewer and the focus
system.
When an element is focused within a
ScrollViewer (which is part of the
TreeView template), the ScrollViewer
is instructed to make the element
visible. It automatically responds by
scrolling to the requested element.
The methods inside of ScrollViewer
that handle these focus requests are
all private and / or internal so you
really can't get to them. I don't
think there's too much you can do in
this case; it's just how focus works.
So, is that it? Surely there's a way to modify the TreeView template so that the ScrollViewer won't have this behavior...
Ok, I was finally able to get the default style like this:
using (Stream sw = File.Open(#"C:\TreeViewDefaults.xaml", FileMode.Truncate, FileAccess.Write))
{
Style ts = Application.Current.FindResource(typeof(TreeView)) as Style;
if (ts != null)
XamlWriter.Save(ts, sw);
}
Which produced:
<Style TargetType="TreeView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:s="clr-namespace:System;assembly=mscorlib"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style.Triggers>
<Trigger Property="VirtualizingStackPanel.IsVirtualizing">
<Setter Property="ItemsControl.ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate><VirtualizingStackPanel IsItemsHost="True" /></ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Trigger.Value>
<s:Boolean>True</s:Boolean>
</Trigger.Value>
</Trigger>
</Style.Triggers>
<Style.Resources>
<ResourceDictionary />
</Style.Resources>
<Setter Property="Panel.Background">
<Setter.Value><DynamicResource ResourceKey="{x:Static SystemColors.WindowBrushKey}" /></Setter.Value>
</Setter>
<Setter Property="Border.BorderBrush">
<Setter.Value><SolidColorBrush>#FF828790</SolidColorBrush></Setter.Value>
</Setter>
<Setter Property="Border.BorderThickness">
<Setter.Value><Thickness>1,1,1,1</Thickness></Setter.Value>
</Setter>
<Setter Property="Control.Padding">
<Setter.Value><Thickness>1,1,1,1</Thickness></Setter.Value>
</Setter>
<Setter Property="TextElement.Foreground">
<Setter.Value><DynamicResource ResourceKey="{x:Static SystemColors.ControlTextBrushKey}" /></Setter.Value>
</Setter>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility">
<Setter.Value><x:Static Member="ScrollBarVisibility.Auto" /></Setter.Value>
</Setter>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility">
<Setter.Value><x:Static Member="ScrollBarVisibility.Auto" /></Setter.Value>
</Setter>
<Setter Property="Control.VerticalContentAlignment">
<Setter.Value><x:Static Member="VerticalAlignment.Center" /></Setter.Value>
</Setter>
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate TargetType="TreeView">
<Border BorderThickness="{TemplateBinding Border.BorderThickness}"
BorderBrush="{TemplateBinding Border.BorderBrush}"
Name="Bd" SnapsToDevicePixels="True">
<ScrollViewer CanContentScroll="False"
HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}"
Background="{TemplateBinding Panel.Background}"
Padding="{TemplateBinding Control.Padding}"
Name="_tv_scrollviewer_"
SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}"
Focusable="False">
<ItemsPresenter />
</ScrollViewer>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="UIElement.IsEnabled">
<Setter Property="Panel.Background" TargetName="Bd">
<Setter.Value>
<DynamicResource ResourceKey="{x:Static SystemColors.ControlBrushKey}" />
</Setter.Value>
</Setter>
<Trigger.Value>
<s:Boolean>False</s:Boolean>
</Trigger.Value>
</Trigger>
<Trigger Property="VirtualizingStackPanel.IsVirtualizing">
<Setter Property="ScrollViewer.CanContentScroll" TargetName="_tv_scrollviewer_">
<Setter.Value><s:Boolean>True</s:Boolean></Setter.Value>
</Setter>
<Trigger.Value>
<s:Boolean>True</s:Boolean>
</Trigger.Value>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Which, unfortunately, doesn't look helpful. I don't see any properties in there for stopping the auto-scroll-focus thing.
Still looking...
Another fun tidbit: there is a overridable boolean value called HandlesScrolling that always returns true. After decompiling the source, it looks like this property is NEVER used (or it's being used in some deep, dark, secret place in XAML). I tried making my own TreeView control to set this value to false and it didn't work.