Override ComboBox Styles? - c#

I have a Style in Window.Resources applied to all the ComboBox in the application. However, I have come across a situation where I need the styles in the Window.Resources applied to the ComboBox, but I need to disable one feature I have specifically set in the styles.
I want to be able to enter text into one ComboBox in the application.
Being that the ComboBox text editable part is actually a TextBox I set disabled the TextBox altogether: This style is specifically for the ComboBox style I have,
<Style x:Key="ComboBoxTextBoxStyle" TargetType="{x:Type TextBox}">
<Setter Property="IsEnabled" Value="False" />
<....More setters etc
I have also set in the ComboBox styles IsEditable to false. I had to apply this style to both the TextBox part of the ComboBox to the style work correctly. I have also included the code pointing to the static resource to x:Key="ComboBoxTextBoxStyle" shown above:
<Style TargetType="{x:Type ComboBox}">
<Setter Property="IsEditable" Value="False" />
<...More setter's
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBox}">
<TextBox Style="{StaticResource ComboBoxTextBoxStyle}"
<...More styles applied here
So now I have a ComboBox that I want to be able to enter text into, so I set the XAML to this,
<ComboBox x:Name="Cmb" IsEditable="True"
ItemsSource="{Binding Source={x:Static viewModels:ShiftManagerViewModel.MyBindingList}}"
SelectedItem="{Binding UpdateSourceTrigger=PropertyChanged, Path=MySeletcProperty}" />
But, the ComboBox is not able to be able to enter text even though I have set the actuall ComboBox to IsEditable="True".
How do I override the styles to allow this one ComboBox enter text?

You would have to create a new Style which will inherit from that Style that already exists and apply it to that particular combox box, style would be like:
A better apporach is that your TextBox element in Style Template for ComboBox IsEnabled property should have binding to ComboBox IsEditable property :
<Style x:Key="ComboBoxTextBoxStyle" TargetType="{x:Type TextBox}">
<Setter Property="IsEnabled"
Value="{Binding Path=IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" />
and then in xaml consuming side you can specify this style :
<ComboBox x:Name="Cmb" IsEditable="True"
ItemsSource="{Binding Source={x:Static viewModels:ShiftManagerViewModel.MyBindingList}}"
SelectedItem="{Binding UpdateSourceTrigger=PropertyChanged, Path=MySeletcProperty}" />

Related

Binding style property outside itemsource?

I've a combobox like this:
<ComboBox x:Name="CountryMenuComboBox"
ItemsSource="{Binding Countries}">
<ComboBox.ItemContainerStyle>
<Style>
<Setter Property="IsEnabled" Value="{Binding IsRemoving}" />
</Style>
</ComboBox.ItemContainerStyle>
what I need to do is enable or disable the items inside the combobox using the property IsRemoving, but this property isn't located inside the itemsource Countries, so I need to access outside the itemsource. How can I do this for a style?
Is IsRemoving a property of the parent viewmodel that owns the Countries property? If so, try <Setter Property=“IsEnabled” Value=“{Binding DataContext.IsRemoving, RelativeSource={RelativeSource AncestorType=ComboBox}}” />

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

How do you style a single TextBox among others?

I have a WPF textbox among others that I would like to create a style for.
This style should only apply to this type of textbox.
Here is my textbox:
<TextBox Text="{Binding DeviceInformation.SerialNumber, Mode=OneWay}" BorderThickness="0" Background="Transparent" IsReadOnly="True"/>
My text box basically simulates a label I can copy.
How do I make this into a style and target only this textbox?
If you set Key property on your Style definition, then it will be applied only on TextBoxes that have set this Style. Style={StaticResource=ExampleKey}
Example:
<Window.Resources>
<Style TargetType="TextBox" x:Key="ExampleStyle">
<Setter Property="BorderThickness" Value="0"></Setter>
</Style>
</Window.Resources>
You can also have application-wide styles defined in App.xaml

check checkbox when item selected in listview UWP

I am writing a UWP app with a listview. The listviewitems contain a textblock and a checkbox. When the listviewitem is selected, I would like the checkbox to check/uncheck. I would also like to remove the "selected" animation, where the listviewitem turns blue when it is selected.
I have found different solutions, but they all seem to rely on the use of Triggers, which Visual Studio tells me is not available in UWP.
How can I solve this, without triggers in UWP?
My listview:
<ListView Name="ListViewItems" Grid.Row="2">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Margin" Value="0,0,0,1"></Setter>
<Setter Property="Background" Value="White"></Setter>
<Setter Property="Padding" Value="5"></Setter>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Grid Padding="5,0">
<CheckBox HorizontalAlignment="Right" VerticalAlignment="Center" Name="CheckBoxItem"></CheckBox>
<TextBlock HorizontalAlignment="Left" VerticalAlignment="Center" Name="TextblockItem" Text="{Binding}"></TextBlock>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
When the listviewitem is selected, I would like the checkbox to check/uncheck.
You can directly binding the IsChecked property to the CheckBox to the ListViewItem IsSelected property:
<CheckBox
HorizontalAlignment="Right"
Margin="10"
VerticalAlignment="Center"
IsChecked="{Binding IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListViewItem}}}"
Name="CheckBoxItem">
</CheckBox>
Whenever the IsSelected Property of ListViewItem change, the CheckBox will be checked/unchecked.
I would also like to remove the "selected" animation, where the
listviewitem turns blue when it is selected.
The code below can help you achieve this, BUT, it overrides the Template of the Item, which means that you have to write your own template.
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
If your ItemSource of the ListView is bound to a collection on a ViewModel, I would suggest you add a bool to the item class of the collection.
So for example if you are showing Persons, add a bool IsSelected field to the Person class.
You can then use this field to bind it to the IsChecked prop of the checkbox in your view, only thing needed to do is be sure to set the Mode=TwoWay
Last thing left to do is toggle this IsSelected field, you do this by binding the SelectedItem of the ListView to a Person property on your ViewModel and each time this is being called ( setter of the property ), toggle the given IsSelected field.
To override the change in colour when an item is selected of the ListView, you need to get a copy of the ListView template and delete the colour setting in the selected state

WPF Listview & Checkboxes - Binding issue when using relative source

I have a listview with two columns, one contains a textbox and the other a checkbox. These are bound to an ObservableCollection of a custom object containing a string for the textbox and a boolean for the checkbox.
All was working well until I tried having the check event of the checkbox highlight it's the row in the listview as in this article.
My problem is that checkbox no longer binds to the ObservableCollection. The textbox binds okay, but changing the checbox declaration from:
<CheckBox IsChecked="{Binding RestrictedEdit}"/>
to this:
<CheckBox IsChecked="{Binding RestrictedEdit, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListViewItem}}}"/>
stops the checkbox binding and the listview is displayed with the checkboxes all unchecked irrespectivate of status of the boolean. What am I doing wrong?
You are trying to bind to RestrictedEdit property, which ListViewItem doesn't have. This property is declared in view model, which is stored in DataContext, so this should work:
<CheckBox IsChecked="{Binding DataContext.RestrictedEdit,
RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type ListViewItem}}}"/>
However, I don't see any reason to use this code instead of simple IsChecked="{Binding RestrictedEdit}". CheckBox inherits DataContext from ListViewItem, so there is no reason to use relative source.
Let the binding as it is (no RelativeSource) and use rather a style or a DataTemplate having your custom object class as TargetType, and with a DataTrigger set on RestrictedEdit.
example with style :
<Style x:Key="MyStyle" TargetType="MyClass">
<Setter Property="BackGround" Value="White" />
<Style.Trigger>
<DataTrigger Binding="{Binding RestrictedEdit}" Value="False">
<Setter Property="BackGround" Value="Gray" />
</DataTrigger>
</Style.Trigger>
</Style>
Define this style, say, in your application resources (in App.xaml).
Then in your listview, use :
ItemContainerStyle="{StaticResource MyStyle}"

Categories