WPF绑定以更改椭圆的填充颜色

14

如何通过程序根据变量定义在XAML中的椭圆改变其颜色?

我所读到的所有关于绑定的内容都基于集合和列表,难道就不能简单地(文字意义上)根据字符串变量的值设置吗?例如:string color = "red",color = "#FF0000"

4个回答

24

值得指出的是,其他帖子提到的转换器已经存在,这就是为什么你可以在xaml中使用<Ellipse Fill="red">。 转换器是System.Windows.Media.BrushConverter

        BrushConverter bc = new BrushConverter();
        Brush brush = (Brush) bc.ConvertFrom("Red");
更高效的方法是使用完整语法:
myEllipse.Fill = new SolidColorBrush(Colors.Red);

编辑,回应-1和评论:

上面的代码在代码中完美地工作,这就是原始问题所询问的。您也不需要使用IValueConverter - 这些通常用于绑定场景。在这里,TypeConverter是正确的解决方案(因为您正在将字符串单向转换为画笔)。有关详细信息,请参见此文章

进一步编辑(重新阅读了Aviad的评论后):您不需要在Xaml中显式使用TypeConverter - 它会自动为您使用。如果我在Xaml中编写如下内容:

<Ellipse Fill="red">

然后运行时会自动使用BrushConverter将字符串文字转换为笔刷。 Xaml 本质上被转换为等效的全拼写:

<Ellipse>
  <Ellipse.Fill>
     <SolidColorBrush Color="#FFFF0000" />
  </Ellipse.Fill>             
</Ellipse>

所以你说得对 - 你不能在Xaml中使用它 - 但你并不需要。

即使你有一个字符串值想要作为填充进行绑定,你也不需要手动指定转换器。这个来自Kaxaml的测试:

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:s="clr-namespace:System;assembly=mscorlib">
  <Page.Resources>
    <s:String x:Key="col">Red</s:String>
  </Page.Resources>

  <StackPanel>  
    <Ellipse Width="20" Height="20" Fill="{Binding Source={StaticResource col}}" />
  </StackPanel>
</Page>

奇怪的是,你不能只使用StaticResource col就能使它起作用 - 但通过绑定,它会自动使用ValueConverter将字符串转换为画刷。


这并没有回答问题,BrushConverter没有实现IValueConverter,所以你无法在XAML中使用它。 - Aviad P.
1
编辑了我的答案,而不是在这里回复,因为我认为值得详细解释一下为什么我是正确的... - Dan Puzey

7
您需要做的是实现一个自定义转换器,将颜色转换为画刷对象。类似这样的东西...
public class ColorToBrushConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        System.Drawing.Color col = (System.Drawing.Color)value;
        Color c = Color.FromArgb(col.A, col.R, col.G, col.B);
        return new System.Windows.Media.SolidColorBrush(c);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        SolidColorBrush c = (SolidColorBrush)value;
        System.Drawing.Color col = System.Drawing.Color.FromArgb(c.Color.A, c.Color.R, c.Color.G, c.Color.B);
        return col;
    }
}

然后在绑定中指定转换器

Fill="{Binding Colors.Red, Converter={StaticResource ColorToBrushConverter }"

如果您将其转换为Brush对象而不是Color对象,则此方法将是正确的。只需使用BrushConverter而不是ColorConverter即可解决问题。虽然我认为您需要该转换器的实例,因为ConvertFromString方法不是静态的,对吗? - Aviad P.
如果您使用颜色进行绑定,那么您可以自由地使用Colors类,该类在颜色名称上具有智能感知功能。 - Leigh S

2

使用

System.Windows.Media

如果您在XAML中椭圆的名称为my_ellipse,请编写类似以下内容的代码:
my_ellipse.Fill = System.Windows.Media.Brushes.Red;

或者这样:
my_ellipse.Fill = (SolidColorBrush)new BrushConverter().ConvertFromString("#F4F4F5")

0

这是一个快速的解决方法(虽然它不是绑定的,而且效率较低),就是检查对象/元素的状态,并根据状态更新新的/其他对象,我将在下面提供一个基本示例。

您可以通过从用户控件获取MainWindow对象的状态并根据需要更改MainWindow对象状态来在MVVM中执行此操作。

注意:这对于需要超出基本用例的2个主题应用程序和其他情况(例如:深色模式等)将无法正常工作。

在我的示例中,我使用数据在屏幕上绘制“文本”(FrontFog_Text),这就是为什么在我的情况下文本使用.Fill属性的原因。

我没有在我的应用程序中使用这个,但在测试一些东西时遇到了这个问题,所以我想在这个线程中分享一下,同时寻找我的答案!

 private void FrontFog_ToggleButton_Unchecked(object sender, RoutedEventArgs e)
    {
        if (((MainWindow)App.Current.MainWindow).Theme_Control.IsChecked == true)
        {
            FrontFog_Text.Fill = new SolidColorBrush(System.Windows.Media.Colors.White);
        }
        else if (((MainWindow)App.Current.MainWindow).Theme_Control.IsChecked == false)
        {
            FrontFog_Text.Fill = new SolidColorBrush(System.Windows.Media.Colors.Black);
        }
    }

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