Set property in ContentPresenter child control - c#

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.

Related

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

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.

Trying to apply multiple styles to a DataGridRow

I have WPF application, i created DataGrid style in App.xaml to apply whole application.
App.xaml
<Style TargetType="DataGrid" x:Key="GridStyle1">
<Setter Property="HorizontalGridLinesBrush" Value="LightGray" />
<Setter Property="VerticalGridLinesBrush" Value="LightGray" />
<Setter Property="AlternatingRowBackground" Value="WhiteSmoke" />
<Setter Property="RowHeight" Value="30" />
<Setter Property="RowStyle">
<Setter.Value>
<Style TargetType="DataGridRow">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Cyan" />
</Trigger>
</Style.Triggers>
</Style>
</Setter.Value>
</Setter>
</Style>
Then in window :
window1.xaml
<Style TargetType="DataGridRow" BasedOn="{StaticResource {x:Type DataGridRow}}">
<Setter Property="FontStyle" Value="Italic" />
</Style>
The problem that window style does not apply ( font style not italic )
It looks like you want to apply a global style to every DataGridRow in every DataGrid in multiple windows, and you also want to apply additional styling to DataGridRow in one or more DataGrids in one particular window.
If you've learned CSS before, you may expect stylesheets to be cumulative: In CSS, if you apply tr.style1 globally and tr.style2 locally, you get both, with tr.style2 winning the toss in any cases where they set the same attribute.
That's not how styles work in XAML. In XAML, an element may inherit styling from its parent, but it can have at most one Style of its own. Additionally, as you've found, Style has a BasedOn property. You can base one style on another, and get the cumulative effects of both.
Lastly, there are several ways to apply a style. You've found that you can apply them to every element of a given type in a given scope.
Unfortunately, because everything depends on context, the way XAML styles are applied can be very confusing at first (and at second, and sometimes third). Particularly when you are using one style (GridStyle1) to apply another style. It's not always obvious what overrides what.
It's best to keep things as simple as possible. We'll get rid of that RowStyle setter, because we don't need it. We'll just create a global DataGridRow Style that applies by default to every DataGridRow everywhere, and then we'll override that specifically in window1.xaml.
App.xaml
<Application.Resources>
<Style TargetType="DataGridRow" BasedOn="{StaticResource {x:Type DataGridRow}}">
<Setter Property="Background" Value="Cyan" />
</Style>
</Application.Resources>
window1.xaml
<Window.Resources>
<Style TargetType="DataGridRow" BasedOn="{StaticResource {x:Type DataGridRow}}">
<Setter Property="FontStyle" Value="Italic" />
</Style>
</Window.Resources>
That will apply to every DataGridRow in that window. The BasedOn attribute there will refer to whatever style has already been defined for DataGridRow in any containing context -- commonly, that means App.xaml, and if we don't add anything else, that'll be the case here.
The difference between this and what you had is that you were applying the Cyan Background style in a different way: The DataGridRow style you applied in App.xaml was applied via the RowStyle setter on your DataGrid style. That style was BasedOn WPF's pre-existing default Style for DataGridRow, and then it was forcibly applied to every DataGridRow in every DataGrid that used the GridStyle1 style.
The DataGridRow style you defined in window1.xaml would have applied, if DataGrid.RowStyle hadn't already been set in GridStyle1.
But as we've seen, you don't need to use RowStyle to apply a style globally to every DataGridRow. You can do that with the default style for that type, as in my App.xaml fragment above. DataGrid.RowStyle is useful for individually overriding the global DataGridRow style on one particular DataGrid. But you don't want to do that globally! So your styles in App.xaml should look like this:
App.xaml
<Style TargetType="DataGrid" x:Key="GridStyle1">
<Setter Property="HorizontalGridLinesBrush" Value="LightGray" />
<Setter Property="VerticalGridLinesBrush" Value="LightGray" />
<Setter Property="AlternatingRowBackground" Value="WhiteSmoke" />
<Setter Property="RowHeight" Value="30" />
</Style>
<Style TargetType="DataGridRow" BasedOn="{StaticResource {x:Type DataGridRow}}">
<Setter Property="Background" Value="Cyan" />
</Style>
And again, here's the Style in window1.xaml
<Style TargetType="DataGridRow" BasedOn="{StaticResource {x:Type DataGridRow}}">
<Setter Property="FontStyle" Value="Italic" />
</Style>
Extra Credit
The styles above should solve your problem.
But there are other ways to approach this stuff. Unless you're very comfortable with what we did above, what follows may just add confusion, so if you start reading this and you find that the more you read, the less you understand -- then stop reading! It can wait!
You could also make all text in a DataGrid be italic, but that changes the headers too so I don't think it's what you want:
<DataGrid
FontStyle="Italic"
/>
If you want to apply that Italic style on just one grid in window1.xaml, here's how to do that. If we add an x:Key attribute to a Style, it won't be applied to every DataGridRow in scope. Instead, it's just sitting there, waiting to be used by name as a StaticResource.
window1.xaml
<Window.Resources>
<Style x:Key="ItalicDataGridRowStyle"
TargetType="DataGridRow" BasedOn="{StaticResource {x:Type DataGridRow}}">
<Setter Property="FontStyle" Value="Italic" />
</Style>
</Window.Resources>
<-- ... -->
<!-- One grid with italic rows -->
<DataGrid
x:Name="dataGrid1"
RowStyle="{StaticResource ItalicDataGridRowStyle}"
/>
<!-- And another grid with default rows -->
<DataGrid
x:Name="dataGrid2"
/>
And here's another way to apply styling to the rows in just one grid in window1.xaml:
<!-- Yet another grid -->
<DataGrid
x:Name="dataGrid3"
>
<DataGrid.RowStyle>
<Style TargetType="DataGridRow" BasedOn="{StaticResource ItalicDataGridRowStyle}">
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Background" Value="Wheat" />
</Style>
</DataGrid.RowStyle>
</DataGrid>
Finally, you could have set RowStyle in GridStyle1, and then explicitly set RowStyle on specific grids in specific windows, as above. That would work. You could have also created a new DataGrid style in window1.xaml (based on GridStyle1) which set RowStyle to something else.

Binding to value of property from inside style template failing

I'm having an issue with attempting to bind the Fill property of an Elipse (in a ToggleButton control) to a custom DependencyProperty of another control.
Below is the XAML code raising the "Property path is not valid" error - It's a Resource dictionary file for the Expander control.
The erroneous line:
Value="{Binding Path=(local:Expander.ToggleButtonMouseoverColor)}"
The first code block - the MixSelectorExpanderButtonStyle is attached to a style definition for an expander, seen in the second code block.
<Style x:Key="MixSelectorExpanderButtonStyle" TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="Circle" Property="Fill" Value="{Binding Path=(local:Expander.ToggleButtonMouseoverColor)}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I'm confident the property is correct - in the same file, I am able to access the ToggleButtonMouseoverColor property without error:
<Style TargetType="{x:Type local:Expander}">
<Style.Triggers>
<Trigger Property="Status" Value="0">
<Setter Property="ToggleButtonMouseoverColor" Value="{DynamicResource ZKGeneric_Highlight_MouseOver}" />
</Trigger>
</Style.Triggers>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Expander}">
<ToggleButton style=""{StaticResource MixSelectorExpanderButtonStyle}" />
</ControlTemplate>
</Setter.Value>
</Setter.Value>
</Style>
When I remove the local: prefix from the path, the error changes to the property not being recognized or accessible.
If I name the style definition and change the binding to:
Value="{Binding Path=ExpanderStyle.ToggleButtonMouseoverColor}"
I am able to build and run it, however it appears to just be a null value.
Clearly I'm missing some syntax to properly point to the property, but this is the first time i have attempted to bind in such a convoluted manner.
If not, is there a more optimal way to define this behaviour?
Any help would be appreciated, in the meantime, I shall attempt to consult my WPF programmer's reference.
EDIT:
I forgot to mention, I have also been trying to use Value="{Binding ToggleButtonMouseoverColor, RelativeSource={RelativeSource TemplatedParent}}", among other variations, but can't seem to get it working.
I believe you want this, although it sounds like you've potentially tried it? I have no idea why it wouldn't work...
Value="{Binding ToggleButtonMouseoverColor, RelativeSource={RelativeSource AncestorType={x:Type local:Expander}}}"

Set Style of ComboBoxItem = null, but programmatically

I have in my XAML the following lines as Window.Resources:
<Style TargetType="{x:Type ComboBoxItem}">
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="pics/greenbutton.png" />
</Setter.Value>
</Setter>
<Setter Property="Foreground" Value="White" />
</Style>
In my Window are several ComboBoxes where this is good. But I have one, where it is disturbing, so I wanted to set the style to null. I already put a Style="{x:Null}" inside the XAML-ComboBox. That gives the ComboBox itself a good view, but not the open Box (i.e. the ComboBoxItems). I use a DataBinding inside the Code-Behind, so how can I delete the window-style for the ComboBoxItems?
You should add to ComboBox resources empty style with target type ComboBoxItem.
You can do this in the XAML like this:
<ComboBox x:Name="myComboBox" ...>
<ComboBox.Resources>
<Style TargetType="ComboBoxItem">
</Style>
</ComboBox.Resources>
...
</ComboBox>
Or you can do this in the code-behind using following code:
myComboBox.Resources.Add(typeof(ComboBoxItem), new Style(typeof(ComboBoxItem)));

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