xaml code not working - c# - xaml

I have following code:
<DataTemplate DataType="{x:Type abc}">
<StackPanel Orientation="Horizontal">
<CheckBox Margin="0,0,3,0" x:Name="CheckBox">
<CheckBox.IsChecked>
<Binding Path="IsSelected"
Mode="TwoWay">
<Binding.RelativeSource>
<RelativeSource Mode="Template" />
</Binding.RelativeSource>
</Binding>
</CheckBox.IsChecked>
</CheckBox>
<TextBlock Text="{Binding}"
Margin="0,0,10,5" />
<TextBlock Text="{Binding Channel}"
Margin="7,0,0,0"
Visibility="{Binding Path=IsChannelVisible,ElementName=View, Converter={StaticResource BooleanToVisibile}}" />
</StackPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Valid}" Value="true">
<Setter TargetName="CheckBox" Property="Foreground" Value="#000000"/>
</DataTrigger>
<DataTrigger Binding="{Binding Valid}" Value="false">
<Setter TargetName="CheckBox" Property="Foreground" Value="#999999"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
What i am trying to achieve is change the color of the the checkbox text. But above code is not working. Can anyone please help me with this?
Tried code from Tilak:
<ControlTemplate x:Key="Template"
TargetType="ListViewItem">
<StackPanel Orientation="Horizontal">
<CheckBox Margin="7,0,0,0" Foreground={Binding Valid, Converter={StaticResource ValidToColorConverter}}
x:Name="CheckBox">
<CheckBox.IsChecked>
<Binding Path="IsSelected"
Mode="TwoWay">
<Binding.RelativeSource>
<RelativeSource Mode="Parent" />
</Binding.RelativeSource>
</Binding>
</CheckBox.IsChecked>
</CheckBox>
<ContentPresenter />
<DataTemplate.CheckBox>
<Intellivu:ValidToColorConverter x:Key="ValidToColorConverter" />
</DataTemplate.CheckBox>
</StackPanel>
</ControlTemplate>
This is not working? Am i doing something wrong?

You can use converter and bind to Foreground property directly.
Following following steps for it
Create ValidToColorConverter
public class ValidToColorConverter : IValueConverter
{
// This converts the DateTime object to the string to display.
public object Convert(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
bool valid = value as bool;
return valid ? Colors.Black : new SolidColorBrush(Colors.FromArgb(255,99,99,99));
}
// No need to implement converting back on a one-way binding
public object ConvertBack(object value, Type targetType,
object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Add ValidToColorConverter as static resource in the resources corresponding to control
<DataTemplate.Resources>
<local:ValidToColorConverter x:Key="ValidToColorConverter" />
</DataTemplate.Resources>
Note - local should be added into page namespaces(corresponding to namespace where converter is defined)
Refer to Converter in the Checkbox
<CheckBox Margin="0,0,3,0" Foreground={Binding Valid, Converter={StaticResource ValidToColorConverter}} x:Name="CheckBox">

Related

Xaml how to make a condition

Hi Guys i have a problems
Well, I have a sql command that extracts the number of days remaining until the end of the order. Below is the code in XAML and the problem is that there is no idea how to do that e.g. if the number of days is greater than 5 then color green etc? It's about making a condition. I am a beginner and I am asking for some thought. Regards.
XAML CODE
<DataTemplate xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:user="clr-namespace:Okna.Documents.Views.User;assembly=Okna.Documents">
<Grid
x:Name="grid">
<TextBlock
Margin="3,2"
Text="{Binding RowData.Row.ud_pozostalo_dni2}" />
</Grid>
<DataTemplate.Triggers>
<DataTrigger
Binding="{Binding RowData.Row.ud_pozostalo_dni2}"
Value="8">
<Setter
TargetName="grid"
Property="Background"
Value="Green" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
SQL select datediff(day,getdate(), o.realizacja)
You can add a value converter for this.
An example converter can be:
public class CellColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
int val = (int)value;
if (val > 5)
{
return Brushes.Green;
}
return Brushes.Transparent;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
And in your XAML:
<Window.Resources>
<local:CellColorConverter x:Key="CellColorConverter"/>
</Window.Resources>
<Grid x:Name="grid">
<TextBlock
Margin="3,2"
Text="{Binding RowData.Row.ud_pozostalo_dni2}" Background="{Binding RowData.Row.ud_pozostalo_dni2,Converter={StaticResource CellColorConverter}}" />
</Grid>

Tooltip position in Oxyplot

I am recently using OxyPlot to draw charts for my WPF project. I have an issue with the tooltip in a line series. The rectangle box of the tooltip is too close to the point my mouse locates. I am wondering if there is any way to modify the position of the tooltip box and make it further from the cursor. Thank a lot. For example, I would like to move the tooltip box (in the red box) to right a bit.
[Edit]
Following Anu's idea, I added the following code but seems like it not works as expected.
In the xaml.cs file, I added
<UserControl.Resources>
<popups:ScreenPointToOffSetScreenPointConverter x:Key="ScreenPointToOffSetScreenPointConverter"/>
</UserControl.Resources>
And then change my OxyPlot to
<ItemsControl ItemsSource="{Binding AmplitudeDtos}" Margin="0" Name="Amplitude" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid popups:GridUtilities.ItemsPerRow="1" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type dtoModels:SignalDto}">
<oxy:PlotView Height="Auto" Width="Auto" MinHeight="40" MinWidth="100" HorizontalContentAlignment="Stretch"
FontStyle="Normal" FontFamily="Roboto, Microsoft YaHei" FontSize="8" Model="{Binding PlotModel}" Controller="{Binding PlotController}" Padding="8" Margin="0">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding SignalLoadedCommand}" CommandParameter="{Binding}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<oxy:PlotView.DefaultTrackerTemplate>
<ControlTemplate>
<oxy:TrackerControl Position="{Binding Position, Converter={StaticResource ScreenPointToOffSetScreenPointConverter}}" LineExtents="{Binding PlotModel.PlotArea}">
<oxy:TrackerControl.Content>
<TextBlock Text="{Binding}" />
</oxy:TrackerControl.Content>
</oxy:TrackerControl>
</ControlTemplate>
</oxy:PlotView.DefaultTrackerTemplate>
</oxy:PlotView>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Please note that my OxyPlot is in a DataTemplate.
ScreenPointToOffSetScreenPointConverter class is the exactly the same as in Anu's example.
A relatively simple fix for the requirement would be to modify DefaultTrackerTemplate and use a Custom Converter to change the Position.For example, You could define a ScreenPoint converter as following
public class ScreenPointToOffSetScreenPointConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if(value is ScreenPoint screenPoint)
{
return new ScreenPoint(screenPoint.X + 50, screenPoint.Y);
}
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
// TODO: Implement
throw new NotImplementedException();
}
}
And then in your XAML
<oxy:PlotView Model="{Binding MyModel}">
<oxy:PlotView.DefaultTrackerTemplate>
<ControlTemplate>
<oxy:TrackerControl Position="{Binding Position,Converter={StaticResource ScreenPointToOffSetScreenPointConverter}}" LineExtents="{Binding PlotModel.PlotArea}">
<TextBlock Text="{Binding}" />
</oxy:TrackerControl>
</ControlTemplate>
</oxy:PlotView.DefaultTrackerTemplate>
</oxy:PlotView>
The Converter would add an Offset to the ScreenPoint position for the Tracker. You could modify the Offset Value to the Converter if it makes sense for your application requirement.

DataGrid with binding for rows and just some columns?

How do I get a datagrid like this with templates for rows as well as for repeatable cells?
DataGrid is bound to a property called Blocks, which is a BindingList of Block type, defined in the view model:
<DataGrid x:Name="dgBlocks" DockPanel.Dock="Left"
Margin="20,10,10,20" AutoGenerateColumns="False"
ItemsSource="{Binding Blocks, Mode=TwoWay}"
IsSynchronizedWithCurrentItem="True"
CanUserAddRows="False"
SelectionUnit="Cell" SelectionMode="Single"
EnableColumnVirtualization="False"
EnableRowVirtualization="False"
SelectedIndex="-1" MinRowHeight="10"
LoadingRow="dg_LoadingRow"
SelectionChanged="dgBlocks_SelectionChanged"
>
<DataGrid.Resources>
<helper:BindingProxy x:Key="proxy" Data="{Binding}" />
<!--todo: change to symbol’s ‘ReadOnly’ property instead of block’s ‘Permission’ -->
<Style x:Key="CellPermissionStyle" TargetType="DataGridCell">
<Setter Property="Background" Value="{Binding Permission, Converter={StaticResource BlockPermissionToBrushConverter}}" />
<Setter Property="IsEnabled" Value="{Binding Permission, Converter={StaticResource BlockPermissionToBoolConverter}}" />
</Style>
</DataGrid.Resources>
<DataGrid.RowHeaderTemplate>
<DataTemplate>
<TextBlock Name="txtBlockRowHeader"
Text="{Binding Path=Header,
RelativeSource={RelativeSource AncestorType=DataGridRow}}">
</TextBlock>
</DataTemplate>
</DataGrid.RowHeaderTemplate>
<DataGrid.Columns>
<DataGridTemplateColumn>
<!-- Selection checkboxes -->
<DataGridTemplateColumn.Header>
<StackPanel>
<CheckBox HorizontalAlignment="Center" IsThreeState="True" ToolTip="Select All" Margin="10,0,0,0">
<CheckBox.IsChecked>
<Binding Path="DataContext.SelectAll"
RelativeSource="{RelativeSource AncestorType={x:Type UserControl}}"
Mode="TwoWay"
UpdateSourceTrigger="PropertyChanged"
/>
</CheckBox.IsChecked>
</CheckBox>
</StackPanel>
</DataGridTemplateColumn.Header>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox Margin="5,0,0,0" IsChecked="{Binding IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Width="50">
<DataGridTemplateColumn.Header>
<TextBlock Text="Repeat" HorizontalAlignment="Center" />
</DataGridTemplateColumn.Header>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<telerik:RadNumericUpDown Name="nudRepeatBlock" ValueFormat="Numeric" Width="40"
ToolTip="Repeat block number of times" IsInteger="True" IsEditable="True"
Minimum="1" Maximum="100" UpdateValueEvent="PropertyChanged"
Value="{Binding Repeat, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" MinWidth="40" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Name" Binding="{Binding Name}" IsReadOnly="True" CanUserReorder="False" CanUserResize="False"
Visibility="{Binding Data.Encoding, Converter={StaticResource Encoding8b10bToCollapsedConverter}, Source={StaticResource proxy}}">
<DataGridTextColumn.HeaderStyle>
<Style TargetType="DataGridColumnHeader">
<Setter Property="HorizontalContentAlignment" Value="Center" />
</Style>
</DataGridTextColumn.HeaderStyle>
</DataGridTextColumn>
<!--todo: change… -->
<DataGridTextColumn Header="[0]" Binding="{Binding .Symbols[0].SymbolText, UpdateSourceTrigger=LostFocus}" CellStyle="{StaticResource CellPermissionStyle}" />
<DataGridTextColumn Header="[1]" Binding="{Binding .Symbols[1].SymbolText, UpdateSourceTrigger=LostFocus}" CellStyle="{StaticResource CellPermissionStyle}" />
<!-- … -->
<DataGridTextColumn Header="[15]" Binding="{Binding .Symbols[15].SymbolText, UpdateSourceTrigger=LostFocus}" CellStyle="{StaticResource CellPermissionStyle}" />
</DataGrid.Columns>
</DataGrid>
Each Block object has a property called Symbols, defined as a BindingList of Symbol type, and some other properties. Symbols get shown in columns with headers [0], 1, etc.
Other block’s properties shown in other columns. E.g. IsSelected for checkbox, Reapeat, Name.
public interface ISymbol
{
int Index { get; set; }
bool ReadOnly { get; set; }
string SymbolText { get; set; }
}
public class BlockBase : ObservableObject, IDataErrorInfo
{
public bool IsSelected
{
get { return _isSelected; }
set
{
if (value == _isSelected)
return;
_isSelected = value;
OnPropertyChanged("IsSelected");
RaiseSelectionChangedEvent();
}
}
public string Name { get; set; }
public virtual BindingList<ISymbol> Symbols { get; set; }
public BlockPermission Permission { get; set; }
public int Repeat { get; set; }
}
public class Symbol : ObservableObject, ISymbol
{
DisplayFormat Format { get; set; }
public int Index { get; set; }
public virtual bool ReadOnly { get; set; }
public virtual string SymbolText
{
get { return (Format == DisplayFormat.Binary) ? _binSymbol : _hexSymbol;
}
set
{
// … validate and set _binSymbol & _hexSymbol values
OnPropertyChanged("SymbolText");
}
}
Now, I need to bind each symbol’s cell 'IsEnabled' property to Symbol's 'ReadOnly' property.
I tried to define this in DataGrid.Resources as CellPermissionStyle, but I don’t know how to access a Symbol on this level.
Also, it would be nice to replace all repeating DataGridTextColumn defenitions for symbols with a template.
Would somebody help me?
My researches just confirmed that unfortunately there is no way to do this with templates or styles applicable to a subset of columns. It is also imposible to send a parameter to a style or template as Mishka suggested :(.
So, I've just ended up with 'copy-paste-modify' cell style for each of my 16 columns like that:
<DataGridTextColumn Header="[0]" Binding="{Binding .Symbols[0].SymbolText, UpdateSourceTrigger=LostFocus}">
<DataGridTextColumn.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="Background" Value="{Binding .Symbols[0].ReadOnly, Converter={StaticResource SymbolReadOnlyToBrushConverter}}" />
<Setter Property="IsEnabled" Value="{Binding .Symbols[0].ReadOnly, Converter={StaticResource SymbolReadOnlyToEnabledConverter}}" />
<Setter Property="TextBlock.TextAlignment" Value="Center" />
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
...
<DataGridTextColumn Header="[15]" Binding="{Binding .Symbols[15].SymbolText, UpdateSourceTrigger=LostFocus}">
<DataGridTextColumn.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="Background" Value="{Binding .Symbols[15].ReadOnly, Converter={StaticResource SymbolReadOnlyToBrushConverter}}" />
<Setter Property="IsEnabled" Value="{Binding .Symbols[15].ReadOnly, Converter={StaticResource SymbolReadOnlyToEnabledConverter}}" />
<Setter Property="TextBlock.TextAlignment" Value="Center" />
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
Yes, I know, this XAML looks ugly, but it works for me without a risky redesign of existing code base.
I'd be happy if someone could suggest a better, more elegant way doing this in XAML.

ListBox and ApplicationBar: last element padding

I have a ListBox and ApplicationBar with Opacity=.5. I want that ListBox items are under the ApplicationBar.
Like figure:
But when I scrolled to end of list then last element of ListBox is under the ApplicationBar.
I want that last element is over ApplicationBar.
Can I add padding for a last element of the ListBox (LongListSelector)? How can solved this issue?
UPDATE
<ListBox Name="MyListBox">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<i:Interaction.Triggers>
<ec:DataTrigger Binding="{Binding RelativeSource=
{RelativeSource Self},
Converter={StaticResource IsLastItemInContainerConverter}}"
Value="True">
<ec:ChangePropertyAction PropertyName="Padding" Value="0,0,0,72"/>
</ec:DataTrigger>
</i:Interaction.Triggers>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Background="Red"
Width="400"
Height="120"
Margin="15">
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
UPDATE 2
My problem can be easily solved by using LongListSelector. Just add empty ListFooterTemplate with Height = ApplicationBar height.
You can use converter to check if it's last item in listbox and in case yes, set padding to desired value via DataTrigger.
Check my answer over here for converter code. Just for sake of completeness of this answer i will post that converter code here:
public class IsLastItemInContainerConverter : IValueConverter
{
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
DependencyObject item = (DependencyObject)value;
ItemsControl ic = ItemsControl.ItemsControlFromItemContainer(item);
return ic.ItemContainerGenerator.IndexFromContainer(item)
== ic.Items.Count - 1;
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
and use it like this:
<ListBox>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource=
{RelativeSource Self},
Converter={StaticResource IsLastItemInContainerConverter}}"
Value="True">
<Setter Property="Padding" Value="5"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
edit: Didn't see the update to the original question. The below remains for additional detail.
This solution is for Windows Phone 8 only (although you could use the LongListSelector from the Windows Phone Toolkit if you are targeting 7.1/5).
I'd replace the ListBox with the LongListSelector from the SDK
<Grid>
<controls:LongListSelector ItemTemplate="{StaticResource Item}" ListFooterTemplate="{StaticResource Footer}" />
</Grid>
and for the templates add
<phone:PhoneApplicationPage.Resources>
<DataTemplate x:Key="Item">
<StackPanel Background="Red"
Width="400"
Height="120"
Margin="15">
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="Footer">
<Border Height="72" />
</DataTemplate>
</phone:PhoneApplicationPage.Resources>
Maybe simplest solution is to customize ItemsPanel property on ListBox:
<ListBox>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Margin="0,0,0,150"/> <!-- set margin to show some 'blank' space after last item -->
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
...
</ListBox>
But be aware that by default ListBox uses VirtualizedStackPanel as ItemsPanel. If you change it to StackPanel, it may bring some performance penalty. This is solution is suitable for lists with few items.

XAML UserControl - Set Background based on Trigger

I have a UserControl that contains an Expander :
<UserControl x:Class="Client.DevicesExpander"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
x:Name="devicesExpander" >
<Expander Margin="1" Name="expander" FontSize="11" BorderThickness="1" BorderBrush="DarkRed" Foreground="Black" Header="{Binding ElementName=devicesExpander, Path=Header}" FontWeight="Bold" MouseDoubleClick="Expander_MouseDoubleClick" Expanded="Expander_Expanded" IsExpanded="{Binding ElementName=devicesExpander, Path=IsExpanded}" Background="{Binding ElementName=devicesExpander, Path=Background}">
<StackPanel Name="_devicesPanel">
<ListBox BorderThickness="0,1,0,0" Name="_devicesList" FontWeight="Normal" MouseDoubleClick="DevicesList_MouseDoubleClick" Background="{Binding ElementName=devicesExpander, Path=Background}" />
</StackPanel>
<Expander.Style>
<Style TargetType="{x:Type Expander}">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=devicesExpander, Path=IsExpanded}" Value="True">
<Setter Property="Background" Value="White" />
</DataTrigger>
</Style.Triggers>
</Style>
</Expander.Style>
</Expander>
</UserControl>
Ans basically all I'd like to do is change the Expander and StackPanel's Background color based on the IsExpanded of the UserControl (or Expander).
I've added three Dependancy Properties to the control :
public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register("Header", typeof(string), typeof(DevicesExpander));
public static readonly DependencyProperty IsExpandedProperty = DependencyProperty.Register("IsExpanded", typeof(bool), typeof(DevicesExpander));
public static readonly DependencyProperty BackgroundProperty = DependencyProperty.Register("Background", typeof(System.Windows.Media.Brush), typeof(DevicesExpander));
But my code does not work. The IsExpanded property from the usercontrol does work as the property changes accordingly (when the expander expands) when checked from within the window where the usercontrol is placed.
How can I change the background color of the Expander based on the UserControl.IsExpanded property ?
Thanks !
EDIT:
I have in the meanwhile done the following:
<UserControl.Resources>
<Style TargetType="{x:Type UserControl}">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=devicesExpander, Path=IsExpanded}" Value="True">
<Setter Property="Background" Value="White" />
</DataTrigger>
</Style.Triggers>
</Style>
</UserControl.Resources>
<Expander Margin="1" Name="expander" FontSize="11" BorderThickness="1" BorderBrush="DarkRed" Foreground="Black" Header="{Binding ElementName=devicesExpander, Path=Header}" FontWeight="Bold" MouseDoubleClick="Expander_MouseDoubleClick" Expanded="Expander_Expanded" IsExpanded="{Binding ElementName=devicesExpander, Path=IsExpanded}" Background="Transparent">
<StackPanel Name="_devicesPanel">
<ListBox BorderThickness="0,1,0,0" Name="_devicesList" FontWeight="Normal" MouseDoubleClick="DevicesList_MouseDoubleClick" Background="Transparent" />
</StackPanel>
</Expander>
and removed the BackgroundProperty dependancy property. I actually thought this could work, but alas ...
I have managed to solve my problem. Herewith the solution (showing only the essential code) ...
My Dependancy Property is created as follows:
public static readonly DependencyProperty IsExpandedProperty = DependencyProperty.Register("IsExpanded", typeof(bool), typeof(DevicesExpander));
public bool IsExpanded
{
get { return (bool)GetValue(IsExpandedProperty); }
set { SetValue(IsExpandedProperty, value); }
}
and my XAML is :
<UserControl x:Class="TestApp.DevicesExpander"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Name="devicesExpander">
<Expander>
<Expander.Style>
<Style TargetType="Expander">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=devicesExpander, Path=IsExpanded}" Value="True">
<Setter Property="Background" Value="Black" />
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=devicesExpander, Path=IsExpanded}" Value="False">
<Setter Property="Background" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</Expander.Style>
</Expander>
</UserControl>
The solution in the end was to remove the Backgroud property from the element and specify a DataTrigger for IsExpanded=True and IsExpanded=False. It thus seems like the Background property when specified in the element properties overrides anything that the triggers tried to set.
Hope this helps someone !
Herewith another solution to the same problem, this time using a IValueConverter ...
My XAML:
<UserControl.Resources>
<local:BackgroundConverter x:Key="backgroundConvertor" />
</UserControl.Resources>
<Expander>
<Expander.Style>
<Style TargetType="Expander">
<Setter Property="Background" Value="{Binding ElementName=devicesEntry, Path=IsExpanded, Converter={StaticResource backgroundConvertor}}" />
</Style>
</Expander.Style>
</Expander>
and my code for the value convertor :
public class BackgroundConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return (bool)value ? "White" : "Transparent";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
string color = value as string;
if (color == "White")
return true;
return false;
}
}
I think though that I prefer the XAML only solution, although the IValueConverter option does make for slightly better reading of the XAML ...
(The DependancyProperty is still created exactly the same way)