Set Style of ComboBoxItem = null, but programmatically - c#

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)));

Related

Lost previous combobox item style after applying style for cursor on hover

I want all clickable elements in the app to have hand cursor on hover. My problem is in comboboxes: all of them apply default (or what?) style when I set my custom style below (but hand cursor works!):
<Style x:Key="ComboBoxItemStyle" TargetType="ComboBoxItem">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Cursor" Value="Hand"/>
</Trigger>
</Style.Triggers>
</Style>
<StackPanel Grid.Column="1" HorizontalAlignment="Right" Orientation="Horizontal">
<TextBlock Style="{StaticResource OptionTextBlockStyle}" />
<ComboBox x:Name="SortTypesComboBox" FontSize="14px" DisplayMemberPath="Description" ItemContainerStyle="{StaticResource ComboBoxItemStyle}">
</ComboBox>
</StackPanel>
The first image is what I want but with hand cursor on clickable items, the second one is what I actually have applying my comboboxitemstyle.
I don't know why I lost my previous style using this line ItemContainerStyle="{StaticResource ComboBoxItemStyle}. How can I save it and make right cursor on hover at the same time?
---UPG----
I've just added BasedOn="{StaticResource {x:Type ComboBoxItem}}" line and this didn't help me much. Now I have my items with wrong style and green lightning:
The way that you define your style overrides the default style for ComboBox. Instead, you should base your style on the default style using the BasedOn property.
<Style x:Key="ComboBoxItemStyle"
TargetType="ComboBoxItem"
BasedOn="{StaticResource {x:Type ComboBoxItem}}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Cursor" Value="Hand"/>
</Trigger>
</Style.Triggers>
</Style>
The reason for referencing the default style with {x:Type ComboBoxItem} is that it is an implicit style, which gets applied automatically to each control of that type in scope unless a different style is assigned explicitly and the x:Key of an implicit style is their TargetType.

Wpf Custom ListBox with Rounded Border

I have extended ListBox control and wanted to give it rounded corner so I have applied styles as below and it works fine:
<control:MultiSelectionListBox SelectionMode="Extended" ItemsSource="{Binding Offerables,Mode=TwoWay}"
SelectedItemsList="{Binding SelectedOfferables, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" DisplayMemberPath="Name"
Grid.Row="6" Grid.Column="0" MaxHeight="150">
<control:MultiSelectionListBox.Resources>
<Style TargetType="Border">
<Setter Property="CornerRadius" Value="5"></Setter>
</Style>
</control:MultiSelectionListBox.Resources>
</control:MultiSelectionListBox>
but I have too many Listboxes and I don't wanted to add style in each and every control individually.
I wanted to define this style in app.xaml and wanted to reuse that design by name like Style = "{StaticResource RoundedListBoxStyle}".
I have tried like below in app.xaml but with no luck
<Style TargetType="ListBox" x:Key="RoundedListBoxStyle">
<Setter Property="Border" Value="10"></Setter>
</Style>
The member Border is not recognized or is not accessible.
Please guide me what I am doing wrong here.
Finally I managed to do that as Bradley Uffner mentioned in the comment Border is not the property of the ListBox and we cannot use it in style like that. I used Style.Resource and mentioned Style for Border elements as below:
<Style TargetType="ListBox" x:Key="RoundedListBoxStyle">
<Style.Resources>
<Style TargetType="Border">
<Setter Property="CornerRadius" Value="5"></Setter>
</Style>
</Style.Resources>
</Style>
and it worked. :)

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.

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 TreeViewItem dyanmic context menu

I'm having some trouble with a databound TreeView in WPF, basically I want a context menu to be databound to an IEnumerable property on my TreeViewItem ViewModel, this is what I'm trying to do in the of each TreeViewItem:
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu ItemsSource="{Binding ContextMenu}" />
</Setter.Value>
but it gives me an exception when loading the xaml saying it can't set ContextMenu on System.Object or something along those lines.
Can anyone shed some light on this?
Thanks
declare it as resource in your style and then assign it to Value as StaticResource
<Style>
<Style.Resources>
<ContextMenu x:Key="contextmenustyle" ItemsSource="{Binding ContextMenu}" />
</Style.Resources>
<Setter Property="ContextMenu" Value="{StaticResource contextmenustyle}">
</Style>

Categories