如何在WPF/XAML中绑定背景颜色?

39
我需要更改以下代码才能使背景变为红色,但是我尝试的两种方法都没有成功:

alt text
(来源: 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>

后台代码:

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

    }
}

更新 1:

我尝试了 Aviad 的答案,但好像不起作用。我可以按此处所示使用 x:Name 手动完成此操作,但我想将颜色绑定到 INotifyPropertyChanged 属性,该如何实现?

alt text
(来源: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>

代码后台:

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

    }
}

相关链接:http://stackoverflow.com/questions/33309271/wpf-bind-background-color-of-datagridtextcolumn-to-color-by-row - BlueRaja - Danny Pflughoeft
8个回答

68

重要:

请确保使用的是 System.Windows.Media.Brush 而非 System.Drawing.Brush,它们不兼容,否则会出现绑定错误。

你需要使用的颜色枚举也是不同的:

System.Windows.Media.Colors.Aquamarine (类名为 Colors) <--- 使用这个 System.Drawing.Color.Aquamarine (类名为 Color)

如果有疑问,请使用 Snoop 并检查元素的背景属性以查找绑定错误 - 或者只需在调试日志中查找即可。


请注意,System.Windows.Media.Colors 命名空间返回一个没有 sSystem.Windows.Media.Color - John Doe
2
请确保您使用的是 System.Windows.Media.Brush 而不是 System.Drawing.Brush。 - david2020

29

Background属性需要一个Brush对象,而不是一个字符串。将该属性的类型更改为Brush并进行如下初始化:

Background = new SolidColorBrush(Colors.Red);

那对我似乎没有起作用,我已经发布了代码(更新1) - Edward Tanguay
7
请使用 System.Windows.Media 中的 SolidColorBrush,而不要使用 System.Drawing 中的 SolidBrush。 - Simon_Weaver
3
我知道我来晚了,但是正确的写法是Colors.Red而不是Color.Red。在发现这一点之前,我对你的回答感到有些困惑。 - DanteTheEgregore
1
在这种情况下,最简单的变体是使用预定义的纯色画刷。Background = Brushes.Red //System.Windows.Media - Marťas
一个令人沮丧且容易被忽视的概念:<TextBlock Background="{Binding TheBackground}"/>需要使用System.Windows.Media.SolidColorBrush命名空间。如果您需要透明度,因此使用<TextBlock><TextBlock.Background><SolidColorBrush Color="{Binding TheBackground}" Opacity="{Binding TheOpacity}"/></TextBlock.Background></TextBlock>,则需要System.Windows.Media.Color命名空间。本答案展示了如何在两者之间进行转换。 - John Doe

8

以下是复制粘贴的代码:

class NameToBackgroundConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if(value.ToString() == "System")
            {
                return new SolidColorBrush(System.Windows.Media.Colors.Aqua);
            }else
            {
                return new SolidColorBrush(System.Windows.Media.Colors.Blue);
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return null;
        }
    }

改用SolidColorBrush而不是使用原始颜色,这对我解决了问题。谢谢。 - frostymarvelous

5
我找到了答案,这只是一个命名冲突问题:如果你使用TheBackground而不是Background,它将像第一个例子中发布的那样工作。属性“Background”与窗口属性背景干扰了。

4
我建议阅读以下关于调试数据绑定的博客文章:http://beacosta.com/blog/?p=52 对于这个具体问题:如果你查看编译器警告,你会注意到你的属性已经隐藏了Window.Background属性(或Control或任何定义该属性的类)。

是的,正是编译器警告让我发现了它,感谢提供链接,那里有很好的信息。 - Edward Tanguay
很遗憾,该链接已经失效了,你知道类似的帖子吗?谢谢。 - Ouissal
@Ouissal https://web.archive.org/web/20151215181325/http://www.zagstudio.com/blog/486 - Artfaith

2

XAML代码:

<Grid x:Name="Message2">
   <TextBlock Text="This one is manually orange."/>
</Grid>
protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        CreateNewColorBrush();
    }

    private void CreateNewColorBrush()
    {

        SolidColorBrush my_brush = new SolidColorBrush(Color.FromArgb(255, 255, 215, 0));
        Message2.Background = my_brush;

    }

这个可以在Windows 8商店应用程序中运行。试一下看看,祝你好运!

在这种情况下,最简单的变体是使用预定义的纯色画刷Background = Brushes.Red //System.Windows.Media - Marťas

2
你赋值了一个字符串 "Red"。你的 Background 属性应该是 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

        //...//
}

然后你可以像这样使用绑定到SolidColorBrush:

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

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

}

对于 Color-Object 上的 .toString() 方法我不是100%确定。它可能会告诉你它是一个 Color-Class,但你会弄清楚的 ;)


0

只要给窗口命名并在绑定的“源”上使用此名称,您仍然可以将“Background”用作属性名称。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接