Set property of ViewModel using setter within some Trigger - wpf

I tried to google but all problems had related heading but problem context different. My problem is that I have a DataTrigger which gets triggered when certain property has a certain value i-e IsDockPanelVisible has true/false (different triggers for each value) in my case. Now when it gets triggered, it should set the value of Width - a property defined in ViewModel. Here is my specific code:
<Style.Triggers>
<DataTrigger Binding="{Binding IsDockPanelVisible}" Value="False">
<Setter Property="mainWindowViewModel.Width" Value="Auto">
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding IsDockPanelVisible}" Value="True">
<Setter Property="mainWindowViewModel.Width" Value="7*"></Setter>
<Setter Property="MinWidth">
<Setter.Value>
<MultiBinding Converter="{StaticResource StringSumtoIntConvert}">
<Binding ElementName="cdLblNotificationsHeader" Path="MinWidth"/>
<Binding ElementName="cdBtnNotificationsClose" Path="ActualWidth"/>
</MultiBinding>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
Here is complete code:
<Window x:Class="EmbroidaryManagementSystem_V2._0.View.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:EmbroidaryManagementSystem_V2._0.View"
xmlns:adf="clr-namespace:EmbroidaryManagementSystem_V2"
xmlns:collectionVM="clr-namespace:EmbroidaryManagementSystem_V2._0.ViewModel.CollectionsViewModel"
xmlns:helperClasses="clr-namespace:EmbroidaryManagementSystem_V2._0.HelperClasses"
xmlns:mainWindowVM="clr-namespace:EmbroidaryManagementSystem_V2._0.ViewModel.UIViewModel"
mc:Ignorable="d"
Title="Khalil Embroidery Management System" Height="655.512" Width="1135.159" FontSize="24"
WindowStartupLocation="CenterScreen" MinWidth="200" MinHeight="300"
Icon="/EmbroidaryManagementSystem V2.0;component/Images/KhalilEmbroideryLogonobackgrnd2.png"
>
<Window.DataContext>
<!--<collectionVM:ClientCollectionVM/>-->
<mainWindowVM:MainWindowViewModel/>
</Window.DataContext>
<Window.Resources>
<helperClasses:StringSumtoIntConverter x:Key="StringSumtoIntConvert"/>
<ControlTemplate x:Key="DockedPanelButtonTemplate" TargetType="{x:Type Button}">
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Black"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<Style x:Key="DockedPanelButton" TargetType="Button">
<Setter Property="LayoutTransform">
<Setter.Value>
<RotateTransform Angle="90"/>
</Setter.Value>
</Setter>
<!--<Setter Property="Template" Value="{StaticResource DockedPanelButtonTemplate}"/>-->
<Setter x:Name="border" Property="BorderBrush" Value="DodgerBlue"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="Aquamarine"/>
<Setter Property="Background" Value="Yellow"/>
</Trigger>
</Style.Triggers>
</Style>
<!--<mainWindowVM:MainWindowViewModel x:Key="WindowViewModel"/>-->
<Style x:Key="OnIsDockPanelVisibleChangedGridBehaviour" TargetType="Grid">
<Style.Triggers>
<DataTrigger Binding="{Binding IsDockPanelVisible}" Value="False">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
<DataTrigger Binding="{Binding IsDockPanelVisible}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
<Style x:Key="OnIsDockPanelVisibleChangedPanelColumnBehaviour" TargetType="ColumnDefinition">
<Style.Triggers>
<DataTrigger Binding="{Binding IsDockPanelVisible}" Value="False">
<Setter Property="mainWindowViewModel.Width" Value="Auto">
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding IsDockPanelVisible}" Value="True">
<Setter Property="mainWindowViewModel.Width" Value="7*"></Setter>
<Setter Property="MinWidth">
<Setter.Value>
<MultiBinding Converter="{StaticResource StringSumtoIntConvert}">
<Binding ElementName="cdLblNotificationsHeader" Path="MinWidth"/>
<Binding ElementName="cdBtnNotificationsClose" Path="ActualWidth"/>
</MultiBinding>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
<Style x:Key="OnIsDockPanelVisibleChangedButtonBehaviour" TargetType="Button"
BasedOn="{StaticResource DockedPanelButton}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsDockPanelVisible}" Value="True">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
<DataTrigger Binding="{Binding IsDockPanelVisible}" Value="False">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
<Style x:Key="OnIsDockPanelVisibleChangedGridSplitterBehaviour" TargetType="GridSplitter">
<Style.Triggers>
<DataTrigger Binding="{Binding IsDockPanelVisible}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
<DataTrigger Binding="{Binding IsDockPanelVisible}" Value="False">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
<SolidColorBrush x:Key="TransparentBackground">
Transparent
</SolidColorBrush>
<Style x:Key="LeftDockedPanelButton" TargetType="Button" BasedOn="{StaticResource OnIsDockPanelVisibleChangedButtonBehaviour}">
<Setter Property="BorderThickness" Value="0,0,0,15"/>
</Style>
<Style x:Key="RightDockedPanelButton" TargetType="Button" BasedOn="{StaticResource OnIsDockPanelVisibleChangedButtonBehaviour}">
<Setter Property="BorderThickness" Value="0,8,0,0"/>
</Style>
<BitmapImage x:Key="LogoImage" UriSource="/Images/KhalilEmbroideryLogonobackgrnd2.png"/>
</Window.Resources>
<!--<ScrollViewer HorizontalScrollBarVisibility="Auto">-->
<Grid x:Name="mainGrid" Background="#FFD6DBE9">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition MinHeight="103"/>
</Grid.RowDefinitions>
<Menu Height="18" VerticalAlignment="Top" Grid.Row="0" Margin="0,0,0,0">
<MenuItem Header="_Exit">
<MenuItem Header="Exit"/>
</MenuItem>
<MenuItem Header="_View">
<MenuItem Header="Notifications" Command="{Binding ShowDockPanelCommand}"/>
</MenuItem>
<MenuItem Header="Add _New">
<MenuItem Header="Employee"/>
<MenuItem Header="Employee Salary"/>
</MenuItem>
<MenuItem Header="_About">
<MenuItem Header="About us"/>
</MenuItem>
</Menu>
<ScrollViewer HorizontalScrollBarVisibility="Auto" Grid.Row="1">
<Grid x:Name="innerContentGrid" MinHeight="500" MinWidth="600">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20*" MinWidth="{Binding MinWidth, ElementName=tabDataEntities}"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Style="{StaticResource OnIsDockPanelVisibleChangedPanelColumnBehaviour}" Width="{Binding }"/>
</Grid.ColumnDefinitions>
<GridSplitter x:Name="gridSplitter" Grid.Column="1" HorizontalAlignment="Center"
Width="3" Margin="0,10,0,0" Background="#FF657695"
Style="{StaticResource OnIsDockPanelVisibleChangedGridSplitterBehaviour}"/>
<Grid x:Name="gridNotificationsHeader" Grid.Column="2" Background="#FF657695" Margin="0,10,0,0"
Height="30" VerticalAlignment="Top" Style="{StaticResource OnIsDockPanelVisibleChangedGridBehaviour}">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="cdLblNotificationsHeader"
MinWidth="{Binding Width, ElementName=lblNotificationsHeader}"/>
<ColumnDefinition x:Name="cdBtnNotificationsClose" Width="Auto"/>
</Grid.ColumnDefinitions>
<Label x:Name="lblNotificationsHeader" Content="Notifications" VerticalAlignment="Top"
FontSize="14.667" Height="29" Foreground="#FFEBF0EE" HorizontalAlignment="Left" Width="92"/>
<Button x:Name="btnNotificationsClose" Content="X"
Margin="0,5,8,0" VerticalAlignment="Top" Width="20" FontFamily="Verdana" HorizontalAlignment="Right"
Background="Transparent" FontSize="13.333" Foreground="Black" Grid.Column="1"
Command="{Binding HideDockPanelCommand}"/>
</Grid>
<TabControl Grid.Column="0" x:Name="tabDataEntities" Margin="0,10,5,0" FontSize="12"
MinWidth="{Binding ElementName=TabItemOne, Path=ActualWidth}">
<TabItem x:Name="TabItemOne">
<TabItem.Header>Tab Item</TabItem.Header>
<Grid Background="#FFE5E5E5" Margin="0,0,0,0"/>
</TabItem>
<TabItem Header="TabItem">
<Grid Background="#FFE5E5E5"/>
</TabItem>
</TabControl>
<Button x:Name="btnShowNotificationsPanel" Content="Notifications" Grid.Column="2"
Margin="0,12,-0,0" VerticalAlignment="Top" Style="{StaticResource RightDockedPanelButton}" Background="Transparent"
FontSize="12" Height="Auto" HorizontalAlignment="Right" Width="Auto"
Command="{Binding ShowDockPanelCommand}"/>
</Grid>
</ScrollViewer>
</Grid>
Width is property in my ViewModel and not FrameworkElement.Width. However, it has the same double type. ViewModel class is MainWindowViewModel and its object in XAML is mainWindowVM.

You can not set view model properties with a setter of your view.
Have a look here: Setter.Property Property.
It states that you can only uses a DependencyProperty as the value for the setter (Besides, you cannot specify a binding expression there, just a string value).
<object Property="DependencyProperty" .../>
Suggestion:
If IsDockPanelVisible is a property inside your view model, you could react to change events there in your view model, either by subscribing to INotifyPropertyChanged of this property or by calling a method in the setter of IsDockPanelVisible.
You could then set another property in your view model which is bound to the view and then achieve your desired result.

Related

side bar with multiple collapsible sub menu in side bar wpf

I have two toggle buttons which I am used to making to the collapsable sidebar sub-menu option. I want to display both collapsed initially. when of them is pressed it shout expand and when the other submenu is clicked the first one should collapse and the other one should get open.
<ToggleButton Grid.Column="0" Height="50" Style="{StaticResource CategoryButton}" FontSize="14" FontWeight="Regular" Foreground="{StaticResource SupremeFontColor}" Margin="6,2,6,0"
FontFamily="{StaticResource FontFamily}" Content="Report Group" ToolTip="Report Group" x:Name="reportToggleButton" BorderBrush="Transparent" Click="reportToggleButton_Click">
</ToggleButton>
<Grid Height="60" Visibility="{Binding IsChecked, ElementName=reportToggleButton, Converter={StaticResource BoolToVisibilityConverter}}">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Text="Fail Reports." Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="0,0,0,0" Width="Auto" Height="30">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Background" Value="white" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource SupremeprimaryDarkBlue}" />
</Trigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
<TextBlock Text="Other Reports." Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="0,0,0,0" Width="Auto" Height="30">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Background" Value="white" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource SupremeprimaryDarkBlue}" />
</Trigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</Grid>
<!--Sales Report-->
<ToggleButton Grid.Column="0" Height="50" Style="{StaticResource CategoryButton}" FontSize="14" FontWeight="Regular" Foreground="{StaticResource SupremeFontColor}" Margin="6,2,6,0"
FontFamily="{StaticResource FontFamily}" Content="Sales Report" ToolTip="Sales Report" x:Name="salesToggleButton" BorderBrush="Transparent" Click="salesToggleButton_Click">
</ToggleButton>
<Grid Height="60" Visibility="{Binding IsChecked, ElementName=salesToggleButton, Converter={StaticResource BoolToVisibilityConverter}}">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Text="Daily Course Summary" Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Center" Width="Auto" Height="30">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Background" Value="white" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource SupremeprimaryDarkBlue}" />
</Trigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
<TextBlock Text="Finalize Event Payment Report" Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Center" Width="Auto" Height="30">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Background" Value="white" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource SupremeprimaryDarkBlue}" />
</Trigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</Grid>
I would first clean-up your mess at least a little:
<!--I used StackPanel, but it can be any container you have-->
<StackPanel>
<StackPanel.Resources>
<Style TargetType="TextBlock" x:Key="myTextbox">
<Setter Property="Background" Value="White" />
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="Width" Value="Auto"/>
<Setter Property="Height" Value="30"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="ToggleButton" x:Key="myToggleButton">
<Setter Property="Height" Value="50" />
<Setter Property="FontSize" Value="14"/>
<Setter Property="FontWeight" Value="Regular"/>
<Setter Property="Margin" Value="6,2,6,0"/>
<Setter Property="BorderBrush" Value="Transparent"/>
</Style>
</StackPanel.Resources>
<ToggleButton Content="Report Group" ToolTip="Report Group" x:Name="reportToggleButton" Click="reportToggleButton_Click" Style="{StaticResource myToggleButton}"/>
<StackPanel Orientation="Horizontal" Height="60" Visibility="{Binding IsChecked, ElementName=reportToggleButton, Converter={StaticResource boolToVisibilityConverter}}">
<TextBlock Text="Fail Reports." Style="{StaticResource myTextbox}"/>
<TextBlock Text="Other Reports." Style="{StaticResource myTextbox}"/>
</StackPanel>
<!--Sales Report-->
<ToggleButton Content="Sales Report" ToolTip="Sales Report" x:Name="salesToggleButton" Click="salesToggleButton_Click" Style="{StaticResource myToggleButton}"/>
<StackPanel Orientation="Horizontal" Height="60" Visibility="{Binding IsChecked, ElementName=salesToggleButton, Converter={StaticResource boolToVisibilityConverter}}">
<TextBlock Text="Daily Course Summary" Style="{StaticResource myTextbox}"/>
<TextBlock Text="Finalize Event Payment Report" Style="{StaticResource myTextbox}"/>
</StackPanel>
</StackPanel>
And after would add something like this in your event handlers:
private void reportToggleButton_Click(object sender, RoutedEventArgs e)
{
salesToggleButton.IsChecked = !(sender as ToggleButton).IsChecked;
}
private void salesToggleButton_Click(object sender, RoutedEventArgs e)
{
reportToggleButton.IsChecked = !(sender as ToggleButton).IsChecked;
}
However I would recommend you to learn how to use standard components (maybe MenuItem or TreeItem would work for you) before considering creating something like that.

Check my ListView progress-bar cell backgroung color based on property

So i have this cell Progress-Bar inside my ListView.Resources:
<DataTemplate x:Key="MyDataTemplate">
<Grid Margin="-6,0,0,0" Height="20.5" Width="80">
<ProgressBar Name="progressBarColumn"
Maximum="100"
Value="{Binding Progress, UpdateSourceTrigger=PropertyChanged}"
Width="{Binding Path=Width, ElementName=ProgressCell}"
Background="{Binding Path=IsCkecked}"
Margin="0,0,0,0"
Style="{StaticResource CustomProgressBar}" />
<TextBlock Text="{Binding Path=Value, ElementName=progressBarColumn, StringFormat={}{0:N1}%}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Foreground="{DynamicResource ProgressBarForegroundColor}"
FontFamily="{DynamicResource ProgressBarFontFamily}"
FontSize="{DynamicResource ProgressBarFontSize}"
Margin="{DynamicResource ProgressBarMargin}"/>
</Grid>
</DataTemplate>
And my style:
<Style x:Key="CustomProgressBar" TargetType="ProgressBar">
<Setter Property="Template" >
<Setter.Value>
<ControlTemplate TargetType="ProgressBar">
<Border BorderBrush="{DynamicResource ProgressBorderBrushColor}" BorderThickness="0" Background="{DynamicResource ProgressBackgroundColor}" CornerRadius="0" Padding="0">
<Grid x:Name="PART_Track">
<Rectangle x:Name="PART_Indicator" HorizontalAlignment="Left">
<Rectangle.Style>
<Style TargetType="Rectangle">
<Setter Property="Fill" Value="{DynamicResource ProgressBarFillColor}"/>
<Style.Triggers>
<DataTrigger Value="100" Binding="{Binding Path=Value, RelativeSource={RelativeSource AncestorType=ProgressBar}}">
<Setter Property="Fill" Value="{DynamicResource ProgressBarFillCompleteColor}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
</Rectangle>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Now inside my ListView each binding object has this bool property IsChecked which is another CheckBox cell and when this CheckBox is Unchecked my IsChecked property is false and in this case i wan to change my Progress-Bar Background color.
So this is what i have try and add into my Progress-Bar style (not effect at all on my Progress-Bar Background color...):
<DataTrigger Value="False" Binding="{Binding Path=IsChecked, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=CheckBox}}">
<Setter Property="Fill" Value="Red"/>
</DataTrigger>
EDIT:
My CheckBox is already bind into my property:
IsChecked="{Binding Path=IsChecked}"
...
<DataTrigger Value="True" Binding="{Binding Path=IsChecked}">
<Setter Property="Fill" Value="Red"/>
</DataTrigger>
<DataTrigger Value="False" Binding="{Binding Path=IsChecked}">
<Setter Property="Fill" Value="Yellow"/>
</DataTrigger>
public bool IsChecked
{
get { return _isChecked; }
set
{
_isChecked = value;
OnPropertyChanged();
}
}
after a little bit of work here is the solution:
<Style x:Key="CustomProgressBar" TargetType="ProgressBar">
<Style.Triggers>
<DataTrigger Value="True" Binding="{Binding Path=IsChecked}">
<Setter Property="Background" Value="Red"/>
</DataTrigger>
<DataTrigger Value="False" Binding="{Binding Path=IsChecked}">
<Setter Property="Background" Value="Yellow"/>
</DataTrigger>
</Style.Triggers>
<Setter Property="Template" >
<Setter.Value>
<ControlTemplate TargetType="ProgressBar">
<Border BorderBrush="{DynamicResource ProgressBorderBrushColor}" BorderThickness="0" Background="{DynamicResource ProgressBackgroundColor}" CornerRadius="0" Padding="0">
<Grid x:Name="PART_Track">
<Rectangle x:Name="PART_Indicator" HorizontalAlignment="Left">
<Rectangle.Style>
<Style TargetType="Rectangle">
<Setter Property="Fill" Value="{Binding}"/>
</Style>
</Rectangle.Style>
</Rectangle>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Fill button into a datagrid cell

I have a data grid and for the column HCode I have/need buttons, but the property Code can be null/empty in which case the Button will not be visible.
I'd like to know if there are options or defining a mouse-click handler for the cell is the way to go.
Below is the DataGridTemplate defining the column
<DataGridTemplateColumn Header="HCode" MinWidth="120">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Content="{Binding Code}"
Style="{StaticResource BStyle}"
Background="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=TextBlock}, Path=Background}"
Click="ButtonBase_OnClick"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Center"
/>
<!--Visibility="{qc:Binding '$P != null && $P.Length > 0 ? Visibility.Visible : Visibility.Collapsed', P={Binding Code}}"-->
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
Below is the style that is used
<Style x:Key="BStyle"
TargetType="{x:Type Button}">
<Setter Property="SnapsToDevicePixels"
Value="true" />
<Setter Property="BorderThickness"
Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30*"></RowDefinition>
</Grid.RowDefinitions>
<ContentPresenter Margin="0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
RecognizesAccessKey="True" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Foreground"
Value="Blue" />
<Style.Triggers>
<Trigger Property="IsMouseOver"
Value="true">
<Setter Property="Foreground"
Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
You could define two DataTriggers. Try this:
<Button Content="{Binding Code}"
Background="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=TextBlock}, Path=Background}"
Click="ButtonBase_OnClick"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Center">
<Button.Style>
<Style TargetType="Button" BasedOn="{StaticResource BStyle}">
<Style.Triggers>
<DataTrigger Binding="{Binding Code}" Value="{x:Null}">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
<DataTrigger Binding="{Binding Code.Length}" Value="0">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
Or:
<DataTrigger Binding="{Binding Code.Length, FallbackValue=0}" Value="0">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>

Can't figure out why some controls are being clipped

So I have buttons that extend beyond the grid they are in, but they only show up on mouse over. In some grids they render correctly and some they are rendered incorrectly. It seems to be consistent which ones are incorrect, but I cannot figure out why the issue occurs on those particular grids. I looked at the elements with snoop and can't see any issues with the properties as they are being rendered.
Correct rendering:
Incorrect rendering:
Here's the code
<ScrollViewer x:Name="GridItemScroller" Height="300">
<ItemsControl Margin="0,0" ItemsSource="{Binding Source={StaticResource rowItemsView}}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid VerticalAlignment="Top" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Margin" Value="{Binding RowIndex, Converter={StaticResource IndexToPositionConverter}, ConverterParameter=20}" />
<Setter Property="VerticalAlignment" Value="Top" />
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate >
<Grid x:Name="itemPanel" VerticalAlignment="Top" ClipToBounds="False">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Rectangle Grid.Column="0" Grid.ColumnSpan="2" Fill="Transparent" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<CheckBox IsChecked="{Binding Path=Filtered, Converter={StaticResource NotConverter}}" Content="{Binding RowName}" />
<Canvas x:Name="CheckBoxButtonPanel" Grid.Column="1" ClipToBounds="False" VerticalAlignment="Center" Width="25" Height="2">
<Canvas.Style>
<Style TargetType="Canvas">
<Setter Property="Visibility" Value="Collapsed" />
<Setter Property="Panel.ZIndex" Value="0" />
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=itemPanel, Path=IsMouseOver}" Value="True">
<Setter Property="Visibility" Value="Visible" />
<Setter Property="Panel.ZIndex" Value="10" />
</DataTrigger>
</Style.Triggers>
</Style>
</Canvas.Style>
<Button HorizontalAlignment="Right" Height="15" Width="25" Canvas.Top="-15" local:ToolIcon.IconName ="{Binding Source={StaticResource LanguageInfo}, XPath=//Strings/#Up}" local:ToolIcon.Image="pack://application:,,,/CalUI;component/images/Up.png"
Style="{DynamicResource ToolIcon}" Click="Move_Up"/>
<Button HorizontalAlignment="Right" Height="15" Width="25" Canvas.Top="2" local:ToolIcon.IconName ="{Binding Source={StaticResource LanguageInfo}, XPath=//Strings/#Down}" local:ToolIcon.Image="pack://application:,,,/CalUI;component/images/Down.png"
Style="{DynamicResource ToolIcon}" Click="Move_Down"/>
</Canvas>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
Here's the XAML for the ToolIcon Style
<Style x:Key="ToolIcon" TargetType="{x:Type Button}">
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid x:Name="ImageGrid">
<Grid.Effect>
<local:SaturationLuminanceEffect SaturationShift="0.95" LuminanceShift="0.8" />
</Grid.Effect>
<Image x:Name="image" RenderTransformOrigin="0.5,0.5" Source="{TemplateBinding local:ToolIcon.Image}" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Effect" TargetName="ImageGrid">
<Setter.Value>
<local:SaturationLuminanceEffect SaturationShift="1" LuminanceShift="1.2" />
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Effect" TargetName="ImageGrid">
<Setter.Value>
<local:SaturationLuminanceEffect SaturationShift="1.05" LuminanceShift="1.0" />
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Effect" TargetName="ImageGrid">
<Setter.Value>
<local:SaturationLuminanceEffect SaturationShift="0.80" LuminanceShift="1.3" />
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
#CodeNaked had the following insight in a comment:
Clipping can be a tricky business. See this question for more info on the subject.
The question mentioned is «Why do my panels clip all the way around the panel when made smaller than the explicit size?»

DataTrigger inside ControlTemplate doesn't update

I have a ListBox that is bound to a list of CustomerViewModel-objects, that each has two dependency properties:
- Name (string)
- Description (string)
- IsVisible (bool)
(the IsVisible property is True by default and is reversed via the ToggleVisibility Command on the CustomerViewModel)
I would like to display the Name and Description to the right of a Border-control, that is has a Transparent background when the IsVisible property is True and Green when the False.
My problem is that the DataTrigger part of the code below doesn't work the way I want, because the Setter-part isn't triggered when the IsVisible is changed.
What am I doing wrong?
Here's my code:
<UserControl.Resources>
<Style x:Key="ListBoxStyle" TargetType="{x:Type ListBox}">
<Setter Property="Margin" Value="-1,-1,0,0" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="ItemContainerStyle" Value="{DynamicResource ListboxItemStyle}" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled" />
</Style>
<Style x:Key="ListboxItemStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Grid>
<Border x:Name="border" Background="{TemplateBinding Background}" BorderBrush="#FFD4D6D5" BorderThickness="0,0,0,1">
<Grid Height="70" Margin="0,0,10,0">
<Grid.RowDefinitions>
<RowDefinition Height="10" />
<RowDefinition Height="Auto" />
<RowDefinition />
<RowDefinition Height="10" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Border x:Name="visibilityColumn" Grid.Row="0" Grid.Column="0" Grid.RowSpan="4" Background="Transparent" Width="4" Margin="0,0,4,0" />
<TextBlock x:Name="customerName" Grid.Row="1" Grid.Column="1" Foreground="#FF191919" FontWeight="Bold" Text="{Binding Name}" VerticalAlignment="Top" />
<TextBlock Grid.Row="2" Grid.Column="1" VerticalAlignment="Stretch" Text="{Binding Description}" TextWrapping="Wrap" Foreground="#FFB4B4B4" TextTrimming="CharacterEllipsis" />
</Grid>
<Border.ContextMenu>
<ContextMenu>
<MenuItem Header="Edit..." />
<MenuItem Header="Visible" IsCheckable="True" IsChecked="{Binding IsVisible}" Command="{Binding ToggleVisibility}"/>
</ContextMenu>
</Border.ContextMenu>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#FFEEEEEE" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="#FFF5F5F5" />
<Setter TargetName="customerName" Property="Foreground" Value="Green" />
</Trigger>
<DataTrigger Binding="{Binding IsVisible}" Value="False"> <!--If Value="True" the customerName Border shows up green!-->
<Setter Property="Background" Value="Green" />
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<ListBox Style="{StaticResource ListBoxStyle}" ItemsSource="{Binding CustomerViewModels}" />
UPDATED:
The DataTrigger was indeed missing the TargetName="visibilityColumn" as pointed out by Goblin.
However - the "real" problem was, this line:
<MenuItem Header="Visible" IsCheckable="True" IsChecked="{Binding IsVisible}" Command="{Binding ToggleVisibility}"/>
A checkable MenuItem has a TwoWay binding-mode on the IsChecked-property, so I was actually inverting the IsVisiblity twice - via databinding and via the ToggleVisibility command... Whoops :)
Try switching this part:
<DataTrigger Binding="{Binding IsVisible}" Value="False">
<Setter Property="Background" Value="Green" />
</DataTrigger>
With this part:
<DataTrigger Binding="{Binding IsVisible}" Value="False">
<Setter TargetName="visibilityColumn" Property="Background" Value="Green" />
</DataTrigger>
I think you missed the TargetName property in your setter. (Same goes for your IsSelected- and IsMouseOver-trigger by the way)
Hope this helps!

Resources