Why ContentPresenter's render time is bigger than its children's sum? - c#

See the below picture:
I just used Performance Profiler in VS2017 and i found that the listBoxItem's ContentPresenter render time is so bigger than its children's.
I have to reduce total render time (which is 1.1s roughly).
Sum of ListBoxItems render time is also 1.1s.
I don't know why time difference is made.
The Listbox's visual tree is like this:
ListBox(3057)
Border(3056)
ScollViewer(3055)
Grid(3054)
ScrollContentPresenter(3031)
ItemsPresenter(3029)
VirtualizingStackPanel(3028)
ListBoxItem(120)
ListBoxItem(84) ...

I can reduce visual tree's Control.
The way that i do is "redefine some Control's ControlTemplate"
Before redefine ControlTemplate, my ListBoxItem have Bd(Border), ContentPresenter, Grid,, etc. like below
After redefine ControlTemplate like below xaml
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<ContentPresenter>
<ContentPresenter.Style>
<Style TargetType="{x:Type ContentPresenter}">
<Setter Property="VirtualizingPanel.IsVirtualizing" Value="True"/>
<Setter Property="VirtualizingPanel.VirtualizationMode" Value="Recycling"/>
</Style>
</ContentPresenter.Style>
</ContentPresenter>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
Then i can remove "Bd"(Border) like below.
ListBoxItem
ContentPresenter
Grid ...
To reduce render time, I will find useless Controls and remove.

Related

Override style on parts of ComboBox scrollbar

After lots of research, I stumbled across a relatively simple way to target just specific parts of the control style without using the entire control template. It's partially successful, but I need a little help getting all the way to the end.
Specifically, I am trying to override the Thumb button color of the scrollbar in the dropdown of a ComboBox. The cool technique I came across is the following, which utilizes nested Style.Resources to access the lower objects...
<Style x:Key="MyComboBoxStyle" TargetType="{x:Type ComboBox}">
<Style.Resources>
<Style TargetType="ScrollViewer">
<Style.Resources>
<Style TargetType="ScrollBar">
<Setter Property="Background" Value="LightGreen" />
<Style.Resources>
<Style TargetType="Track">
<Setter Property="Cursor" Value="Cross" />
<Style.Resources>
<Style TargetType="Thumb">
<Setter Property="Background" Value="Red"/>
<Setter Property="Cursor" Value="Hand" />
</Style>
</Style.Resources>
</Style>
<Style TargetType="RepeatButton">
<Setter Property="Background" Value="Red"/>
<Setter Property="Cursor" Value="Hand" />
</Style>
</Style.Resources>
</Style>
</Style.Resources>
</Style>
</Style.Resources>
<!--- rest of ComboBox style definition follows... -->
By sequentially drilling down into the complex control style tree, using nested Style.Resources, I am able to target specific aspects of a control style, without needing the entire style definition.
The xaml code above successfully drills all the way down to the "Track"... I can change things like the margin, cursor, etc. of the Track. But, I just can't seem to get that last step to the Thumb. Also, I can't seem to access the Repeat buttons, which should be at the same level (in the object tree) as the Track.
Looking at the style template for ScrollBars seems to show that the object tree is ScrollBar->Track->Thumb... but I seem to be missing something?
Any ideas on how to get access to the Thumb color?
The default style for the ScrollBar sets the Style property of the Thumb explicitly in the Track:
<Track x:Name="PART_Track" ...>
...
<Track.Thumb>
<Thumb Style="{StaticResource ScrollBarThumbVertical}"/>
</Track.Thumb>
</Track>
This means that your implicit Thumb style won't be applied.
So you will have to define a custom complete ControlTemplate for the ScrollBar to be able to modify the style/template of the Thumb.
Alternatively, you may consider to look it up in the visual tree at runtime and set any of its properties programmatically.

WPF Style at Windows or App level yields different results

I'm trying to learn Styling in WPF and encountered a funny thing:
There is a difference when I apply a style at application or (main) window level.
When I define the following resource in the App.xaml:
<Application.Resource>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="FontStyle" Value="Italic" />
</Style>
<Style TargetType="{x:Type GroupBox}">
<Setter Property="FontWeight" Value="Bold" />
</Style>
<Application.Resource>
the GroupBox caption is bold and italic.
When I instead define the styling in the MainWindow.xaml:
<Window.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="FontStyle" Value="Italic" />
</Style>
<Style TargetType="{x:Type GroupBox}">
<Setter Property="FontWeight" Value="Bold" />
</Style>
</Window.Resources>
The GroupBox caption box is only bold and not italic.
Can anybody explain this behavior?
In picking TextBlock you have unearthed something. TextBlock is not derived from Control, and thus behaves slightly differently.
See https://stackoverflow.com/a/27065140/4258144 :
there is a curious rule in WPF implicit styles are only inherited
across template boundaries by elements which inherit from the Control
class
I guess you can add to that, "unless it is globally specified in App.xaml".
UPDATE:
Following comments, here's a look at a GroupBox visual tree, taken from Snoop.

Set property in ContentPresenter child control

I want to set TextTrimming on TextBlock.
<Style TargetType="{x:Type dg.CellValuePresenter}">
<Setter Property="ContentTemplate" Value="{StaticResource Tmp}" />
</Style>
My template:
<DataTemplate x:Key="Tmp">
<ContentPresenter Content="{Binding}" >
<ContentPresenter.Resource>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="TextTrimming" Value="CharacterEllipsis"/>
</Style>
</ContentPresenter.Resource>
</ContentPresenter>
</DataTemplate>
Content Presenter is XamTextEditor from Infragistic:
<Style TargetType="{x:Type igEditors:XamTextEditor}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type igEditors:XamTextEditor}">
<TextBlock/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Setter from DataTemplate doesn't work. Do you know how to set this property?
How can I set TextTrimming property in Textblock of XamTextEditor cudtom style? I cannot do this in this style because it is used in other datatemplates where texttrimming must be turn off. So I tried to set it in DataTemplate but it not work (i see in snoop that it is set to none)
Unfortunately I cannot show more code because I don't have access to internet on dev and write down more code is time consuming :/
I'm not sure if I get your problem completely.
But If you are using explicit column definition. Then instead of CellvaluePresenter try create a EditorStyle For any column type(I've done it for string type column so the editor would be XamTextEditor)
<!--(xmlns:igWindows="http://infragistics.com/Windows")-->
<Style TargetType="{x:Type igEditors:XamTextEditor}" x:Key="DefaultXamDateTimeEditor">
<Style.Resources >
<Style TargetType="{x:Type igWindows:SimpleTextBlock}" >
<Setter Property="TextTrimming" Value="CharacterEllipsis" />
</Style>
</Style.Resources>
</Style>
And use this style as columns EditorStyle. It should work in XamDatagrid as this is working for me. Please post specific situation If I didn't get the question right.

WPF using style that contains another style

I'm trying to make a progress bar style that is re-usable.
So the idea here is very simple. I have a style already with target type ProgressBar, and it's just a spinny circle that fills as it goes from 0-100%. However, in order to make it re-usable and modular, I do not want to hard-code the text that goes along with it - it should be optional.
So I want to create another style that DOES include text "Downloading... X/Y MB". For this I take Value for X, Maximum for Y, and Tag for the unit. I want to include the same spinny circle thingy for the graphical part on the left. How can I do this? With BasedOn property, I think you can only set something already there to be different. What if I want to add additional elements (like textblocks in this case)?
If only text value differentiates then within style you can bind propertie's value to parent's property like Tag where at every single either style or element you adjust it to specific requirement.
<Window.Resources>
<Style x:Key="FirstButtonStyle" TargetType="Button">
<Setter Property="Content" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<ContentPresenter/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="SecondButtonStyle" TargetType="Button" BasedOn="{StaticResource FirstButtonStyle}">
<Setter Property="Content" Value="2"/>
</Style>
</Window.Resources>
<StackPanel>
<Button Style="{StaticResource FirstButtonStyle}"/>
<Button Style="{StaticResource SecondButtonStyle}"/>
</StackPanel>
The outcome is 1 and 2. If your intent is to inject some UI element within style then there is no such an option, alas. Style needs to be rewritten once again.

GridViewColumn content and VerticalAlignment

i want to display some information in a listview using the GridView.
i have several GridViewColumns and everything works fine.
However, want the GridViewColumns content to have a VerticalAlignment (Top in this case)
but the gridvewcolumn intself doesnt offer a VerticalContentAlignment dependency property.
when using DisplayMemberBinding there is also no possibility to supply
VerticalAlignment information.
When using a custom DataTemplate as Celltemplate, i can add a VerticalAlignment="top" dp to e.g. some textblock. however this does not work.
is there any "nifty-grifty special magic trick" to fullfill this tasK?
(
You can apply this style to your ListView:
<Style TargetType="{x:Type ListView}">
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="ListViewItem">
<Setter Property="VerticalContentAlignment" Value="Top"/>
</Style>
</Setter.Value>
</Setter>
</Style>

Categories