I have been trying to develop a bar of RadioButtons (styled as ToggleButtons) which select which content is displayed in a ContentControl. I have been able to use a DataTrigger to display the proper view in the ContentControl based on which RadioButton is checked, but I am also trying to bind a view model from the parent DataContext into the child's DataContext, without success. A minimum sample is as follows:
<Window x:Class="WpfApplication1.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:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" VerticalAlignment="Top" >
<RadioButton Name="rbShowChild" Content="Show Child" Style="{StaticResource {x:Type ToggleButton}}" />
</StackPanel>
<ContentControl Grid.Row="1">
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked, ElementName=rbShowChild}" Value="True">
<Setter Property="Content">
<Setter.Value>
<local:ChildView DataContext="{Binding ChildViewModel, PresentationTraceSources.TraceLevel=High}"/>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</Grid>
</Window>
The Binding to the ChildViewModel seems to be the part that is not working as expected. For completeness, here is the related ChildView.
<UserControl x:Class="WpfApplication1.ChildView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<StackPanel>
<TextBlock Text="Child" />
<TextBlock Text="{Binding Text}" />
</StackPanel>
</Grid>
</UserControl>
And the ViewModels:
namespace WpfApplication1
{
public class ChildViewModel
{
public string Text { get; set; }
public ChildViewModel()
{
Text = "It works!";
}
}
public class MainWindowViewModel
{
public ChildViewModel ChildViewModel { get; set; }
public MainWindowViewModel()
{
ChildViewModel = new ChildViewModel();
}
}
}
And the MainWindow DataContext is set as follows:
var window = new MainWindow()
{
DataContext = new MainWindowViewModel()
};
window.Show();
The Output window (with PresentationTraceSources.TraceLevel=High) shows this:
System.Windows.Data Error: 3 : Cannot find element that provides DataContext. BindingExpression:Path=ChildViewModel; DataItem=null; target element is 'ChildView' (Name=''); target property is 'DataContext' (type 'Object')
which leads me to think that somehow the MainWindow.DataContext is not the DataContext used to resolve the "{Binding ChildViewModel}" expression in the trigger, but I couldn't find any DataContext property on the trigger, nor have I been able to find anything in my searches to suggest an answer for this.
I would very much appreciate any suggestions to resolve this.
UPDATE: Looks like the issue is with how you are setting the data context.
Set the DataContext of the window in the XAML, then set the data context of the ContentControl to the ChildViewModel. Then set the actual displayed Content (AKA ChildView) Value. The ContentControl is the host of this view, so it should be the DataContext supplier. I myself am a little unsure the exact mechanics going on, but I know for fact the below code works.
NOTE Your XML namespaces may vary from the code below. Adjust accordingly.
<Window.DataContext>
<!-- Data Context added here OR in code-behind initialize-->
<local:MainWindowViewModel/>
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" VerticalAlignment="Top" >
<RadioButton Name="rbShowChild" Content="Show Child" Style="{StaticResource {x:Type ToggleButton}}" />
</StackPanel>
<!-- Bind the ContentControls Data context-->
<ContentControl DataContext="{Binding ChildViewModel}" Grid.Row="1">
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked, ElementName=rbShowChild}" Value="True">
<Setter Property="Content">
<Setter.Value>
<!-- Just simply set the view content here, no binding.-->
<local:ChildView />
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</Grid>
Doing this, I have run your application just fine in a project.
Related
I am not successful at getting my DataTrigger to work for binding to enum.
Each line in the ListBox is 'S', just as in the default Setter
XAML:
<Window x:Class="BindToEnumTest.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:BindToEnumTest"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<ListBox Grid.Column="0" x:Name="LBMain" ItemsSource="{Binding}" ScrollViewer.VerticalScrollBarVisibility="Auto">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Grid.Column="0" x:Name="TxtType">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Text" Value="S" />
<Style.Triggers>
<DataTrigger Binding="{Binding Type}" Value="TypeEnum.User">
<Setter Property="Text" Value="U"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Window>
Code:
namespace BindToEnumTest
{
public enum TypeEnum { None, System, User }
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public Collection<TypeEnum> TypeList = new() { TypeEnum.System, TypeEnum.User, TypeEnum.System, TypeEnum.User };
public MainWindow()
{
InitializeComponent();
LBMain.DataContext = TypeList;
}
}
}
I have tried using 'TypeEnum.User' and 'User' in the DataTrigger - no help.
Using Text="{Binding}" in the TextBlock shows 'User' and 'System' in the ListBox, so it seems to be getting the data.
How can I change this trigger to function?
A TypeEnum instance has no Type property, hence the Binding must not specify a property path:
<DataTrigger Binding="{Binding}" Value="{x:Static local:TypeEnum.User}">
Or with built-in type conversion from string to enum:
<DataTrigger Binding="{Binding}" Value="User">
In short, the question title says it all. For those that want more detail, here is the crux of my problem: I need to apply a custom ControlTemplate to the DataGridColumnHeader elements in my DataGrid control, but I also need to style them differently, depending on the cell data nearest the header. However, when I set both the ContentTemplateSelector and Template properties on a DataGridColumnHeader element, the DataTemplateSelector that is set as the value of the ContentTemplateSelector property is not called. Commenting out the Template property setting confirms this to be the case, as the DataTemplateSelector element will now be called.
Yes, I know that you guys love to see some code, but I have completely templated the whole DataGrid control to look like Excel, so as you can imagine, I have far too much code to display here. But just to please you code hungry devs, I've recreated my problem in a much simpler example... let's first see the XAML:
<Window x:Class="WpfApp1.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:WpfApp1"
xmlns:System="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<DataGrid>
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
<DataGrid.Items>
<System:String>One</System:String>
<System:String>Two</System:String>
<System:String>Three</System:String>
</DataGrid.Items>
<DataGrid.Resources>
<Local:StringDataTemplateSelector x:Key="StringDataTemplateSelector" />
<Style TargetType="{x:Type DataGridColumnHeader}" BasedOn="{StaticResource {x:Type DataGridColumnHeader}}">
<Setter Property="ContentTemplateSelector" Value="{StaticResource StringDataTemplateSelector}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
<Grid>
<Thumb x:Name="PART_LeftHeaderGripper" HorizontalAlignment="Left" />
<Thumb x:Name="PART_RightHeaderGripper" HorizontalAlignment="Right" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DataGrid.Resources>
</DataGrid>
</Grid>
</Window>
Now the most simple DataTemplateSelector class:
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
namespace WpfApp1
{
public class StringDataTemplateSelector : DataTemplateSelector
{
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
Debugger.Break();
return null;
}
}
}
In the XAML, we see a DataGrid, with just one DataGridTemplateColumn and three string values, one on each row, and some resources. There is a Style for the DataGridColumnHeader element in the Resource section, with the most simple ControlTemplate set up for it, that only includes the required named parts from the default ControlTemplate.
If you run the application as it is, then it will NOT currently break at the Debugger.Break() method in the StringDataTemplateSelector class. This is unexpected. If you now comment out the setting of the Template property in the Style and run the application again, then you will now see that program execution will now break at the Debugger.Break() method, as expected.
Further information:
In the Remarks section of the ContentControl.ContentTemplateSelector Property page of MSDN, it states that
If both the ContentTemplateSelector and the ContentTemplate properties are set, then this property is ignored.
However, it does not mention the Template property and there is also no mention of this on the Control.Template Property page on MSDN.
Furthermore, I tried this same setup using a simple Button control and can confirm that setting both the ContentTemplateSelector and the ContentTemplate properties on that does NOT stop the StringDataTemplateSelector class from being called:
<ItemsControl>
<ItemsControl.Resources>
<Local:StringDataTemplateSelector x:Key="StringDataTemplateSelector" />
<Style TargetType="{x:Type Button}">
<Setter Property="ContentTemplateSelector" Value="{StaticResource StringDataTemplateSelector}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Ellipse Stroke="Red" StrokeThickness="1" Width="{TemplateBinding ActualWidth}" Height="{TemplateBinding Height}" />
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ItemsControl.Resources>
<Button Content="One" />
<Button Content="Two" />
<Button Content="Three" />
</ItemsControl>
So, what I'm after is a way to apply a custom ControlTemplate element to the DataGridColumnHeader objects, yet still be able to have the DataTemplateSelector class called during the rendering process.
add a content presenter in your controltemplate?
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
<Grid>
<Thumb x:Name="PART_LeftHeaderGripper" HorizontalAlignment="Left" />
<Thumb x:Name="PART_RightHeaderGripper" HorizontalAlignment="Right" />
<ContentPresenter></ContentPresenter>
</Grid>
</ControlTemplate>
I have the following XAML:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WpfApplication4" Height="300" Width="300">
<Window.Resources>
<ControlTemplate x:Key="simpleErrorTemplate">
<TextBox Margin="10,10,10,5" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" Text="T1" />
</ControlTemplate>
<ControlTemplate x:Key="detailedErrorTemplate">
<StackPanel>
<TextBox Margin="10,10,10,5" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" Text="T2" />
<TextBox Margin="10,10,10,5" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" Text="T3" />
<TextBox Margin="10,10,10,5" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" Text="T4" />
</StackPanel>
</ControlTemplate>
</Window.Resources>
<Grid>
<ContentControl>
<ContentControl.Style>
<Style TargetType="ContentControl">
<Setter Property="Template"
Value="{StaticResource simpleErrorTemplate}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=Button,Path=IsPressed}" Value="True">
<Setter Property="Template" Value="{StaticResource detailedErrorTemplate}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
<Button x:Name="Button" Content="Button" Height="40" Width="129" Margin="88,5,76,5" Grid.Row="1" Click="Button_Click1"/>
</Grid>
</Window>
I had like to change the GUI style the moment I click the button just like it happends when DataTrigger is set for the Checkbox.
The code Behind looks as follows however the moment I click the button the window closes and no result.
import wpf
from System.Windows import Application, Window
class MyWindow(Window):
def __init__(self):
self.ui = wpf.LoadComponent(self, 'WpfApplication4.xaml')
def Button_Click1(self, sender, e):
self.ContentTemplate = Window.Resources.FindName(self,'detailedErrorTemplate')
if __name__ == '__main__':
Application().Run(MyWindow())
Why the template wont change?
Thank you.
I am unfamiliar with ironpython, but in your click handler it looks like you're setting the ContentTemplate of your window, which seems incorrect. I assume your detailedErrorTemplate is supposed to apply to your ContentControl. In this case you need to add x:Name to your ContentControl (i.e.: x:Name="TheContentControl") in order to reference the ContentControl in your code behind and set (in c#)
TheContentControl.Template = this.Resources["detailedErrorTemplate"] as ControlTemplate;
You have key's for your resources, not Names, so you need to index the resource dictionary by the key.
Edit details based on comments.
In your xaml, change your line
<ContentControl>
to
<ContentControl x:Name="TheContentControl">
Since we now have a name for the ContentControl, you can properly change the ControlTemplate of the ContentControl (NOT the window. I understand that your ContentControl effectively encompasses the Window, but you can't just assign that ControlTemplate meant for the ContentControl to the Window like that). Change your line of code from:
self.ContentTemplate = Window.Resources.FindName(self,'detailedErrorTemplate')
to (I hope I'm doing the syntax correctly).
self.TheContentControl.Template = self.Resources['detailedErrorTemplate']
Inside my window xaml:
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.Style>
<Style TargetType="{x:Type Grid}">
<Setter Property="Background">
<Setter.Value>
<VisualBrush>
<VisualBrush.Visual>
<Image Source="{Binding Path=ImageSource,Converter={StaticResource imgconverter}}">
<Image.BitmapEffect>
<BlurBitmapEffect KernelType="Box" />
</Image.BitmapEffect>
</Image>
</VisualBrush.Visual>
</VisualBrush>
</Setter.Value>
</Setter>
</Style>
</Grid.Style>
</Grid>
(I added to window resources this converter)
I would like to add background image with blur effect to this grid (with MVVM pattern) but my property never called in my viewmodel. If i use just converter with "Path=." the converter going to work but I have to use static ImageSource in conveter because if i add any object type for ImageSource (to path) (BitmapImage,ImageSource,..,etc), the converter will not call. (I tried to use UpdateSourceTrigger with PropertyChanged value but this solution didn't help to me.) The converter just an unwanted solution because this is the only one way to set my background correctly because my ImageSouce property has wanted value but its not works without converter and unfortunately the converter will not work too if i add any path to binding.
Here is my property inside the ViewModel:
private ImageSource _imageSource;
public ImageSource ImageSource
{
get
{
return _imageSource;
}
set
{
_imageSource = value;
OnPropertyChanged();
}
}
Any idea to set my background image with Blur effect correctly with MVVM pattern and without use uri path? (i dont want to save the image to physical storage)
A VisualBrush is not part of the element tree so it doesn't inherit the DataContext of the Grid.
But you could define the Image as a resource and bind its Source property to a property of the parent window using an {x:Reference}. This should work:
<Window x:Class="WpfApplication1.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:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="300" Width="300" x:Name="win">
<Window.Resources>
<local:imgconverter x:Key="imgconverter" />
</Window.Resources>
<Grid>
<Grid.Resources>
<Image x:Key="img" Source="{Binding Path=DataContext.ImageSource,Converter={StaticResource imgconverter}, Source={x:Reference win}}">
<Image.BitmapEffect>
<BlurBitmapEffect KernelType="Box" />
</Image.BitmapEffect>
</Image>
</Grid.Resources>
<Grid.Style>
<Style TargetType="{x:Type Grid}">
<Setter Property="Background">
<Setter.Value>
<VisualBrush Visual="{StaticResource img}" />
</Setter.Value>
</Setter>
</Style>
</Grid.Style>
<TextBlock Text="..." />
</Grid>
</Window>
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"));
}
}
}
Add an additional Setter with the default value Hidden to the Style itself, not the triggers.
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.
UPDATE
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}".