我在设置Underline,Overline或Strikethrough时看到的所有示例都看起来像这样:
// setting underline
textRange.ApplyPropertyValue(Inline.TextDecorationsProperty,
TextDecorations.Underline);
// clearing underline
textRange.ApplyPropertyValue(Inline.TextDecorationsProperty, null );
这对我来说似乎过于简单; TextDecorationsProperty
会返回装饰的集合 - 您可以同时应用Overline
,Underline
和Strikethrough
;像这样设置它们会消灭整个集合。
这就是我通过TextDecorationLocation
切换它们所拥有的:
var textRange = new TextRange(tb.Selection.Start, tb.Selection.End);
var tdp = textRange.GetPropertyValue(Inline.TextDecorationsProperty);
var textDecorations = tdp.Equals(DependencyProperty.UnsetValue)
? new TextDecorationCollection()
: tdp as TextDecorationCollection
?? new TextDecorationCollection();
var strikethroughs = textDecorations.Where(d => d.Location == TextDecorationLocation.Strikethrough)
.ToList();
if (strikethroughs.Any())
{
foreach (var strike in strikethroughs)
{
textDecorations.Remove(strike);
}
}
else
{
textDecorations.Add(TextDecorations.Strikethrough);
}
textRange.ApplyPropertyValue(Inline.TextDecorationsProperty, textDecorations);
这是一个很好的解决方法,还是让我过于复杂?
答案 0 :(得分:3)
如果您试图打开和关闭装饰品,同时允许它们合并,您可以执行以下操作:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal">
<Button Content="Underline" Click="Underline" />
<Button Content="Strikethrough" Click="Strikethrough" />
<Button Content="Baseline" Click="Baseline" />
<Button Content="Overline" Click="Overline" />
</StackPanel>
<RichTextBox x:Name="tb" Grid.Row="1" />
</Grid>
然后在代码中
private void Underline(object sender, RoutedEventArgs e)
{
this.SetDecorations(new TextRange(this.tb.Selection.Start, this.tb.Selection.End), TextDecorations.Underline);
}
private void Strikethrough(object sender, RoutedEventArgs e)
{
this.SetDecorations(new TextRange(this.tb.Selection.Start, this.tb.Selection.End), TextDecorations.Strikethrough);
}
private void Baseline(object sender, RoutedEventArgs e)
{
this.SetDecorations(new TextRange(this.tb.Selection.Start, this.tb.Selection.End), TextDecorations.Baseline);
}
private void Overline(object sender, RoutedEventArgs e)
{
this.SetDecorations(new TextRange(this.tb.Selection.Start, this.tb.Selection.End), TextDecorations.OverLine);
}
private void SetDecorations(TextRange textRange, TextDecorationCollection decoration)
{
var decorations = textRange.GetPropertyValue(Inline.TextDecorationsProperty) as TextDecorationCollection
?? new TextDecorationCollection();
decorations = decorations.Contains(decoration.First())
? new TextDecorationCollection(decorations.Except(decoration))
: new TextDecorationCollection(decorations.Union(decoration));
textRange.ApplyPropertyValue(Inline.TextDecorationsProperty, decorations);
}
此代码使用现有的装饰设置,然后使用联合或根据是否已经附加设置排除当前装饰 - 允许打开/关闭装饰。