如何应用多个 TextDecorations?
How can I apply multiple TextDecorations?
我见过的所有设置下划线、上划线或删除线的示例都是这样的:
// setting underline
textRange.ApplyPropertyValue(Inline.TextDecorationsProperty,
TextDecorations.Underline);
// clearing underline
textRange.ApplyPropertyValue(Inline.TextDecorationsProperty, null );
这对我来说似乎过于简单化; TextDecorationsProperty
returns 系列 装饰品 - 您可以将 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);
这是解决这个问题的好方法,还是我让它过于复杂了?
如果您尝试打开和关闭装饰,同时允许它们组合,您可以执行以下操作:
<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);
}
此代码使用现有装饰集,然后联合或集根据当前装饰是否已附加来排除当前装饰 - 允许切换装饰 on/off。
我见过的所有设置下划线、上划线或删除线的示例都是这样的:
// setting underline
textRange.ApplyPropertyValue(Inline.TextDecorationsProperty,
TextDecorations.Underline);
// clearing underline
textRange.ApplyPropertyValue(Inline.TextDecorationsProperty, null );
这对我来说似乎过于简单化; TextDecorationsProperty
returns 系列 装饰品 - 您可以将 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);
这是解决这个问题的好方法,还是我让它过于复杂了?
如果您尝试打开和关闭装饰,同时允许它们组合,您可以执行以下操作:
<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);
}
此代码使用现有装饰集,然后联合或集根据当前装饰是否已附加来排除当前装饰 - 允许切换装饰 on/off。