XAML trigger not triggering - c#

do you see anything wrong with this trigger?
<Border Margin="2" BorderBrush="#6593CF" BorderThickness="1.5" >
<Border.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding IsCreating, UpdateSourceTrigger=PropertyChanged}" Value="true">
<Setter Property="Border.BorderBrush" Value="Lime"/>
<Setter Property="Border.BorderThickness" Value="3" />
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
It is bound to this property:
private bool _IsCreating = false;
public bool IsCreating
{
get
{
return _IsCreating;
}
set
{
if (_IsCreating == value)
{
return;
}
_IsCreating = value;
RaisePropertyChanged("IsCreating");
}
}
When I set IsCreating = true, the style does not update.

You have set BorderBrush and BorderThinkness inline on your border. Inline declaration has quite hight precedence and override your trigger. Remove your inline declaration from border and move it to trigger:
<Border Margin="2">
<Border.Style>
<Style TargetType="{x:Type Border}">
<Style.Triggers>
<DataTrigger
Binding="{Binding Path=DataContext.IsCreating, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
Value="true">
<Setter Property="BorderBrush" Value="Lime" />
<Setter Property="BorderThickness" Value="3" />
</DataTrigger>
<DataTrigger
Binding="{Binding Path=DataContext.IsCreating, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
Value="false">
<Setter Property="BorderBrush" Value="#6593CF" />
<Setter Property="BorderThickness" Value="1.5" />
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<CheckBox IsChecked="{Binding IsCreating}" />
</Border>

Related

ScaleTransform binds but does not update when the bound property is changed

I bound ViewScale to Grid's ScaleTransform and when the app starts it correctly scales by 2. But when I change ViewScale by pressing F12, it doesn't trigger ScaleTransform update even though the property value is changed.
Here is the code:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace test
{
public partial class MainWindow : Window
{
public event PropertyChangedEventHandler PropertyChanged;
protected void SetField<T> ( ref T field, T value, string propertyName )
{
if ( !EqualityComparer<T>.Default.Equals ( field, value ) )
{
field = value;
PropertyChanged?.Invoke ( this, new PropertyChangedEventArgs ( propertyName ) );
}
}
decimal viewScale = 2;
public decimal ViewScale
{
get => this.viewScale;
set => SetField ( ref this.viewScale, value,
"ViewScale"
);
}
ObservableCollection<Coin> _coins;
public ObservableCollection<Coin> Coins { get => _coins; set => SetField ( ref _coins, value, nameof ( _coins ) ); }
public ICollectionView CollectionView;
public MainWindow ( )
{
this.Coins = new ObservableCollection<Coin> ( );
for ( int i = 0 ; i < 100 ; ++i )
this.Coins.Add ( new Coin ( "Coin 1", i ) );
this.DataContext = this;
InitializeComponent ( );
this.PreviewKeyDown += MainWindow_PreviewKeyDown;
}
void MainWindow_PreviewKeyDown ( object sender, KeyEventArgs e )
{
Console.WriteLine ( e.Key );
if ( e.Key == Key.Home )
{
this.dataGrid.ScrollIntoView ( this.dataGrid.Items [ this.dataGrid.Items.Count - 1 ] );
this.dataGrid.UpdateLayout ( );
this.dataGrid.ScrollIntoView ( this.dataGrid.Items [ 0 ] );
}
else if ( e.Key == Key.F12 )
{
this.ViewScale += 0.1m;
}
}
void MainWindow_KeyDown ( object sender, KeyEventArgs e )
{
}
}
public class Coin
{
public string Symbol { get; set; }
public int PNL { get; set; }
public SolidColorBrush Color2 { get; set; }
public Coin ( string symbol, int pnl )
{
this.Symbol = symbol;
this.PNL = pnl;
Random rnd = new Random ( );
Color c = Color.FromRgb ( ( byte ) rnd.Next ( 256 ), ( byte ) rnd.Next ( 256 ), ( byte ) rnd.Next ( 256 ) );
this.Color2 = new SolidColorBrush ( c );
}
}
}
XAML:
<Window x:Class="test.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:test"
mc:Ignorable="d"
Name="myMainWindow"
SizeToContent="Width"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Title="Profit Tracker"
WindowStyle="None"
Topmost="True"
Height="426">
<Window.Resources>
<Style x:Key="DataGridColumnSeparatorStyle" TargetType="DataGridCell">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Rectangle VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Fill="#1e90ff"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="DataGridColumnAlarmStyle" TargetType="DataGridCell">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Rectangle VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Fill="#000000"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type DataGrid}">
<Setter Property="Background" Value="#FFF" />
<Setter Property="AlternationCount" Value="2" />
<Setter Property="BorderBrush" Value="Red" />
<Setter Property="BorderThickness" Value="0" />
</Style>
<Style x:Key="RowStyleWithAlternation" TargetType="DataGridRow">
<Setter Property="Background" Value="#141414"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="FontWeight" Value="Normal"/>
<Style.Triggers>
<Trigger Property="AlternationIndex" Value="0">
<Setter Property="Background" Value="#141414"/>
</Trigger>
<Trigger Property="AlternationIndex" Value="1">
<Setter Property="Background" Value="#282828"/>
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="BorderBrush" Value="Red" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Margin" Value="-1,0,0,0" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<!--<Setter Property="BorderBrush" Value="#2eff00" />
<Setter Property="BorderThickness" Value="1" />-->
<Setter Property="Background" Value="Orange"/>
<!--<Setter Property="Margin" Value="-1,0,0,0" />-->
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="DataGridCell">
<Setter Property="TextBlock.TextAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Grid Background="{TemplateBinding Background}">
<ContentPresenter VerticalAlignment="Stretch"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="BorderBrush" Value="#1e90ff" />
<Setter Property="BorderThickness" Value="1" />
<!--<Setter Property="Background" Value="Red"/>-->
</Trigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Column.DisplayIndex, RelativeSource={RelativeSource Self}}" Value="4"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="VerticalAlignment" Value="Stretch"/>
</MultiDataTrigger.Setters>
</MultiDataTrigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="{x:Null}"/>
<Setter Property="BorderBrush" Value="{x:Null}"/>
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="DataGridColumnHeader">
<Setter Property="HorizontalContentAlignment" Value="Center" />
</Style>
<Style TargetType="{x:Type ProgressBar}">
<Setter Property="Padding" Value="0"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ProgressBar">
<Border BorderThickness="1" Background="#006400" CornerRadius="0" Padding="0">
<Grid x:Name="PART_Track">
<Rectangle x:Name="PART_Indicator" HorizontalAlignment="Left" Fill="#75001D" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<CollectionViewSource Source="{Binding Coins}" IsLiveSortingRequested="True" x:Key="MyKey" />
</Window.Resources>
<Grid>
<Grid.LayoutTransform>
<ScaleTransform ScaleX="{Binding ViewScale, ElementName=myMainWindow}" ScaleY="{Binding ViewScale, ElementName=myMainWindow}" />
</Grid.LayoutTransform>
<DataGrid Name="dataGrid" ItemsSource="{Binding Source={StaticResource MyKey}}" SelectionMode="Single" GridLinesVisibility="None" HorizontalScrollBarVisibility="Hidden" RowHeaderWidth="0" IsReadOnly="True" CanUserAddRows="False" CanUserResizeColumns="False" CanUserResizeRows="False" AutoGenerateColumns="False" RowStyle="{StaticResource RowStyleWithAlternation}">
<DataGrid.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Transparent" />
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTemplateColumn MinWidth="0" Width="2" CellStyle="{StaticResource DataGridColumnSeparatorStyle}"/>
<DataGridTextColumn Header="PNL" Width="60" SortMemberPath="Balance.UnitPrice" Binding="{Binding Path=PNL}" />
<DataGridTemplateColumn MinWidth="0" Width="2" CellStyle="{StaticResource DataGridColumnSeparatorStyle}" CanUserSort="False"/>
<DataGridTemplateColumn Header="Price" Width="60" SortMemberPath="Price">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<Grid>
<Border BorderBrush="#241C59" BorderThickness="1" CornerRadius="1" Background="#2D255B">
<Border BorderBrush="#206fb6" BorderThickness="4" CornerRadius="2" ClipToBounds="True" Margin="-1" HorizontalAlignment="Stretch">
<Border.Effect>
<BlurEffect Radius="10"/>
</Border.Effect>
</Border>
</Border>
<Border Margin="1" VerticalAlignment="Stretch" BorderThickness="0." Background="#69ABDB" HorizontalAlignment="Left" Width="30">
<Border BorderBrush="#38e2ff" BorderThickness="2" CornerRadius="2" ClipToBounds="False">
<Border.Effect>
<BlurEffect Radius="5"/>
</Border.Effect>
</Border>
</Border>
</Grid>
<TextBlock Text="25%" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Vol BTC/h" Width="30" SortMemberPath="LastHourVolumeInBtc">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<TextBlock Text="ABCDE" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Vol BTC/h" Width="40">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<ProgressBar Value="0.3" Minimum="0" Maximum="1"/>
<TextBlock Text="12345" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Net BTC/m" Width="60"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
In order to provide property changed notifications, you have to implement the INotifyPropertyChanged interface in the type that the bound property is defined. You missed this part in your MainWindow code-behind, which is also the data context of your window.
public partial class MainWindow : Window, INotifyPropertyChanged
Although you defined the PropertyChanged event and your SetField method raises the event correctly, WPF will not be aware of it, if you do not declare the interface on your class definition.

C# WPF Treeview ItemContainerStyle makes mouseclick event sender lose TreeviewItem reference

I have this code that works,
private void TreeSetup_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
if (sender is TreeViewItem)
{
((TreeViewItem)sender).IsSelected = true;
}
e.Handled = true;
}
private void TreeSetup_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
{
ContextMenu PopupMenu = this.FindResource("cmButton") as ContextMenu;
if (TreeSetup.SelectedItem != null)
{
PopupMenu.PlacementTarget = sender as TreeViewItem;
PopupMenu.IsOpen = true;
}
}
But once I add this ItemContainerStyle,
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}" />
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}"/>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontWeight" Value="Bold" />
</Trigger>
</Style.Triggers>
</Style>
</TreeView.ItemContainerStyle>
My sender on the mouse down event becomes a TreeView instead of TreeViewItem.
Does anyone know the cause and fix to this?
I binded the mousedown event under the ItemContainerStyle:
<TreeView.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<EventSetter Event="MouseRightButtonDown" Handler="TreeSetup_MouseRightButtonDown"/>
<Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}" />
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}"/>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontWeight" Value="Bold" />
</Trigger>
</Style.Triggers>
</Style>
</TreeView.ItemContainerStyle>

TextBox not resetting focus when reopening the dropdown in a ComboBox

I have a customized ComboBox to handle the text input and filter the itemsource. The problem I'm having is when I open the ComboBox the textBox is focused and let me write in it, then if I close and open it again, the TextBox is not focused and I cant write anything inside. I've discovered that the first time the comboBox is opening it is setting the focus on the TextBox but when I close it the TextBox keeps its IsFocused property true so when reopening the problem happens. It's just when opening and reopening clicking the comboBox because if I click outside the ComboBox to close it and then open it again everything works nice.
Here is the customized style I wrote and the ComboBox I'm using.
<Style x:Key="FilteringComboBox" TargetType="ComboBox">
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Visible" />
<Setter Property="ScrollViewer.CanContentScroll" Value="true" />
<Setter Property="IsEditable" Value="True"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="FontFamily" Value="Coves"/>
<Setter Property="FontWeight" Value="Normal"/>
<Setter Property="FontSize" Value="12"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBox">
<Border x:Name="TopBorder"
CornerRadius="8"
BorderBrush="Grey"
BorderThickness="1"
Padding="10,0,1,0">
<Border.Background>
<LinearGradientBrush EndPoint="0.504,1.5" StartPoint="0.504,0.03">
<GradientStop Color="White" Offset="0"/>
<GradientStop Color="#e3e3e5" Offset="0.65"/>
</LinearGradientBrush>
</Border.Background>
<Grid>
<ToggleButton
Name="ToggleButton"
Template="{DynamicResource FilteringComboBoxToggleButton}"
Grid.Column="2"
Focusable="false"
IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
ClickMode="Press">
</ToggleButton>
<TextBlock Name="ContentSite" IsHitTestVisible="False"
Text="{Binding Source={StaticResource Proxy}, Path=Data.Name, UpdateSourceTrigger=PropertyChanged}"
Visibility="Visible" Foreground="#37465c"
Padding="3,3,23,3" VerticalAlignment="Center"
HorizontalAlignment="Left" />
<TextBox x:Name="PART_EditableTextBox" MaxWidth="215" MinWidth="100"
Text="{Binding Source={StaticResource Proxy}, Path=Data.FilterText, UpdateSourceTrigger=PropertyChanged}"
Foreground="#37465c"
HorizontalAlignment="Left" VerticalAlignment="Center" Margin="3,3,23,3" Focusable="True" Background="Transparent"
Visibility="Collapsed"/>
<Popup x:Name="Popup" Placement="Bottom" IsOpen="{TemplateBinding IsDropDownOpen}" AllowsTransparency="True"
Focusable="False" PopupAnimation="Fade">
<StackPanel Orientation="Vertical" Width="215">
<Grid Name="DropDown" SnapsToDevicePixels="True"
MaxHeight="{TemplateBinding MaxDropDownHeight}">
<Border x:Name="DropDownBorder" BorderThickness="1"
BorderBrush="#888">
<Border.Background>
<LinearGradientBrush EndPoint="0.504,1.5" StartPoint="0.504,0.03">
<GradientStop Color="White" Offset="0"/>
<GradientStop Color="#e3e3e5" Offset="0.65"/>
</LinearGradientBrush>
</Border.Background>
<ScrollViewer Margin="0" SnapsToDevicePixels="True">
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained"/>
</ScrollViewer>
</Border>
</Grid>
</StackPanel>
</Popup>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Cursor" Value="Hand"/>
</Trigger>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="IsDropDownOpen" Value="True"/>
<Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Visible" />
<Setter TargetName="ContentSite" Property="Visibility" Value="Collapsed" />
<Setter Property="IsEditable" Value="True"/>
</Trigger>
<Trigger Property="IsMouseCaptured" Value="False">
<Setter Property="IsDropDownOpen" Value="False"/>
<Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Collapsed" />
<Setter TargetName="ContentSite" Property="Visibility" Value="Visible" />
<Setter Property="Text" Value=""/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I tried adding this event handler to remove the focus but it isn't working
private static void QuantityBox_IsMouseCapturedWithin(object sender, DependencyPropertyChangedEventArgs e)
{
var qBox = sender as ComboBox;
if (qBox.IsDropDownOpen == false)
{
Keyboard.ClearFocus();
flag = true;
}
}
Hope that this helps someone, the erratic behaviour was happening because I was using these triggers:
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="IsDropDownOpen" Value="True"/>
<Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Visible" />
<Setter TargetName="ContentSite" Property="Visibility" Value="Collapsed" />
<Setter Property="IsEditable" Value="True"/>
</Trigger>
<Trigger Property="IsMouseCaptured" Value="False">
<Setter Property="IsDropDownOpen" Value="False"/>
<Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Collapsed" />
<Setter TargetName="ContentSite" Property="Visibility" Value="Visible" />
<Setter Property="Text" Value=""/>
</Trigger>
The triggers were ment to handle the visibility toggle between the TexBlock and the TextBox (showing the TextBlock when the ComboBox was inactive and the TextBox when it is focused so the user can type and filter).
So I removed the triggers and handled that behaviour in a dependency property:
public static readonly DependencyProperty MouseCapturedProperty = DependencyProperty.RegisterAttached("MouseCaptured",
typeof(bool), typeof(QuantitiesBoxBehaviours),
new UIPropertyMetadata(false, MouseCapturedPropertyChangedCallback));
public static bool GetMouseCaptured(UIElement element)
{
return (bool)element.GetValue(MouseCapturedProperty);
}
public static void SetMouseCaptured(UIElement element, bool command)
{
element.SetValue(MouseCapturedProperty, command);
}
private static void MouseCapturedPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var qBox = d as ComboBox;
bool value = GetMouseCaptured(qBox);
if (qBox != null && value)
{
qBox.IsMouseCaptureWithinChanged += QBox_IsMouseCaptureWithinChanged;
qBox.DropDownOpened += QBox_DropDownOpened;
}
}
private static void QBox_DropDownOpened(object sender, EventArgs e)
{
var qBox = sender as ComboBox;
var template = qBox.Template;
var txtBox = template.FindName("PART_EditableTextBox", qBox) as TextBox;
var txtBlock = template.FindName("ContentSite", qBox) as TextBlock;
txtBlock.Visibility = Visibility.Collapsed;
txtBox.Visibility = Visibility.Visible;
}
private static void QBox_IsMouseCaptureWithinChanged(object sender, DependencyPropertyChangedEventArgs e)
{
var qBox = sender as ComboBox;
var template = qBox.Template;
var txtBox = template.FindName("PART_EditableTextBox", qBox) as TextBox;
var txtBlock = template.FindName("ContentSite", qBox) as TextBlock;
if (qBox.IsDropDownOpen == false)
{
Keyboard.ClearFocus();
txtBox.Visibility = Visibility.Collapsed;
txtBlock.Visibility = Visibility.Visible;
qBox.ItemsSource = _presentationQuantities;
flag = true;
}
}
That solved the problem and now it's working great, that property was set to the ComboBox.

Swapping ContentPresenter content in custom control

I have 2 ContentPresenter fixedContentPresenter and resizableContentPresenter and obviously a Content in Generic.xaml. How can i set the Content to be only in fixedContentPresenter when FixedContent = true; and Content to be only in resizableContentPresenter when FixedContent = false;
I tried changing the content in the code but the content is not showing.
Xaml:
<Grid>
<ContentPresenter x:Name="fixedContent"/>
<Grid>
<ContentPresenter x:Name="resizableContent"/>
</Grid>
</Grid>
Use an implicit style on the content presenters to either hide or show a specific presenter depending on the value of FixedContent
<Style TargetType={x:Type ContentPresenter } x:Key="HideOrShow">
<Style.Triggers>
<DataTrigger Binding="{Binding FixedContent}" Value="False">
<Setter Property="Visibility" Value="Hidden"/>
</DataTrigger>
</Style.Triggers>
</Style>
You should use ContentControl here instead of ContentPresenter.
When FixedContent values changes, Content becomes null, so no Animation related side-effects.
<Grid Background="Purple">
<ContentControl x:Name="fixedContent" Margin="0,75,0,0">
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<Style.Triggers>
<DataTrigger Binding="{Binding FixedContent, Mode=OneWay}" Value="false">
<DataTrigger.Setters>
<Setter Property="Content" Value="{StaticResource ContentKey}"/>
</DataTrigger.Setters>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
<Grid Background="Red" Margin="0,54,0,0">
<ContentControl x:Name="resizableContent" Margin="0,75,0,0">
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<Style.Triggers>
<DataTrigger Binding="{Binding FixedContent, Mode=OneWay}" Value="true">
<DataTrigger.Setters>
<Setter Property="Content" Value="{StaticResource ContentKey}"/>
</DataTrigger.Setters>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</Grid>
</Grid>
After a day of struggle, I finally found a better answer than that proposed by #OmegaMan, let's hope it help others. Here's the new XAML (added Content="{x:Null}" to both ContentPresenter):
<Grid>
<ContentPresenter x:Name="fixedContent" Content="{x:Null}"/>
<Grid>
<ContentPresenter x:Name="resizableContent" Content="{x:Null}"/>
</Grid>
</Grid>
And the FixedContent logic:
public bool FixedContent
{
get { return (bool)GetValue(FixedContentProperty); }
set
{
SetValue(FixedContentProperty, value);
if (value) // Is Fixed
{
ResizableContentPresenter.Content = null;
FixedContentPresenter.Content = Content;
}
else
{
FixedContentPresenter.Content = null;
ResizableContentPresenter.Content = Content;
}
}
}

WPF Enable Disable Border based on MultiDataTrigger not working

I have a border in WPF that I am trying to enable or disable based on two properties in the viewmodel: ConnectedVisibility and OperatingMode. This data trigger disables the border when connectedvisibility visibility is not set to "Visible". But it does not work for OperatingMode. For OperatingMode other than 0, the border should be disabled but it stays enabled. It appears that there is no impact of OperatingMode changing its value at all. Even the breakpoints that I put in the convertor are not being hit except when the program first starts up. The bindings look Ok as there is no problem shown in Debug output for these bindings. Any help is appreciated.
The Style is
<Style x:Key="EnableOnConnectBorderCorrected" TargetType="{x:Type Border}">
<!--<Setter Property="BorderBrush" Value="#FFDADADA"/>-->
<Setter Property="BorderBrush" Value="Red"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="CornerRadius" Value="2"/>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ConnectedVisibility}" Value="Visible"/>
<Condition Binding="{Binding OperatingMode}" Value="0"/>
</MultiDataTrigger.Conditions>
<Setter Property="IsEnabled" Value="True"/>
</MultiDataTrigger>
<DataTrigger Binding="{Binding OperatingMode, Converter={x:Static VM:IsEqualOrGreaterThanSHORTConverter.Instance}, ConverterParameter=1,Mode=TwoWay}" Value="True">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
<DataTrigger Binding="{Binding ConnectedVisibility}" Value="Collapsed">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
</Style.Triggers>
</Style>
The convertor used in the style is ->
public class IsEqualOrGreaterThanSHORTConverter : IValueConverter
{
public static readonly IValueConverter Instance = new IsEqualOrGreaterThanSHORTConverter();
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
short iValue = (short)value;
short compareToValue = System.Convert.ToInt16(parameter);
return iValue >= compareToValue;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
The XAML where this style is applied is
<Border Name="RebootDash" Grid.Row="2" Grid.Column="1" Style="{StaticResource EnableOnConnectBorderCorrected}" BorderBrush="#FFDADADA" BorderThickness="1" CornerRadius="2" Width="Auto" Margin="0,1,1,0">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Border Grid.Row="2" Background="Wheat"/>
<telerik:RadButton Command="{Binding ResetUnitCommand, Source={StaticResource UnitCommandProvider}}" Style="{StaticResource DashBoardImageButton}">
<Image Grid.Row="0" Source="/Images/UnitManagementImages/IMG_THOR_UNITResetUnit128.png"
ToolTip="{x:Static properties:Resources.Unit_Command_ResetUnit}"
Width="40" Height="40"
Margin="0,5,0,5"
HorizontalAlignment="Center"/>
</telerik:RadButton>
<TextBlock Grid.Row="2" Text="{x:Static properties:Resources.Unit_Command_ResetUnit}" HorizontalAlignment="Center" Margin="5,5,5,5"/>
</Grid>
</Border>
The properties to which it is bound are
public Visibility ConnectedVisibility
{
get { return connectedVisibility; }
set
{
if (connectedVisibility == value) return;
connectedVisibility = value;
RaisePropertyChanged("ConnectedVisibility");
}
}
public short OperatingMode
{
get { return UnitOperatingModeVM.OperatingMode; }
set
{
UnitOperatingModeVM.OperatingMode = value;
}
}
since you have only one condition to enable the same, so perhaps setting IsEnabled to False by default should do the trick
<Style x:Key="EnableOnConnectBorderCorrected" TargetType="{x:Type Border}">
<!--<Setter Property="BorderBrush" Value="#FFDADADA"/>-->
<Setter Property="BorderBrush" Value="Red"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="CornerRadius" Value="2"/>
<Setter Property="IsEnabled" Value="False"/>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ConnectedVisibility}" Value="Visible"/>
<Condition Binding="{Binding OperatingMode}" Value="0"/>
</MultiDataTrigger.Conditions>
<Setter Property="IsEnabled" Value="True"/>
</MultiDataTrigger>
</Style.Triggers>
</Style>
I have added <Setter Property="IsEnabled" Value="False"/> in the style which will by default disable the control and I have removed the other redundant conditions
so as result when the both conditions in MultiDataTrigger will meet it will enable the same, otherwise it remains disabled
above example assumes that both of the property in MultiDataTrigger ConnectedVisibility & OperatingMode are notifying the changes.
you may also need to add the notification for OperatingMode in order for MultiDataTrigger to fire the trigger
public short OperatingMode
{
get { return UnitOperatingModeVM.OperatingMode; }
set
{
UnitOperatingModeVM.OperatingMode = value;
RaisePropertyChanged("OperatingMode");
}
}
Is your OperatingMode property set implementation call RaisePropertyChanged("OperatingMode");
private short operatingMode;
public short OperatingMode
{
get
{
return operatingMode;
}
set
{
if (operatingMode != value)
{
operatingMode = value;
this.RaisePropertyChanged("OperatingMode");
}
}
}

Categories

Resources