【问题标题】:Change TextBox foreground color based on specific starting and closing tags根据特定的开始和结束标记更改 TextBox 前景色
【发布时间】:2018-07-30 11:00:02
【问题描述】:

我正在开发 WPF 应用程序,我在其中使用TextBox 编写一些文本。每当用户用<qs>(开始时)和<qe>在结束时将特定文本括在文本框中时,我想将文本框的前景色更改为红色。同样,如果用户在开始时用<as> 和在结束时用<ae> 括起一些文本,则文本颜色应该变为绿色。我在网上搜索了很多,但没有找到任何信息。非常感谢任何帮助。

预期输出如图所示

另外,我在我的应用程序中使用 MVVM。

【问题讨论】:

  • 你试过为此写一个 ValueConverter 吗?另外:您要使用的确切规则是什么?
  • 我已经更新了我的问题并放置了一张图片,显示了预期的结果。
  • 另外,我在我的应用程序中使用 MVVM。

标签: c# wpf xaml textbox wpf-controls


【解决方案1】:

正如@Erno de Weerd 所说,您可以为此使用自定义 ValueConvertert。我能想到的另一种方法是继承 TextBox 并覆盖 TextProperty 元数据以对该属性的更改做出反应。以下示例包含两种方法:

XAML:

<Window x:Class="WpfApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:wpfApp="clr-namespace:WpfApp"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.DataContext>
        <wpfApp:MainWindowViewModel/>
    </Window.DataContext>
    <Window.Resources>
        <wpfApp:TextToColorConverter x:Key="TextToColorConverter"/>
    </Window.Resources>
    <StackPanel >
        <TextBox Text="{Binding SomeString, UpdateSourceTrigger=PropertyChanged}"
                 Foreground="{Binding SomeString, Mode=OneWay, Converter={StaticResource TextToColorConverter}}"
                 Margin="0,0,0,20"/>
        <wpfApp:MyCustomTextBox Text="{Binding SomeString, UpdateSourceTrigger=PropertyChanged}"/>
    </StackPanel>
</Window>

MainWindowViewModel 只包含绑定的属性并实现了 INotifyPropertyChanged:

public class MainWindowViewModel : INotifyPropertyChanged
{
    private string _someString;

    public string SomeString
    {
        get => _someString;
        set
        {
            if (value == _someString) return;
            _someString = value;
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

第一种方法,IValueConverter:

public class TextToColorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var str = (string)value;
        if (str == null) return new SolidColorBrush(Colors.Black);
        return str.StartsWith("<qs>") && str.EndsWith("<qe>") ? new SolidColorBrush(Colors.Red) :
            str.StartsWith("<as>") && str.EndsWith("<ae>") ? new SolidColorBrush(Colors.Green) :
            new SolidColorBrush(Colors.Black);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

第二个,我们继承自TextBox:

public class MyCustomTextBox : TextBox
{
    static MyCustomTextBox()
    {
        TextProperty.OverrideMetadata(typeof(MyCustomTextBox), new FrameworkPropertyMetadata(OnTextChanged));
    }

    private static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var control = (MyCustomTextBox)d;
        var str = (string)e.NewValue;
        SolidColorBrush foreGround;
        if (str == null)
        {
            foreGround = new SolidColorBrush(Colors.Black);
        }
        else
        {
            foreGround = str.StartsWith("<qs>") && str.EndsWith("<qe>") ? new SolidColorBrush(Colors.Red) :
                str.StartsWith("<as>") && str.EndsWith("<ae>") ? new SolidColorBrush(Colors.Green) :
                new SolidColorBrush(Colors.Black);
        }

        control.Foreground = foreGround;
    }
}

我个人更喜欢第二种方法,创建自己的自定义控件允许我在任意多个视图中使用该控件,而无需在我的 XAML 中始终包含转换器的实例,此外,如果您需要一些更多的自定义行为,然后您只需将该行为添加到您的自定义控件中,而不是编写许多其他转换器。

【讨论】:

  • 谢谢,但它部分工作。仅当完整的文本包含在 ( , ) 或 ( , ) 标记中时才有效。如果单个单词或多个单词被大句子中的标签包围,它不会改变文本颜色。
  • 那么你需要一个 RichTextBox 就像@Greg 评论的那样
  • 你能举个例子吗?
  • 我卡住了,请大家帮忙。
猜你喜欢
  • 1970-01-01
  • 2021-11-06
  • 1970-01-01
  • 2016-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-03
  • 1970-01-01
相关资源
最近更新 更多