Is there any way in XAML to bind the opacity of a GroupBox depending on if a checkbox is ticked or not?
For example, I want a GroupBox to be 100% opacity if the checkbox is ticked, otherwise it will be 60% opacity if the checkbox is un-ticked.
Can I use element binding to achieve this?
Thanks all.
You could use a Style with a DataTrigger that binds to the IsChecked property of the CheckBox:
<CheckBox x:Name="chk" />
<GroupBox>
<GroupBox.Style>
<Style TargetType="GroupBox">
<Setter Property="Opacity" Value="0.6" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsChecked, ElementName=chk}" Value="True">
<Setter Property="Opacity" Value="1" />
</DataTrigger>
</Style.Triggers>
</Style>
</GroupBox.Style>
</GroupBox>
Related
I have a treeview and a listbox.
I want to specify on the style trigger-setter option that, when the listbox visibility is Hidden the focus have to return on the treeview.
Is it possibile to condition an user control focus on the state of another user control?
something like
<Style TargetType="{x:Type TreeView}">
<Style.Triggers>
<Trigger Property="Visibility" Value="Hidden">
<Setter Property="IsFocus" Value="True" />
</Trigger>
</Style.Triggers>
</Style>
Yes it is, see the example here
FOR CHILDREN IN CONTAINERS
<StackPanel FocusManager.FocusedElement="{Binding ElementName=lol}">
<TextBox x:Name="lol"/>
<TextBox x:Name="lul"/>
</StackPanel>
FOR SELF
<TextBox FocusManager.FocusedElement="{Binding RelativeSource={RelativeSource Self}}"/>
XAML
<utility:InvalidNotification x:Name="InvalidNotificationControl"/>
<Button Content="Clean AppV Cache" Click="Button_Click">
<Button.Style>
<Style TargetType="Button">
<Setter Property="IsEnabled" Value="True"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=InvalidNotificationControl, Path=Visibility}" Value="Visible">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
NOTE
InvalidNotification is a custom UserControl
Now, the DataTrigger works fine initially and disable the button since the Usercontrol is visible.
The problem is when I collapse the Usercontrol based on another condition the button stays disable. I found this related answer which states that The properties changed by triggers are automatically reset to their previous value when the triggered condition is no longer satisfied. which is not my case. Why is that ?
EDIT
Thanks to #mm8 which led me to the solution. So if ever you're trying to bind a control on a UserControl's content (inner TextBlock in my case), just add a second trigger at the bottom of your Usercontrol like so,
<UserControl.Style>
<Style TargetType="UserControl">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=Notification, Path=Visibility}" Value="Visible">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</UserControl.Style>
where notification would be the name of my TextBlock
Your example works provided that you toggle/set the Visibility property of the InvalidNotification control itself, since it is this property that you bind to.
If you set the Visibility property of some element within the InvalidNotification control, you need to bind to this specific element.
You can't do this using an ElementName binding though because the Button and any element defined in the InvalidNotification control don't belong to the same namescope.
Style defined in Resource
<Setter Property="Background" Value="Red"/>
</Style>enter code here
</Window.Resources>
In window i am adding a groupbox with child label .
<Grid>
<GroupBox Header="Header">
<GroupBox.Resources>
<Style TargetType="{x:Type GroupBox}">
<Setter Property="Background" Value="white"/>
</Style>
</GroupBox.Resources>
<Label Content="dsfdsfdsf" Foreground="Black" />
</GroupBox>
</Grid>
My Expected Result was Label taking background of white . But actually it is taking Red Background (that is defined in style of Resource )
If i set the style of the Label to explicitly null it works fine
Label Content="dsfdsfdsf" Foreground="Black" Style={x:Null}
But Controls to GroupBox are dynamically added so i want to set
Style={x:Null} to all childrens that are being added to Group box
if i set OverrideDefalutStyle to True in Label the content of label is not comming ......................
Label Content="dsfdsfdsf" Foreground="Black" OverridesDefaultStyle="True"
That style in GroupBox.Resources has no effect on the GroupBox itself. The implicit GroupBox's style is the one of its closest ancestor on VisualTree. You put that style in the wrong place.
Or use Style property instead
<Grid>
<GroupBox Header="Header">
<GroupBox.Style>
<Style TargetType="{x:Type GroupBox}">
<Setter Property="Background" Value="white"/>
</Style>
</GroupBox.Style>
<Label Content="dsfdsfdsf" Foreground="Black" />
</GroupBox>
</Grid>
By setting
<Style TargetType="{x:Type GroupBox}">
<Setter Property="Background" Value="White"/>
</Style>
you will set the background of all GroupBox controls within your GroupBox and the GroupBox itself to white.
So if you want to set/override the Background of all Labels within your GroupBox just add an additional Style to your GroupBox targeting Label
<Style TargetType="{x:Type Label}">
<Setter Property="Background" Value="White"/>
</Style>
If you want to reset the style property of your Label just add an empty style definition to your GroupBox
<Style TargetType="{x:Type Label}"/>
The next approach is used on your on risk :)
If you only want to reset the background color, you can do this trick/hack to reset:
<Style TargetType="{x:Type Label}">
<Setter Property="Background" Value="{Binding Background.DefaultValue, RelativeSource={RelativeSource Self}}" />
<Setter Property="Foreground" Value="Black" />
</Style>
Hint: Instead of Background.DefaultValue you can also write Background.ABC the main thing here is that the binding goes wrong.
I prepared my own DataTemplate to display my own Item class objets. To set the width I use binding to ViewportWidth of ScrollViewer. This is how:
<DataTemplate x:Key="MyItemTemplate">
<Grid Margin="5" HorizontalAlignment="Stretch"
Width="{Binding ViewportWidth, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ScrollViewer}}}">
...
</Grid>
</DataTemplate>
How I display data:
<TabItem Header="Shop">
<!--<ScrollViewer>-->
<ListView Name="ShopListView" ItemsSource="{Binding itemList}"
ItemTemplate="{StaticResource MyItemTemplate}"
ItemContainerStyle="{StaticResource alternatingListViewItemStyle}"
AlternationCount="2"
ScrollViewer.CanContentScroll="True"
/>
<!--</ScrollViewer>-->
</TabItem>
The issue is the grid that makes my DataTemplate is sliglty broader - it overlaps the right border of the View Window.
EDIT
Buttons on their right edges are cut.
<Style x:Key="alternatingListViewItemStyle" TargetType="{x:Type ListViewItem}">
<Style.Triggers>
<!-- setting up triggers for alternate background colors -->
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="#FF4C85FF"></Setter>
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="2">
<Setter Property="Background" Value="#FFFF8C7C"></Setter>
</Trigger>
</Style.Triggers>
</Style>
The default style of the item container element generated by the ListView for each item incorporates some padding. That means, rendered items normally have a width which is slightly smaller than the view port width.
To not let your items cross the right border of the viewport, you could set the padding of the item container to zero. This can easily be done with a simple style for the item container. Since you already provide an item container style, you could just let it set the padding property.
However, this might not be necessary. To stretch the item content across the width of the view port, you don't need to bind the Grid.Width property in your item template to ListView.ViewPortWidth. It can be done simpler: The item container can be instructed to horizontally stretch the item content by setting its HorizontalContentAlignment accordingly. This of course can also be done with the item container style.
The below example style (based on the style given in your question) demonstrates both setting the HorizontalContentAlignment and Padding property. If you want to keep the default padding between the items and the border of the ListView, simply omit the Padding setter from my example:
<Style x:Key="alternatingListViewItemStyle" TargetType="{x:Type ListViewItem}">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="Padding" Value="0" />
<Style.Triggers>
<!-- setting up triggers for alternate background colors -->
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="#FF4C85FF"></Setter>
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="2">
<Setter Property="Background" Value="#FFFF8C7C"></Setter>
</Trigger>
</Style.Triggers>
</Style>
I have a TabControl which has its SelectedIndex property bound to a boolean value like this:
<TabControl>
<TabControl.Style>
<Style TargetType="TabControl">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsRunning, UpdateSourceTrigger=PropertyChanged}" Value="True">
<Setter Property="SelectedIndex" Value="1" />
</DataTrigger>
</Style.Triggers>
</Style>
</TabControl.Style>
<TabItem Header="Foo" />
<TabItem Header="Bar" />
</TabControl>
The TabControl should only switch to the second tab, if the IsRunningproperty changes to True, but the problem now is, that as soon as the IsRunning property changes, the TabControl does not update itself to display the second TabItem.
Is there a way to do this through XAML, or do I have to implement a SelectedIndex property in my viewmodel, that binds directly to the SelectedIndexof the TabControl?
This works for me just as expected, if the property changes to true the tab switches. Maybe there's a problem with the binding? (Or did i misuderstand the question?)
This is an old thread but who knows someone else may stuble upon this just like me looking for an answer.
Solution: Just add a setter in TabControl style to set SelectedIndex to initial value. e.g. Setter Property="SelectedIndex" Value="0"
<TabControl>
<TabControl.Style>
<Style TargetType="TabControl">
<Setter Property="SelectedIndex" Value="0" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsRunning, UpdateSourceTrigger=PropertyChanged}" Value="True">
<Setter Property="SelectedIndex" Value="1" />
</DataTrigger>
</Style.Triggers>
</Style>
</TabControl.Style>
<TabItem Header="Foo" />
<TabItem Header="Bar" />
</TabControl>