I have a usecase to show nearly 10000 items in a WPF usercontrol. I am using ItemsControl and each item is represented by a button (items a simple clickable text). I have defined a style for button in usercontrol resources.
Things work fine till I have more than 5000 items in my list then UI paint starts to slow down- 10000 items takes nearly 3+ minutes to be displayed.
If I move the style from resources to Button.Style then also it take 2.5 mins to displays the items.
If I remove the style completely, I see no noticeable delay.The only reason to use Button style is to give its ContentPresenter's Border (named as Chrome in below code) the same background as button, which is otherwise Gray.
Please let me know how can I use styles efficiently without incurring a Performance hit or how can I paint the ContentPresenter Border's Background as same color as Button (transparent would work somehow).
Here is the code sample:
<UserControl.Resources>
<Style x:Key="ButtonStyle" TargetType="{x:Type Button}" BasedOn="{x:Null}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="Chrome" Background="{TemplateBinding Property=Background}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<ContentPresenter.Resources>
<Style TargetType="{x:Type TextBlock}" BasedOn="{x:Null}">
<Setter Property="FontSize" Value="{Binding FontSize, RelativeSource={RelativeSource AncestorType={x:Type Button}}}"/>
</Style>
</ContentPresenter.Resources>
</ContentPresenter>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Grid Name="Grid1" Margin="5,5,5,5">
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" Margin="5,0,0,0">
<Border Name="Border1" Margin="2,2,2,2" BorderBrush="Gray" BorderThickness="2">
<ItemsControl Name="ItemsControl1" ItemsSource="{Binding LargeItems}" FocusVisualStyle="{x:Null}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="{Binding Columns}" Rows="{Binding Rows}"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Name="Border1" Background="{Binding BorderBkg}"
BorderThickness="1" Padding="{Binding PaddingVal}">
<Button Name="MyButton" Content="{Binding Label}"
Background="{Binding Background}"
Foreground="{Binding Foreground}"
BorderThickness="0"
BorderBrush="Transparent"
Margin="0"
Style="{StaticResource ButtonStyle}"
IsEnabled="{Binding IsButtonEnabled}"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}, Path=DataContext.ButtonAction}"
CommandParameter="{Binding}">
</Button>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Border>
</ScrollViewer>
</Grid>
Thanks,
RDV
It seems that there is no data virtualization implemented in your ItemControl. You can implement the virtualization by adding
VirtualizingPanel.IsVirtualizing="True" VirtualizingPanel.VirtualizationMode="Recycling"
in your ItemsControl and see the performance difference.
Related
so I got an TextBox and i made the Style in my Ressource Dictionary like that:
<Style x:Key="TextBoxTemplateBrowser" TargetType="{x:Type TextBox}">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Border Background="White" CornerRadius="0 0 5 5" BorderBrush="Black" BorderThickness="1">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And my TextBox himself like that:
<TextBox TextWrapping="Wrap" x:Name="tb" Style="{DynamicResource TextBoxTemplateBrowser}"
Text="{Binding Inhalt, RelativeSource={RelativeSource AncestorType=local:ArtikelBezPanel}, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"
TextChanged="TextBox_TextChanged"
Height="{Binding Height, RelativeSource={RelativeSource AncestorType=local:ArtikelBezPanel}, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" AcceptsReturn="True" BorderBrush="Black" AcceptsTab="True" VerticalAlignment="Top" BorderThickness="1">
</TextBox>
The Problem what I got now is that, when i try to write in that TextBox I can write anything and there cant be Text displayed what I declare before.
When templating TextBox you need the PART_ContentHost:
eg:
<ScrollViewer Margin="0" x:Name="PART_ContentHost" />
See DOCS for more info!
Replace
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
with
<ScrollViewer Margin="0" x:Name="PART_ContentHost" HorizontalAlignment="Center" VerticalAlignment="Center"/>
and it should work!
I'm Trying to change listView GridView to IconView, as you see in the screenshot, each item is taking a row.
Style XAML
<UserControl.Resources>
<Style x:Key="FileItemStyle" TargetType="{x:Type ListViewItem}">
<Setter Property="Width" Value="50"/>
<Setter Property="Margin" Value="5,5,5,5"/>
<Setter Property="Padding" Value="0,0,0,0"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<Grid HorizontalAlignment="Left" VerticalAlignment="Top" Height="50" Width="50">
<Border x:Name="border" BorderBrush="{x:Null}" BorderThickness="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" CornerRadius="2.5"/>
<StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<ContentPresenter />
</StackPanel>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
ListView XAML
<ListView ItemContainerStyle="{DynamicResource FileItemStyle}" HorizontalAlignment="Left" Height="194.667" Margin="11,77.666,0,0" VerticalAlignment="Top" Width="368.667" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.CanContentScroll="True" UseLayoutRounding="False">
<ListView.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Left" Height="50">
<Border x:Name="border" BorderBrush="{x:Null}" BorderThickness="1" HorizontalAlignment="Stretch" Height="50" VerticalAlignment="Stretch" Width="50" CornerRadius="2.5"/>
<StackPanel>
<Image x:Name="Img" Source="BtnImg/Computer.png" Stretch="None" Margin="9,0,9,0" Width="32" Height="32"/>
<TextBlock x:Name="PCName" Margin="0" TextWrapping="Wrap" Height="18" HorizontalAlignment="Stretch" TextAlignment="Center"><Run Text="{Binding Content}"/></TextBlock>
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
<ListBoxItem Content="ddd"/> <!--**-->
<ListViewItem Content="zczxcz"/>
</ListView>
I've tried to use MDSN example : How to: Create a Custom View Mode for a ListView and modify it to get what I need, but it didn't work with me, I actually couldn't understand the example clearly, anyone can Simplify how can I create a View mode? Do I have to create an overrided ViewBase class?
Thanks in advance
Using the same exact Code Behind as My Answer to your previous question:
<Style x:Key="FileItemStyle" TargetType="{x:Type ListViewItem}">
<Setter Property="Margin" Value="5,5,5,5"/>
<Setter Property="Padding" Value="0,0,0,0"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<Grid HorizontalAlignment="Left" VerticalAlignment="Top" Height="50" >
<Border x:Name="border" BorderBrush="{x:Null}" BorderThickness="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" CornerRadius="2.5"/>
<StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<ContentPresenter/>
</StackPanel>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Then:
<ListView ItemsSource="{Binding}" ScrollViewer.HorizontalScrollBarVisibility="Disabled"
SelectedItem="{Binding SelectedComputer, RelativeSource={RelativeSource AncestorType=Window}}"
ItemContainerStyle="{StaticResource FileItemStyle}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<DockPanel>
<TextBlock DockPanel.Dock="Bottom" Text="{Binding Name}"/>
<Rectangle Height="32" Width="32" Fill="Blue"/>
</DockPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Result:
Remove the hardcoded Width and Heights
Replace the blue rectangle for your Image.
Add some Triggers in the ControlTemplate so that you get highlighting when IsSelected="True"
Simply change the ItemsPanel of any ItemsControl in order to define how items are laid out.
Using a WrapPanel, you get a layout similar to Windows Explorer, where items are placed horizontally until there is no more horizontal space and then another "row" is created. Run the example and resize the Window to see this.
Bottom line: NO, you don't need custom code to customize the UI in WPF. It can be done with the existing controls and some XAML. Please read the "Alternatives to Writing a New Control" section in MSDN: Control Authoring Overview
I'm trying to translate a control I wrote in WPF into Silverlight for Windows Phone. I've learned a lot and tweaked it quite a bit with improvements made to both versions, but I just can't seem to get the ScrollViewer out of a ListBox in the Silverlight version. It seemed pretty simple from the outset:
ScrollViewer s = VisualTreeHelper.GetChild(List, 0) as ScrollViewer;
However, when I reach this line, I get an IndexOutOfRangeException-- apparently, according to VisualTreeHelper, my ListBox has no visual children.
Since I get the feeling this is a special case, here's my XAML declaration of the ListBox:
<ListBox x:Name="List" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
ItemsSource="{Binding ItemsSource, ElementName=SnapListControl}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.Style>
<Style TargetType="ListBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBox">
<ScrollViewer HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden">
<VirtualizingStackPanel Orientation="Horizontal" IsItemsHost="True"
Margin="{Binding ActualWidth, ElementName=LayoutRoot, Converter={StaticResource Hc}}">
</VirtualizingStackPanel>
</ScrollViewer>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.Style>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="RenderTransformOrigin">
<Setter.Value>
<Point X="0.5" Y="0.5"/>
</Setter.Value>
</Setter>
<Setter Property="Padding" Value="0"/>
<!--<Setter Property="ContentTemplate" Value="{Binding ItemContentTemplate, ElementName=SnapListControl}"/>-->
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
I had to comment out the ContentTemplate binding because apparently that's a readonly property in Silverlight? I'll have to investigate that more when I finish clearing this up.
I can't find much from googling this, most other people seem to use the method above to some success. It certainly works in WPF.
If your objective is simply to hide the ScrollViewer, you are already half way there. You simply need to use the following attached properties on your ListBox
<ListBox ScrollViewer.VerticalScrollBarVisibility="Hidden"
ScrollViewer.HorizontalScrollBarVisibility="Hidden" >
...
As for your other problems:
The ControlTemplate is not being applied because your ScrollViewer does not have a name. It must be named "ScrollViewer".
You cannot explicitly set your ItemsPanel in the ControlTemplate either. Instead, you must provide an ItemsPresenter, and then set the ItemsPanel property of the ListBox.
To set the DataTemplate for your content, you must set the ItemTemplate property on the ListBox.
<ListBox Height="100" Margin="200,195,156,0"
VerticalAlignment="Top"
ScrollViewer.VerticalScrollBarVisibility="Hidden"
ScrollViewer.HorizontalScrollBarVisibility="Hidden"
ItemContainerStyle="{StaticResource ListBoxItemStyle1}">
<ListBox.Style>
<Style TargetType="ListBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBox">
<ScrollViewer x:Name="ScrollViewer" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Foreground="{TemplateBinding Foreground}" Padding="{TemplateBinding Padding}">
<ItemsPresenter/>
</ScrollViewer>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.Style>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal"
Margin="{Binding ActualWidth, ElementName=LayoutRoot, Converter={StaticResource Hc}}">
</VirtualizingStackPanel>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Border Width="100" Height="100" Background="White">
...
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I'm trying to make a custom control that consists of several buttons and a couple labels, but the buttons are supposed to be invisible, showing only the content within them. I can get rid of the border, background, etc by setting them to Transparent. But whenever I MouseOver them the default windows hover effect shows the whole button again. I've tried numerous guides on custom controls, but ultimately cannot figure out how to override this. Basically my questions boil down to, how much of this can be placed in the generic.xaml file, what organization do I have to use within that file, and are there any other places that these styling should go instead? I do realize this is a very basic question, but it's just driving me nuts not being able to figure out the specific answer. Thanks!
Current xaml:
<Style TargetType="{x:Type local:TimePicker}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:TimePicker}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Height="{TemplateBinding Height}"
Width="{TemplateBinding Width}">
<StackPanel Orientation="Horizontal">
<StackPanel x:Name="PART_Root"
Orientation="Horizontal"
HorizontalAlignment="Center">
<ToggleButton x:Name="PART_HourButton"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="0"
Background="Transparent"
BorderBrush="Transparent"
BorderThickness="0"
Height="{Binding ElementName=PART_IncDecPanel, Path=ActualHeight}"
Width="{Binding ElementName=PART_HourButton, Path=ActualHeight}"
Content="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Hour}">
<ToggleButton.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Transparent" />
</Trigger>
</ToggleButton.Triggers>
</ToggleButton>
<Label x:Name="PART_HourMinSeparator"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="0"
Content=":" />
<ToggleButton x:Name="PART_MinButton"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="0"
Background="Transparent"
BorderBrush="Transparent"
BorderThickness="0"
Height="{Binding ElementName=PART_HourButton, Path=ActualHeight}"
Width="{Binding ElementName=PART_HourButton, Path=ActualWidth}"
Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Minute}" />
<StackPanel x:Name="PART_IncDecPanel" HorizontalAlignment="Center" VerticalAlignment="Center">
<Button x:Name="PART_IncreaseTime"
Background="Transparent"
BorderBrush="Transparent"
BorderThickness="0"
HorizontalAlignment="Center"
HorizontalContentAlignment="Center"
VerticalAlignment="Center"
VerticalContentAlignment="Center"
Margin="0"
Padding="0"
Width="22"
Height="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IncreaseImage.ActualHeight}">
<Image Source="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IncreaseImage}" />
</Button>
<Button x:Name="PART_DecreaseTime"
Background="Transparent"
BorderBrush="Transparent"
BorderThickness="0"
HorizontalContentAlignment="Center"
HorizontalAlignment="Center"
VerticalAlignment="Center"
VerticalContentAlignment="Center"
Margin="0"
Padding="0"
Height="{Binding ElementName=PART_IncreaseTime, Path=ActualHeight}"
Width="{Binding ElementName=PART_IncreaseTime, Path=ActualWidth}">
<Image Source="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DecreaseImage}" />
</Button>
</StackPanel>
</StackPanel>
</StackPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
WPF uses "lookless controls," which basically means that you can change the entire visual part (at design- or run-time) of a control without changing its code or the behavior of that code. You're already making use of this concept to create a default Style for your TimePicker control. If you were to remove the ControlTemplate from that Style, you would see nothing at runtime because the control itself is just the behavior defined in the C# or VB code.
Since it sounds like you want to keep the behavior of your buttons, but completely change the look, this is an ideal scenario for re-templating. Here's a very simple example that will show only the Content (in the ContentPresenter):
<Button Content="Hello Template">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</ControlTemplate>
</Button.Template>
</Button>
You will probably want to add some more to the template, like a Transparent Border to catch mouse input and maybe some Triggers. The way you're attempting to use a Trigger on the ToggleButton in your example is incorrect (FrameworkElement Triggers collection only works with EventTriggers), but inside a ControlTemplate or Style, that pattern will work.
If you want to apply the same Style to every Button inside your TimePicker ControlTemplate you can add a default Button Style to the Resources collection of your ControlTemplate:
<ControlTemplate TargetType="{x:Type MyControl}">
<ControlTemplate.Resources>
<Style TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ControlTemplate.Resources>
...
</ControlTemplate>
I'm using this sample to create a multi-column tree view and I've noticed that scrolling no longer works correctly for this list view:
After some playing around I've discovered that the bit that is breaking the scrollbars is the setting of the "Template" property for the TreeListView:
<Style TargetType="{x:Type l:TreeListView}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type l:TreeListView}">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<DockPanel>
<GridViewHeaderRowPresenter Columns="{StaticResource gvcc}" DockPanel.Dock="Top"/>
<ItemsPresenter/>
</DockPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Commenting out the above fixes the scrollbars (however obviously means that the grid column headers are not shown). In fact I've discovered that even the following template breaks the scrollbars:
<Style TargetType="{x:Type l:TreeListView}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type l:TreeListView}">
<ItemsPresenter/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Why is this?
I think this happens because you edit the template of the control defined by WPF.
and it's defined to have a scrollBar.
you override that template and don't add one.
i'm not 100% sure about that, but i'm wondering why are you messing with the Control Template to begin with?
maybe what you want to edit is the DataTemplate?
The DataTemplate decides how to present the object that is bound by Data Binding.
You need to implement your own scrollbars since you are overwriting the default template.
Wrap your ControlTemplate's ItemsPresenter in a ScrollViewer
In the end I solved this by adding in the scrollbars myself - initially I implemented this the nieve way and just got the original content to scroll, the I discovered that the horizontal scroll bar didn't work properly if I did that (the headers didn't scroll).
Instead I used the Control Template Reference to figure out what the base control does and did a variation on wjat the ListView does.
I can see now why I need to set the entire template when I do things like this - what I believed was simple actually turned out to be completely specific to my control.
Here is my Xaml:
<Style x:Key="{x:Static local:TreeListView.ScrollViewerStyleKey}" TargetType="ScrollViewer">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ScrollViewer">
<Grid Background="{TemplateBinding Background}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<DockPanel Margin="{TemplateBinding Padding}">
<ScrollViewer DockPanel.Dock="Top"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Hidden"
Focusable="false">
<GridViewHeaderRowPresenter Margin="2,0,2,0"
Columns="{Binding Path=TemplatedParent.Columns,
RelativeSource={RelativeSource TemplatedParent}}"
ColumnHeaderContainerStyle="{Binding
Path=TemplatedParent.View.ColumnHeaderContainerStyle,
RelativeSource={RelativeSource TemplatedParent}}"
ColumnHeaderTemplate="{Binding
Path=TemplatedParent.View.ColumnHeaderTemplate,
RelativeSource={RelativeSource TemplatedParent}}"
ColumnHeaderTemplateSelector="{Binding
Path=TemplatedParent.View.ColumnHeaderTemplateSelector,
RelativeSource={RelativeSource TemplatedParent}}"
AllowsColumnReorder="{Binding
Path=TemplatedParent.View.AllowsColumnReorder,
RelativeSource={RelativeSource TemplatedParent}}"
ColumnHeaderContextMenu="{Binding
Path=TemplatedParent.View.ColumnHeaderContextMenu,
RelativeSource={RelativeSource TemplatedParent}}"
ColumnHeaderToolTip="{Binding
Path=TemplatedParent.View.ColumnHeaderToolTip,
RelativeSource={RelativeSource TemplatedParent}}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</ScrollViewer>
<ScrollContentPresenter Name="PART_ScrollContentPresenter"
KeyboardNavigation.DirectionalNavigation="Local"
CanHorizontallyScroll="False"
CanVerticallyScroll="False" />
</DockPanel>
<ScrollBar Name="PART_HorizontalScrollBar"
Orientation="Horizontal"
Grid.Row="1"
Maximum="{TemplateBinding ScrollableWidth}"
ViewportSize="{TemplateBinding ViewportWidth}"
Value="{TemplateBinding HorizontalOffset}"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" />
<ScrollBar Name="PART_VerticalScrollBar"
Grid.Column="1"
Maximum="{TemplateBinding ScrollableHeight}"
ViewportSize="{TemplateBinding ViewportHeight}"
Value="{TemplateBinding VerticalOffset}"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type local:TreeListView}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TreeView">
<Border Name="Border" CornerRadius="1" BorderThickness="1">
<Border.BorderBrush>
<SolidColorBrush Color="{DynamicResource BorderMediumColor}" />
</Border.BorderBrush>
<Border.Background>
<SolidColorBrush Color="{DynamicResource ControlLightColor}" />
</Border.Background>
<ScrollViewer Style="{DynamicResource {x:Static local:TreeListView.ScrollViewerStyleKey}}">
<ItemsPresenter />
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The above required that I add some extra properties to the control itself:
public static ResourceKey ScrollViewerStyleKey
{
get
{
return new ComponentResourceKey(typeof(TreeListView), "TreeListView_ScrollViewerStyleKey");
}
}