Лучший способ вызвать изменение цвета на основе отображаемого текста - PullRequest
1 голос
/ 10 июля 2020
  1. У меня есть класс struct, который записывает значение и проверку, которая просто говорит, хорошо это или плохо.
    public enum StressCheck
    {
        Good,
        Bad
    }   

    public struct Stress
    {
        public Stress(double stressValue, StressCheck check)
        {
            StressValue = stressValue;
            Check = check;
        }
        public double StressValue { get; set; }               
        public StressCheck Check { get; set; }
    }
Я хочу создать TextBlock, фон которого становится красным при значении «Плохо». Это то, что я делаю в данный момент в XAML моего пользовательского элемента управления.
<UserControl x:Class="ScienceProgram.UserControls.DataCellCheck"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             x:Name="parent">
    <UserControl.Resources>
        <Style x:Key="CheckStress" TargetType="TextBlock">
            <Style.Triggers>
                <DataTrigger Binding="{Binding ElementName=TB,Path=Text}" Value="Good">
                    <Setter Property="Background" Value="Green" />
                </DataTrigger>
                <DataTrigger Binding="{Binding ElementName=TB,Path=Text}" Value="Bad">
                    <Setter Property="Background" Value="Red" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </UserControl.Resources>
    <Grid Margin="1" DataContext="{Binding ElementName=parent}" Width="100">
        <TextBlock Style="{StaticResource CheckStress}" Text="{Binding Path=Value}" />
        <TextBlock x:Name="TB"  Text="{Binding Path=Check}" Visibility="Collapsed"/>
    </Grid>

и стандартный код программной части для объектов зависимостей «Значение» и «Проверка»

    public partial class DataCellCheck : UserControl
    {
        public DataCellCheck()
        {
            InitializeComponent();
        }

        public static readonly DependencyProperty ValueProp = 
            DependencyProperty.Register("Value", typeof(string), 
                typeof(DataCellCheck), new PropertyMetadata(""));

        public string Value
        {
            get { return GetValue(ValueProp) as String; }
            set { SetValue(ValueProp, value); }
        }

        public static readonly DependencyProperty StatusProp = 
            DependencyProperty.Register("Check", typeof(string), 
                typeof(DataCellCheck), new PropertyMetadata(""));

        public string Check
        {
            get { return GetValue(StatusProp) as String; }
            set { SetValue(StatusProp, value); }
        }
    }
Итак, что здесь происходит, так это то, что я меняю Background цвет отображаемого TextBlock, привязывая его к свернутому Texblock, в котором я привязываю значение StressCheck из viewModel следующим образом .
    public class TestViewModel : BindableBase
    {
        public Stress MyFirstStress { get; set; }

        public TestViewModel()
        {
            MyFirstStress = new Stress(1245, StressCheck.Fail);
        }

        public double DisplayStressValue => MyFirstStress.StressValue;
        public string DisplayStressCheck => MyFirstStress.Check.ToString();
    }
        

и в XAML

<UserControl x:Class="ScienceProgram.Views.TestView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:ScienceProgram.Views"
             xmlns:uc="clr-namespace:ScienceProgram.UserControls"
             mc:Ignorable="d" 
             d:DesignHeight="1200" d:DesignWidth="811">
    <Grid Margin="5">
        <Grid.RowDefinitions>
            <RowDefinition Height="65"/>
        </Grid.RowDefinitions>
        <StackPanel>
            <uc:DataCellCheck Value="{Binding Path=DisplayStressValue }" Check="{Binding Path=DisplayStressCheck}"/>
        </StackPanel>
    </Grid>
</UserControl>
Теперь у меня вопрос, есть ли лучший способ вызвать изменение цвета в отображаемом текстовом блоке без необходимости связывать StressCheck и скрывать его в другом текстовом блоке?

Большое спасибо.

1 Ответ

0 голосов
/ 10 июля 2020

есть ли лучший способ вызвать изменение цвета в отображаемом текстовом блоке без необходимости связывать StressCheck и скрывать его в другом текстовом блоке?

Я надеюсь на это. То, как вы это делаете сейчас, очень неуклюже.

Без минимального, полного, проверяемого кода невозможно подтвердить, что это будет работать в вашем конкретном сценарии, но это должен . Вы можете просто привязать свойство Check в триггере вместо другого. TextBlock:

<Style x:Key="CheckStress" TargetType="TextBlock">
    <Style.Triggers>
        <DataTrigger Binding="{Binding Check}" Value="Good">
            <Setter Property="Background" Value="Green" />
        </DataTrigger>
        <DataTrigger Binding="{Binding Check}" Value="Bad">
            <Setter Property="Background" Value="Red" />
        </DataTrigger>
    </Style.Triggers>
</Style>

Что бы это ни стоило, я предпочитаю включать сеттер для одного значения и использовать триггеры для другого. (или другие, если их несколько):

<Style x:Key="CheckStress" TargetType="TextBlock">
    <Setter Property="Background" Value="Green"/>
    <Style.Triggers>
        <DataTrigger Binding="{Binding Check}" Value="Bad">
            <Setter Property="Background" Value="Red" />
        </DataTrigger>
    </Style.Triggers>
</Style>

В любом случае WPF обрабатывает enum типы неявно, анализируя предоставленное текстовое значение как фактическое значение перечисления и используя его для сравнения триггера. Вам не нужен дополнительный TextBlock или другой механизм (например, конвертер) для перевода между текстом, который вы помещаете в XAML, и фактическими значениями enum.

Если приведенное выше не касается ваша проблема, пожалуйста, улучшите вопрос, предоставив хороший MCVE, чтобы можно было понять полный контекст вашего сценария.

...