Reputation: 5855
On my Window there are several GroupBox Controls, each containing a Grid Control. To those Grids I want to asign a Style. But only to those Grids that are directly in a GroupBox, all other Grids should not be affected.
I have tried the following, which does not work as GetType() is no property.
<Style TargetType="Grid">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Parent.GetType()}" Value="{x:Type GroupBox}">
<!-- <Setter Property="..." Value="..."/> -->
</DataTrigger>
</Style.Triggers>
</Style>
I have found a workaround, but it's not really a beautiful solution, as I have to modify the GroupBoxes:
<Style TargetType="GroupBox">
<Setter Property="Tag" Value="blub"/>
</Style>
<Style TargetType="Grid">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Parent.Tag, RelativeSource={RelativeSource Mode=Self}}" Value="blub">
<!-- <Setter Property="..." Value="..."/> -->
</DataTrigger>
</Style.Triggers>
</Style>
Obviously I could set the style for each Grid manually, but I'm trying to avoid that, as there are quite a lot of them. I hope you can find a way to make the first example work.
Upvotes: 9
Views: 11034
Reputation: 119
This worked for me:
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type StatusBar}}, Path=DependencyObjectType.Name}" Value="StatusBar">
<Setter Property="Margin" Value="0"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="Background" Value="Chartreuse"/>
</DataTrigger>
</Style.Triggers>
It allows you to set style based on parent type without having to resort to Tag which should really be used by code rather than by markup.
Upvotes: 5
Reputation: 2062
Use following Code :
using DevExpress.Xpf.Core.Native;
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
namespace BindingErrorHelper
{
public class IsTypeFoundConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
FrameworkElement element = value as FrameworkElement;
Type type = parameter as Type;
if (element != null && type != null)
{
element = LayoutHelper.FindElement(element,type);
if (element != null)
return true;
}
return false;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return value;
}
}
public class LayoutHelper
{
public static FrameworkElement FindElement(FrameworkElement treeRoot, Type type)
{
FrameworkElement parentElement = VisualTreeHelper.GetParent(treeRoot) as FrameworkElement;
while (parentElement != null)
{
if (parentElement.GetType() == type)
return parentElement;
else
parentElement = VisualTreeHelper.GetParent(parentElement) as FrameworkElement;
}
return null;
}
}
}
Write the XAML Code as :
<tt:IsTypeFoundConverter x:Key="isTypeFoundConverter"/>
<Style TargetType="Grid">
<Style.Triggers>
<DataTrigger Binding={Binding RelativeSource={RelativeSource Self}, Converter={StaticResource isTypeFoundConverter}, ConverterParameter={x:Type GroupBox}}" Value="true">
<!-- <Setter Property="..." Value="..."/> -->
</DataTrigger>
</Style.Triggers>
</Style>
Upvotes: 1
Reputation: 361252
<DataTrigger Binding="{Binding Path=Parent.Tag, RelativeSource={RelativeSource Mode=Self}}" Value="blub">
This code would not work, because type of Mode is actually BindingMode which is an Enumeration, and none of it's member is Self. So this assignment Mode=Self is wrong in your code. To know the possible values of Mode, click this.
The correct way to write this is,
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type GroupBox}}, Path=Tag}" Value="blub">
And of course, for this to work, you've to keep that Style for GroupBox which you've already written.
Upvotes: 9