WPF Binding children property of a custom control to parent - wpf

I'm new to WPF. I'm trying to create a custom control with a HorizontalContentAlignment property that will change according to the setting of the container.
<Style x:Key="SimpleRadioButton" TargetType="{x:Type RadioButton}">
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Margin" Value="20 10 20 0"/>
<Setter Property="Height" Value="24"/>
<Setter Property="Padding" Value="6"/>
<Setter Property="HorizontalContentAlignment" Value="{Binding RelativeSource={RelativeSource TemplatedParent}}"/>
</Style>
And then set them in the parent container.
<ctrl:ToggleExpander
Header="Worklist"
IsChecked="{Binding IsVisible, Mode=TwoWay}"
HorizontalContentAlignment="Right"
IsToggleEnabled="True">
<StackPanel>
<ctrl:SideBarPanel
HorizontalContentAlignment="Right"
Header="map provider">
<RadioButton
Content="Finished"
IsChecked="True"
Style="{DynamicResource SimpleRadioButton}"/>
</StackPanel>
</ctrl:ToggleExpander>
But it doesn't seem to work. Is there any way to go about it? Thanks! And sorry for my English.

you could use the following, and your radiobutton will take the value of the first parent framework element (for example in this case your ctrl:SideBarPanel)
<Setter Property="HorizontalContentAlignment" Value="{Binding RelativeSource={RelativeSource AncestorLevel=1, AncestorType=FrameworkElement}, Path=HorizontalContentAlignment}"/>

you could use this symply way in xaml:
<Setter Property="HorizontalAlignment">
<Setter.Value>
<Binding Path="HorizontalAlignment" RelativeSource="{RelativeSource AncestorLevel=1,AncestorType=FrameworkElement}" />
</Setter.Value>
</Setter>
I hope help you

Related

Creating a style based on another which is using a data template

I have a style for a ListBox using TextBoxes as defined below:
<Style x:Key="MyListBoxStyle" TargetType="ListBox">
<Setter Property="Background" Value="LightGray"/>
<Setter Property="BorderThickness" Value="2"/>
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<TextBox Text="{Binding Mode=OneWay}" Background="LightGray"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
I use this style for a number of ListBox display readonly data.
What I also have is a group of ListBoxes in which I would like to be able to click on one of the TextBoxes in them and then perform some action. So what I want to do is attach a Click event on the TextBox. Ideally I'd like to leverage the above style without having to retype it all and just add a new style which added the event binding. How would yo go about this?
Style.BaseOn
<Style x:Key="MyListBoxStyle" TargetType="ListBox">
<Setter Property="Background" Value="LightGray"/>
<Setter Property="BorderThickness" Value="2"/>
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<TextBox Text="{Binding Mode=OneWay}" Background="LightGray"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="MyListBoxStyle2" BasedOn="{StaticResource MyListBoxStyle}" TargetType="ListBox">
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<TextBox Text="{Binding Mode=OneWay}" Background="LightGray" GotFocus="TextBox_GotFocus"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>

In WPF style how to correct bind parent checkbox property to a child?

I'm new to WPF styling and I cannot make next thing to work:
I've got a custom checkbox style with another checkbox in it. I need parent "IsChecked" value to change as "contolCheckBox" child in ControlTemplate changes.
Tryed different triggers but can't get to parent property.
For now I've got next xaml code:
<Style x:Key="CustomCheckBox" TargetType="{x:Type CheckBox}">
<Setter Property="Height" Value="27" />
<Setter Property="Foreground" Value="#FFBABAC7" />
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<Grid>
<CheckBox x:Name="contolCheckBox" HorizontalAlignment="Right" VerticalAlignment="Center"/>
<ContentPresenter HorizontalAlignment="Left" VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="IsChecked" Value="{Binding IsChecked, ElementName=contolCheckBox}"/>
<!---->
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Foreground" Value="#FF29E200"/>
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter Property="Foreground" Value="Firebrick"/>
</Trigger>
</Style.Triggers>
</Style>
"IsChecked" value of control doesn`t changes.
What am I doing wrong?
Binding ElementName=contolCheckBox, Path=IsChecked
not working too.
I don't think controlCheckBox is within the name scope since it's declared within the ControlTemplate. So your binding isn't working. Instead, invert your binding and bind from the bottom up. What you're looking for in a sitation like this is template binding. Try this in yourControlTemplate ..
<CheckBox x:Name="contolCheckBox" HorizontalAlignment="Right" VerticalAlignment="Center"
IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsChecked, Mode=TwoWay}" />
Note the RelativeSoucebinding. This indicates that I want to bind to the parent of the template. This is the common way to bind underlying ControlTemplate controls to parent properties.

Wpf Tooltip and Binding to Label Content

I have a lot of labels on my wpf App like this.
<Label Style="{StaticResource styleLabelTitle}">
<TextBlock TextTrimming="CharacterEllipsis" Text="{localization:Translate geolocation_controls}">
</TextBlock>
</Label>
I want to add a tooltip to show complete name when ellipsis is working. So i add the tooltip in the label style.
<Style x:Key="styleLabelTitle" TargetType="Label" x:Shared="False">
<Setter Property="Foreground" Value="{StaticResource brushTextsForeground}"></Setter>
<Setter Property="FontWeight" Value="Bold"></Setter>
<Setter Property="FontFamily" Value="Consolas"></Setter>
<Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=Content}" />
</Style>
The problem is that I think when tooltip is appearing is changing the textblock parent. So the text is only appearing in the Tooltip and is removed from the original label.
Any ideas?
Thanks in advance.
I finally came to a solution by doing a new style.
<Style x:Key="styleLabelText" TargetType="{x:Type Label}"
x:Shared="False">
<Setter Property="Foreground" Value="{StaticResource brushTextsForeground}"></Setter>
<Setter Property="FontWeight" Value="Normal"></Setter>
<Setter Property="FontFamily" Value="Consolas"></Setter>
<Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=Content}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Label}">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" TextTrimming="CharacterEllipsis"
Text="{TemplateBinding Content}" />
</ControlTemplate>
</Setter.Value>
</Setter> </Style>
You only have an instance of the textblock, then when you assign it to the tooltip the content is lost as you said.
You should set the value of the tooltip with the translated text out of the style:
<Label Style="{StaticResource styleLabelTitle}" ToolTip="{localization:Translate geolocation_controls}">
<TextBlock ...>
</Label>

WPF Style Binding to Base Style

i have a base style and a style in wpf.
the base style is:
<Style x:Key="BaseTextBox" TargetType="{x:Type TextBox}">
<Setter Property="Background" Value="#DDFFDD" />
<Setter Property="MinWidth" Value="75" />
<Setter Property="behaviors:OCCInteraction.Triggers" Value="{StaticResource ResourceKey=validationTrigger}" />
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="Background" Value="#FFDDDD"/>
<Setter Property="ToolTip" Value="{Binding Path=(Validation.Errors)[0].ErrorContent, RelativeSource={x:Static RelativeSource.Self}}" />
</Trigger>
</Style.Triggers>
</Style>
And the the specific style is:
<Style x:Key="EditableTextBox" TargetType="{x:Type TextBox}" BasedOn="{StaticResource ResourceKey=BaseTextBox}">
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<StackPanel Orientation="Horizontal">
<Border BorderBrush="Red" BorderThickness="1" Padding="0" Margin="0">
<AdornedElementPlaceholder Margin="0"/>
</Border>
<TextBlock Text="test" />
<Image Style="{StaticResource ResourceKey=WarningImage}"/>
<TextBlock Text="{Binding Path=(Validation.Errors)[0].ErrorContent, RelativeSource={RelativeSource Mode=Self,AncestorLevel=2}}" />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Now i want to add the Validation Error Text to a textblock next to the image. But the Same Binding Path doesn't work. I've tried diferent bindings, but I can't figure out how to access the same binding like on the base style.
Thanks for help :)
Have you tried it without the AncestorLevel? You should be the same object.
You cannot use Mode=Self and AncestorLevel properties. Just use Mode=Self.
Ancestor level is used when you try to reach parent of that control in visual tree.

Databinding in style to property on parent window

Is it possible to declare a style that sets the fontsize of tooltips to the same size as the parent form? I have tried this...
<Style TargetType="{x:Type ToolTip}">
<Setter Property="FontSize" Value="{Binding ElementName=MainWindow, Path=FontSize}"/>
</Style>
...but that doesnt work. Any suggestions?
I found a solution to my problem.
<Style TargetType="{x:Type ToolTip}">
<Setter Property="FontSize" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=FontSize}"/>
</Style>

Resources