如何在段落上应用不同的样式?

How to apply different styles on a paragraph?

我可以对按钮的内容应用不同的样式吗?例如我有一个搜索框,如果用户在搜索框中输入"is"并点击搜索,我可以将按钮内容中下面的两个"is"设置为斜体吗?同时,我希望剩下的部分保持原样,不要斜体。

<Button
    Content="This is an example of button content. This is a very long content.">
   <Button.Style>
    ???
   </Button.Style>
</Button>

应用样式后我想要按钮内容: 这个按钮内容的一个例子。这个一个很长的内容。

这可能吗?

Content 可以是任何东西,例如TextBlock 每个单词或文本段包含一个 Run,然后您可以单独设置样式。我不认为纯粹的 XAML 方法在这里很有用。如果您可能想在某处的资源中定义突出显示样式,请在用户输入时有条件地在代码中应用该样式。

如果您的内容是静态的,您可以像这样简单地定义按钮:

<Button>
    <TextBlock>
         <Run Text="This"></Run>
         <Run Text="is" FontStyle="Italic"></Run>
         <Run Text="an example of button content. This"></Run>
         <Run Text="is" FontStyle="Italic"></Run>
         <Run Text="a very long content."></Run>
    </TextBlock>
</Button>

或:

<Button>
    <RichTextBox IsReadOnly="True" BorderThickness="0"> <!-- Other styles as needed -->
        <FlowDocument>
            <Paragraph>
                This
                <Italic>is</Italic> an example of button content. This
                <Italic>is</Italic> a very long content.
            </Paragraph>
        </FlowDocument>
    </RichTextBox>
</Button>

但是,对于样式是动态的情况,我会使用以下服务:

// Note: Not my code, but I can't find the original source
public static class RichTextBoxService
{
    public static string GetContent(DependencyObject obj)
    {
        return (string)obj.GetValue(ContentProperty);
    }

    public static void SetContent(DependencyObject obj, string value)
    {
        obj.SetValue(ContentProperty, value);
    }

    public static readonly DependencyProperty ContentProperty =
        DependencyProperty.RegisterAttached("Content",
        typeof(string), 
        typeof(RichTextBoxHelper),
        new FrameworkPropertyMetadata 
        {
            BindsTwoWayByDefault = true,
            PropertyChangedCallback = OnDocumentChanged,
        });

    private static void OnDocumentChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        var richTextBox = (RichTextBox)obj;

        // Parse the XAML content to a document (or use XamlReader.Parse())
        var xaml = GetContent(richTextBox);
        var doc = new FlowDocument();
        var range = new TextRange(doc.ContentStart, doc.ContentEnd);

        range.Load(new MemoryStream(Encoding.UTF8.GetBytes(xaml)), DataFormats.Xaml);

        richTextBox.Document = doc;

        // When the document changes update the source
        range.Changed += (s, args) =>
        {
            if (richTextBox.Document == doc)
            {
                MemoryStream buffer = new MemoryStream();
                range.Save(buffer, DataFormats.Xaml);

                SetContent(richTextBox, Encoding.UTF8.GetString(buffer.ToArray()));
            }
        };
    }
}

然后,您可以像这样将它与您的按钮一起使用:

查看:

<Window xmlns:services="clr-namespace:MyProject.Services;assembly=MyProject">

    <Button>
        <RichTextBox IsReadOnly="True" BorderThickness="0" services:RichTextBoxService.Content="{Binding ButtonContent}" />
    </Button>

ViewModel:

// Note: I can't remember is Section is required or not
private const string Header = @"<Section xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""><Paragraph>";

private const string DefaultContent = "This is an example of button content. This is a very long content";

private const string Footer = "</Paragraph></Section>";

private string _search;
public string Search
{ 
    get { return _search; }
    set {
         if (Set(ref _search, value))  // using MVVMLight
         {
             // search value was updated
             this.ButtonContent = Header + DefaultContent.Replace(value, "<Italic>" + value + "</Italic>") + Footer;
         }
    }
}

我会简单地定义你的按钮如下:

                <Button.Content>
                <TextBlock>
                    <Run Text="This" />
                    <Run Text="is" FontStyle="{Binding Converter={StaticResource ItalicConverter}}" />
                    <Run Text="a..."  />
                </TextBlock>
            </Button.Content>

然后我会使用 ValueConverter 来检查用户是否按下了另一个按钮或没有更改样式。

像这样:

    public class ItalicConverter : IValueConverter
    {
         public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
         {
            return "Italic";
         }

         public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
         {
            return true;
         }
     }

您必须添加逻辑才能将其恢复正常