views:

414

answers:

4

I want to change the background color of our apps main window when a property changes. We have a business date that can be changed and I want to change the window background when it has changed from expected. I've set up a property to tell this. But can I set a style datatrigger on a window that changes itself? Or would I need to do this in the app.xaml?

A: 

Maybe it's better to just bind the background with the property. You need to set the datasource of the window to the object and may need a valueconverter.

Codism
Hmm I'll try this, the DP sounds good too.
nportelli
+2  A: 

If you're exposing a custom property on the Window just make sure it's defined as a DependencyProperty and then you should be able to use a regular trigger in the style to react to the property. Like so:

<Window.Style>
    <Style TargetType="{x:Type MyWindow}">
        <Style.Triggers>
            <Trigger Property="MyProperty" Value="True">
                <Setter Property="Background" Value="Red" />
            </Trigger>
        </Style.Triggers>
    </Style>
</Window.Style>
Drew Marsh
A: 

Here's a solution with a converter approach:

XAML:

<Window x:Class="StackOverflowTests.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" x:Name="window1" Width="300"
    xmlns:local="clr-namespace:StackOverflowTests">
    <Window.Resources>
     <local:DateToColorConverter x:Key="DateToColorConverter" />
    </Window.Resources>
    <Window.Background>
     <SolidColorBrush Color="{Binding ElementName=textBoxName, Path=Text, Converter={StaticResource DateToColorConverter}}" />
    </Window.Background>
    <Grid>
     <Grid.RowDefinitions>
      <RowDefinition Height="Auto" />
     </Grid.RowDefinitions>
     <TextBox x:Name="textBoxName" Margin="5"></TextBox>
    </Grid>
</Window>

C#:

using System;
using System.Windows;
using System.Windows.Data;
using System.Windows.Media;

namespace StackOverflowTests
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
     public Window1()
     {
      InitializeComponent();
     }
    }

    public class DateToColorConverter : IValueConverter
    {
     #region IValueConverter Members

     public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
     {
      DateTime date;

      if (DateTime.TryParse(value.ToString(), out date))
      {
       if (date == DateTime.Today)
        return Colors.Green;
       else
        return Colors.Red;
      }
      else
      {
       return Colors.Gold;
      }
     }

     public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
     {
      throw new System.NotImplementedException();
     }

     #endregion
    }

}
Carlo
A: 

I ended up kind of doing what Drew suggested. Except I didn't use a Dependency Property.

<Window.Resources>
   <SolidColorBrush x:Key="windowBGBrush" Color="Green"/>
        <SolidColorBrush x:Key="windowBGBrushBusinessDateChanged" Color="Red"/>
</Window.Resources>
<Window.Style >
        <Style TargetType="{x:Type Window}">
            <Setter Property="Background" Value="{DynamicResource windowBGBrush}"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsBusinessDateChanged}" Value="true">
                    <Setter Property="Background" Value="{DynamicResource windowBGBrushBusinessDateChanged}"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Window.Style>

IsBusinessDateChanged is a property on my Viewmodel that gets set by a service. I'm not sure why this was so hard.

nportelli