I have 2 sets of textblocks some of them are in an itemcontrol and some of them are not,
I want to make an style (just based on type) which sets the background of the textblock if its ancestor is an ItemControl.
I can do it by the following code but the problem is that on the log (and output window) a data biding error message will be displayed because of the textblocks which do not have Itemcontrol as ancestore. Is there any better way to do this task and avoid this error message?
<Grid>
<Grid.Resources>
<local:HasAncestorConverter x:Key="HasAncestorConverter" />
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}, Converter={StaticResource HasAncestorConverter}}" Value="True">
<Setter Property="Background"
Value="{Binding Tag,
RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Resources>
<StackPanel>
<TextBlock Text="Out of ItemControl" />
<ItemsControl Tag="Blue" >
<TextBlock Text="Inside of ItemControl" />
</ItemsControl>
</StackPanel>
</Grid>
Convertor:
class HasAncestorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value != null;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Error message:
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ItemsControl', AncestorLevel='1''. BindingExpression:Path=; DataItem=null; target element is 'TextBlock' (Name=''); target property is 'NoTarget' (type 'Object')
According to @makc's response I solved the problem this way:
Converter:
Helper class for finding the parent of specific type:
Note: This helper find any kind of parent in logical or visual tree. for example in my case ItemsControl is a parent in the logical tree, and it can be a grandparent.
You can work with FallbackValue or TargetNullValue
Check this link out:
http://dontcodetired.com/blog/post/FallbackValue-TargetNullValue-StringFormat-in-Silverlight-4.aspx
Use
DataTemplate
for the items inItemsControl
.Keep the style that you have if you need it for other setters, just remove the trigger.
I think @Xameli solution is what you are actually looking for...
but if you simply must do it in a style then you can achieve it using
VisualTreeHelper
like that:the converter: