How can I bind a background color in WPF/XAML?

Viewed 138040

What do I have to change to the following code so that the background is red, neither of the 2 ways I tried worked:

alt text
(source: deviantsart.com)

XAML:

<Window x:Class="TestBackground88238.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <StackPanel>

        <TextBlock Text="{Binding Message}" Background="{Binding Background}"/>

        <TextBlock Text="{Binding Message}">
            <TextBlock.Background>
                <SolidColorBrush Color="{Binding Background}"/>
            </TextBlock.Background>
        </TextBlock>

    </StackPanel>
</Window>

Code Behind:

using System.Windows;
using System.ComponentModel;

namespace TestBackground88238
{
    public partial class Window1 : Window, INotifyPropertyChanged
    {

        #region ViewModelProperty: Background
        private string _background;
        public string Background
        {
            get
            {
                return _background;
            }

            set
            {
                _background = value;
                OnPropertyChanged("Background");
            }
        }
        #endregion

        #region ViewModelProperty: Message
        private string _message;
        public string Message
        {
            get
            {
                return _message;
            }

            set
            {
                _message = value;
                OnPropertyChanged("Message");
            }
        }
        #endregion



        public Window1()
        {
            InitializeComponent();
            DataContext = this;

            Background = "Red";
            Message = "This is the title, the background should be " + Background + ".";

        }

        #region INotifiedProperty Block
        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;

            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion

    }
}

Update 1:

I tried Aviad's answer which didn't seem to work. I can do this manually with x:Name as shown here but I want to be able to bind the color to a INotifyPropertyChanged property, how can I do this?

alt text
(source: deviantsart.com)

XAML:

<Window x:Class="TestBackground88238.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <StackPanel>

        <TextBlock Text="{Binding Message}" Background="{Binding Background}"/>

        <TextBlock x:Name="Message2" Text="This one is manually orange."/>

    </StackPanel>
</Window>

Code Behind:

using System.Windows;
using System.ComponentModel;
using System.Windows.Media;

namespace TestBackground88238
{
    public partial class Window1 : Window, INotifyPropertyChanged
    {

        #region ViewModelProperty: Background
        private Brush _background;
        public Brush Background
        {
            get
            {
                return _background;
            }

            set
            {
                _background = value;
                OnPropertyChanged("Background");
            }
        }
        #endregion

        #region ViewModelProperty: Message
        private string _message;
        public string Message
        {
            get
            {
                return _message;
            }

            set
            {
                _message = value;
                OnPropertyChanged("Message");
            }
        }
        #endregion

        public Window1()
        {
            InitializeComponent();
            DataContext = this;

            Background = new SolidColorBrush(Colors.Red);
            Message = "This is the title, the background should be " + Background + ".";

            Message2.Background = new SolidColorBrush(Colors.Orange);

        }

        #region INotifiedProperty Block
        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;

            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion

    }
}
8 Answers

The Background property expects a Brush object, not a string. Change the type of the property to Brush and initialize it thus:

Background = new SolidColorBrush(Colors.Red);

I figured this out, it was just a naming conflict issue: if you use TheBackground instead of Background it works as posted in the first example. The property Background was interfering with the Window property background.

I recommend reading the following blog post about debugging data binding: http://beacosta.com/blog/?p=52

And for this concrete issue: If you look at the compiler warnings, you will notice that you property has been hiding the Window.Background property (or Control or whatever class the property defines).

You assigned a string "Red". Your Background property should be of type Color:

using System.Windows;
using System.ComponentModel;

namespace TestBackground88238
{
    public partial class Window1 : Window, INotifyPropertyChanged
    {

        #region ViewModelProperty: Background
        private Color _background;
        public Color Background
        {
            get
            {
                return _background;
            }

            set
            {
                _background = value;
                OnPropertyChanged("Background");
            }
        }
        #endregion

        //...//
}

Then you can use the binding to the SolidColorBrush like this:

public Window1()
{
    InitializeComponent();
    DataContext = this;

    Background = Colors.Red;
    Message = "This is the title, the background should be " + Background.toString() + ".";

}

not 100% sure about the .toString() method on Color-Object. It might tell you it is a Color-Class, but you will figur this out ;)

You can still use "Background" as the property name, as long as you give your window a name and use this name on the "Source" of the Binding.

Related