2016-07-27 35 views
1

我可以对按钮的内容应用不同的样式吗?例如我有一个搜索框,如果用户在搜索框中输入“is”并单击搜索,我可以在按钮内容的斜体字体下面两个“is”?同时,我想保留其余部分,不加斜体。如何在一个段落上应用不同的样式?

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

申请后,我想按钮的内容风格: 这按钮内容的例子。这一个很长的内容。

这可能吗?

回答

1

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

<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> 

视图模型:

// 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; 
     } 
    } 
} 
+0

酷!我会试试这个!非常感谢! – spspli

+0

让我知道是否有任何错误。我从我使用的代码中做了一些更改,但没有测试它编译的代码。 – Pakman

+0

你有没有尝试过斜体值部分更花哨的风格?你知道我可以运用任何我喜欢这个价值的风格吗?或者只是像字体等简单的风格? DefaultContent。替换(值,“”+ value +“”) – spspli

1

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

+0

如何有条件地码在用户输入时应用样式?你能谈谈更多关于这个问题吗?或者你有一个例子,以便我可以参考? – spspli

+0

这只是意味着在某些条件成立的情况下分配'Style'属性,例如'if(run.Text.Contains(“the”))run.Style = italicStyle'。 –

0

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

   <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; 
     } 
    } 

你将不得不添加逻辑将其转换回正常

+0

谢谢你的回答。实际上内容是动态的,搜索内容也是动态的。但还是谢谢你! – spspli

相关问题