I have two combo boxes: CarTypeComboBox and SeriesComboBox.
Issues: 1. I want the SeriesCombox to be visible only when the user select BMW. 2. System.Windows.Style is showing up in SeriesComboBox.
Thank you
Complete Code:
<Window x:Class="StyleTrigger.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:StyleTrigger"
xmlns:local2="clr-namespace:ComboBoxData"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources >
<local2:ComboBoxItemCollection x:Key="CarItemsCollection"/>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50*" />
<ColumnDefinition Width="50*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="1" Grid.Column="0" >
<Label x:Name="CarBrand" Height="30" Width="75" Margin="10,0,0,0" Content="Car Brand"
HorizontalAlignment="Left" VerticalAlignment="Top"/>
<ComboBox x:Name="CarTypeComboBox" Margin="10,0,0,0" Width="100" Height="30" HorizontalAlignment="Left" VerticalAlignment="Top"
ItemsSource="{Binding Mode=OneWay, Source={StaticResource CarItemsCollection}}"
DisplayMemberPath="CarType"
SelectedValuePath="CarID"
/>
</StackPanel>
<StackPanel Grid.Row="1" Grid.Column="1" >
<Label x:Name="CarSeries" Height="30" Width="75" Margin="10,0,0,0" Content="Car Series"
HorizontalAlignment="Left" VerticalAlignment="Top"/>
<ComboBox x:Name="SeriesComboBox" Margin="10,0,0,0" Width="100" Height="30"
HorizontalAlignment="Left" VerticalAlignment="Top">
<sys:String>230</sys:String>
<sys:String>280</sys:String>
<sys:String>530</sys:String>
<Style TargetType="ComboBox">
<Setter Property="Visibility" Value="Hidden" />
<Style.Triggers>
<DataTrigger Binding="{Binding SelectedItem.CarType, ElementName=CarTypeComboBox}" Value="BMW">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ComboBox>
</StackPanel>
</Grid>
</Window>
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ComboBoxData
{
class SingleComboBoxItem
{
public SingleComboBoxItem(int pCarID,String pCarBrand)
{
CarID = pCarID;
CarType = pCarBrand;
}
public string CarType { get; set; }
public int CarID { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ComboBoxData
{
class ComboBoxItemCollection : ObservableCollection<SingleComboBoxItem>
{
public ComboBoxItemCollection() : base()
{
Add(new SingleComboBoxItem(1,"Honda"));
Add(new SingleComboBoxItem(2,"Toyota"));
Add(new SingleComboBoxItem(3,"BMW"));
Add(new SingleComboBoxItem(4,"Dodge"));
Add(new SingleComboBoxItem(5,"Lexus"));
}
}
}
Your ComboBox style should look like this:
<Style TargetType="ComboBox">
<!-- Just add this one Setter -->
<Setter Property="Visibility" Value="Hidden" />
<Style.Triggers>
<DataTrigger Binding="{Binding SelectedItem.CarType, ElementName=CarTypeComboBox}" Value="BMW">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
Do not set the Visibility
attribute on the ComboBox
tag itself. No Visibility="Hidden"
on the ComboBox
. That will override the style setters and it will never be visible. ONLY set Visibility
in setters in the style.
Now that I've seen the whole code, I can offer a little more insight. First, you said "The SeriesComboBox is not appearing when I select BMW.", but what's happening in the version you just posted is that it is not disappearing when you don't select BMW. Now, let's take a look at what it does do:
There's an anomaly in that dropdown list: The last item is System.Windows.Style
. I'm willing to bet you haven't ever seen that model of BMW on the road any more than I have.
Your Style
is correctly defined, and I think it may have been correct even before we started hassling you about it. The trouble is you aren't assigning it to the Style
property of the ComboBox
. Instead you're adding it to the default content property, which in the case of ComboBox
is Items
. In WPF, you can throw literally almost figuratively just about anything at all in a ComboBox
(or ListBox
) items collection. It's a collection of object
. It'll eat any old garbage you feed it and never complain. Since you didn't specify DisplayMemberPath
for that one, it just cheerfully calls ToString()
on each object in turn.
So to assign the style to the Style
property of the ComboBox
, put it inside <ComboBox.Style>
:
<ComboBox
x:Name="SeriesComboBox"
Margin="10,0,0,0"
Width="100"
Height="30"
HorizontalAlignment="Left"
VerticalAlignment="Top">
<sys:String>230</sys:String>
<sys:String>280</sys:String>
<sys:String>530</sys:String>
<ComboBox.Style>
<Style TargetType="ComboBox">
<Setter Property="Visibility" Value="Hidden" />
<Style.Triggers>
<DataTrigger
Binding="{Binding SelectedItem.CarType, ElementName=CarTypeComboBox}"
Value="BMW"
>
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ComboBox.Style>
</ComboBox>
You could also define the Style
in Resources
, give it x:Key="SeriesComboBoxStyle"
, and set the Style
attribute on the ComboBox
tag: Style="{StaticResource SeriesComboBoxStyle}"
.