【问题标题】:How to bind WPF element colors without the view model knowing about WPF?如何在视图模型不知道 WPF 的情况下绑定 WPF 元素颜色?
【发布时间】:2015-06-02 15:57:05
【问题描述】:

我想知道如何将元素的颜色属性绑定到 ViewModel,而不会将视图实现(例如 WPF)泄漏到 ViewModel 中,从而创建依赖项。例如,我有一个TextBlock,我已经绑定了它的Foreground 属性,如下所示:

<TextBlock Name="MyTextBlock" Foreground="{Binding Path=PropName}" />

thisthisthis 等许多来源在 ViewModel 中使用 System.Windows.Media.Brush,如下所示:

public System.Windows.Media.Brush PropName
{
    get
    {
        //assume presentation logic to determine correct color.
        return System.Windows.Media.Brushes.Red;
    }
}

我不希望我的 ViewModel 绑定到 WPF(即通过 System.Windows.Media.Brush)或任何其他演示框架。有什么方法可以让我使用通用或通用颜色类型甚至 RGB 值,并通过绑定在 XAML 中正确解释它吗?

【问题讨论】:

  • 为了确保我对您的理解正确,这是否只是一种过于复杂的方式来询问如何将画笔/颜色作为视图的资源而不需要代码和 xaml?
  • 不,我真的是 WPF 新手。你能详细说明一下吗?
  • 1) 你没有。 2)它们很便宜,这很好。这不是教条,而是模式。旁注——为什么你的虚拟机知道或关心颜色?老实说不应该。但是,根据系统当前所处的状态,系统的某些部分可能会用某种颜色表示。使用转换器来解释 VM 或模型的状态,并将该状态转换为颜色。例如,如果您的 Person 模型无效,请将其转换为 Red。如果它有效、已修改但未保存,则将其转换为黄色。
  • 您可以简单地从您的视图模型中返回一个字符串。隐式 TypeConverter 会将其转换为 Brush。您需要返回已知颜色“红色”或返回有效的#FFFFF 颜色。
  • 能否请您映射某人的答案或向我们提供更多信息?

标签: c# wpf xaml mvvm


【解决方案1】:

我会创建一个颜色枚举。 例如:

enum Colors {Red, Green, Yellow, Pink, Blue};

然后,如果您正在使用 WPF 进行开发,您可以只创建一个 ValueConverter,您可以在其中确定枚举是否为红色,您可以按照您想要的方式对其进行转换并将其返回以进行控制。这样您就可以将 UI 逻辑与 viewmodel 分开。 Viewmodel 告诉 UI 处理其余的颜色。

如果您想要自定义颜色,上面的答案是处理它的好方法。

【讨论】:

    【解决方案2】:

    只需将带有十六进制的字符串绑定到元素的背景属性中(当然你需要一个通知实现)

    XAML

    <Border Background="{Binding anycolor}" />
    

    代码

    public string anycolor { get; set; }
    

    【讨论】:

      【解决方案3】:

      如果您不想引用这些命名空间,也许您可​​以返回一个字符串并使用包含类似以下内容的转换器:

      var color = (Color)ColorConverter.ConvertFromString("Red");
      

      或 RGB

      var color = (SolidColorBrush)(new BrushConverter().ConvertFrom("#ffaacc"));
      

      不过我可能不太明白这个问题。

      【讨论】:

      • 我假设您的代码示例将进入代码隐藏。您将如何在 XAML 中实现这一点?
      • 没有代码就无法完成 AFAIK。但不需要后面的代码。只需要一个单独的独立且可重用的转换器类。哪个很好,而且非常好 mvvm。
      【解决方案4】:

      这是我最喜欢的新作品(对 VB 感到抱歉):

      Imports System.Windows.Data
      
      Public Class MappingConverter
          Implements IValueConverter
      
          Public Property Mappings As New List(Of Mapping)
      
      
          Public Function Convert(value As Object, targetType As Type, parameter As Object, culture As Globalization.CultureInfo) As Object Implements IValueConverter.Convert
              Return Mappings.Where(Function(m) m.Source = value.ToString).FirstOrDefault
          End Function
      
          Public Function ConvertBack(value As Object, targetType As Type, parameter As Object, culture As Globalization.CultureInfo) As Object Implements IValueConverter.ConvertBack
              Throw New NotImplementedException
          End Function
      End Class
      
      Public Class Mapping
          Public Property Source As String
          Public Property Target As Object
      End Class
      

      并像这样使用:

       <UserControl.Resources>
              <wpflib:MappingConverter x:Key="SelectionHighlightConverter">
                  <wpflib:MappingConverter.Mappings>
                      <wpflib:Mapping Source="True" Target="{x:Static Brushes.CornflowerBlue}" />
                      <wpflib:Mapping Source="False" Target="{x:Static Brushes.White}" />
                  </wpflib:MappingConverter.Mappings>
              </wpflib:MappingConverter>
          </UserControl.Resources>
      

      当您在布尔属性的绑定上使用该转换器时,True 或 False 将转换为指定的颜色。它实际上可以将任何字符串可转换值(int、string、boolean 等)映射到您想要的任何对象。

      【讨论】:

        猜你喜欢
        • 2011-10-13
        • 1970-01-01
        • 2023-03-06
        • 1970-01-01
        • 2014-04-02
        • 2011-10-07
        • 2017-02-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多