简体   繁体   中英

Color TextBlock depending on enum value

I'm working on WPF with a MvvM model.

I have a view containing Texblocks. It display information about ID (from a document and from a database) :

<GroupBox Grid.Row="1" Grid.Column="0" Header="ID Informations">
    <StackPanel Orientation="Vertical">
        <TextBlock Text="DataBase surname: "/>
        <TextBlock Text="{Binding Model.Db_SURNAME}" FontWeight="Bold"/>
        <TextBlock Text="Document surname: "/>
        <TextBlock Text="{Binding Model.Dc_SURNAME}" FontWeight="Bold"/>
        <TextBlock Text="DataBase forename: "/>
        <TextBlock Text="{Binding Model.Db_FORENAME}" FontWeight="Bold"/>
        <TextBlock Text="Document forename: "/>
        <TextBlock Text="{Binding Model.Dc_FORENAME}" FontWeight="Bold"/>
    </StackPanel>
</GroupBox>

I have an enum containing an error code :

[Flags]
public enum errorID
{
    OK = 1<<0,
    SURNAME_DIFF = 1 << 1,
    FORENAME_DIFF = 1 << 2
}

And my model is wrote like this :

private String _db_SURNAME;
public String Db_SURNAME
{
    get { return _db_SURNAME; }
    set { SetProperty(ref _db_SURNAME, value); }
}
[...]

private errorID _errorID;
public errorID ErrorID
{
    get { return _errorID; }
    set { SetProperty(ref _errorID, value); }
}

I want that both of my textblocks displaying Model.Db_SURNAME and Model.Dc_SURNAME are colored in red when ErrorID.HasFlag(errorID.SURNAME_DIFF ) . And also for Forname .

How can I do ?

Use a converter that converts your enum to a color like following:

public class ErrorIdColorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if(!(value is errorID))
             throw new ArgumentException("value not of type errorID");
        if(!(parameteris errorID))
             throw new ArgumentException("parameter not of type errorID");

        errorID error = (errorID)value;
        errorID flag = (errorID)parameter;

        if (error.HasFlag(flag))
        {
            return Brushes.Red;
        }
        ...

        return Brushes.Black;
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
   ....
}

}

Then you can bind the Foreground Color to your enum using the converter:

<TextBlock Text="{Binding Model.Db_SURNAME}" FontWeight="Bold" Foreground={Binding Model.errorId, Converter={StaticRessource errorIDColorConverter}, ConverterParameter={StaticRessource errorID.SURNAME_DIFF}}/>

The simplest solution: binding Foreground color by the value of ErrorID

XAML

<TextBlock Text="{Binding Model.Db_SURNAME}" FontWeight="Bold" Foreground={Binding SurNameColor}/>
<TextBlock Text="Document surname: "/>
<TextBlock Text="{Binding Model.Dc_SURNAME}" FontWeight="Bold" Foreground={Binding SurNameColor}/>

Model

private Brush _surNameColor = Brush.Black;
public Brush SurNameColor
{
    get { return _surNameColor; }
    set { SetProperty(ref _surNameColor, value); }
}
private errorID _errorID;
public errorID ErrorID
{
    get { return _errorID; }
    set { 
        if(ErrorID.HasFlag(errorID.SURNAME_DIFF))
            SurNameColor = Brushes.Red;
        SetProperty(ref _errorID, value); }
}

I'd suggest you to go for DataTrigger on your ErrorID property of your Model .

Try something like this:

  1. Add a namespace of your enum to your View (Visual Studio will help you get it correct)

     <UserControl [some other namespaces] xmlns:someName="clr-namespace:YourEnumNamespace;assembly=YourAssembly"> 
  2. Add styling for your TextBox (you can set it for all of them at once by doing this, or add x:Key to reference style explicitly for each TextBox you want to have it):

     <UserControl.Resources> <Style TargetType="{x:Type TextBox}"> <Style.Triggers> <DataTrigger Binding="{Binding [your property to bind]}" Value="{x:Static someName:ErrorID.[value of enum]}"> <Setter Property="Foreground" Value="Green" /> </DataTrigger> </Style.Triggers> <!-- repeat data triggers for each enum value you want to check !--> </Style> </UserControl.Resources> 

Or go for converter, but I personally prefer that approach.

If an approach with having that style in UserControl.Resources won't work for you because you are not able to bind like this, just put it in your TextBox.Style tag under your TextBox .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM