Wpf Custom ListBox with Rounded Border - c#

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. :)

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.

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

How to make DataGrid transparent?

How to make DataGrid transparent?
I'm trying to use Background of DataGrid itself, but this doesn't seem to work.
UPD I need only background and borders transparent, not everything! Text should be visible.
So, my solution... use both Background="Transparent" and RowBackground="Transparent"
Have you tried setting the Opacity property to 0.0 ?
A value of 0.0 makes the element
completely transparent
<DataGrid
Background="Transparent" RowBackground="Transparent">
</DataGrid>
Try this:
Background="Transparent" RowBackground="Transparent"
and
<DataGrid.ColumnHeaderStyle>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="FontWeight" Value="Bold" />
</Style>
</DataGrid.ColumnHeaderStyle>
<DataGrid.RowHeaderStyle>
<Style TargetType="{x:Type DataGridRowHeader}">
<Setter Property="Background" Value="Transparent" />
</Style>
</DataGrid.RowHeaderStyle>
It's an undocumentd feature but if you set the visability to Hidden it's the same as setting the element to transparent.
I'm not sure which background you are trying to change, but you can set any background by overriding the DataGrid's ControlTemplate. Your best bet is probably to copy the default DataGrid ControlTemplate from here and then modify the necessary background to match your needs.
When you inicialize datagrid put this tag GridLinesVisibility with argument None
For example:
<DataGrid GridLinesVisibility="None"/>

disable wpftoolkit chart datapoint

Does anybody know how to turn off the datapoints for a noraml LineSeries in a WPFToolkit chart? I find them to be very annoying, and not useful to my purposes, but I can't find a simple property or anything like that on the class itself.
You want to hide them?
It is possible if to set the empty ControlTemplate to the Template property.
Here is the example:
<Window.Resources>
<Style x:Key="InvisibleDataPoint" TargetType="{x:Type charting:DataPoint}">
<Setter Property="Background" Value="Blue"/>
<Setter Property="Template" Value="{x:Null}"/>
</Style>
</Window.Resources>
<Grid>
<charting:Chart>
<charting:LineSeries ItemsSource="{Binding ChartItems}" IndependentValuePath="XValue" DependentValuePath="YValue"
DataPointStyle="{StaticResource InvisibleDataPoint}"/>
</charting:Chart>
</Grid>
And although the points are invisible, you can set other properties, like Background and change the look of chart.

Categories