我目前正在使用WPF编写文本编辑器,其中包含一个工具栏和一个RichTextBox。工具栏中的每个按钮定义了将应用于所选文本的文本属性(使用costum属性)。很好。
如果用户单击文本上的某个位置,则将其文本属性应用于当前位置时,按钮应突出显示。当我尝试检查当前选择项是否带有下划线/删除线时,它不起作用。
private void checkToolBarButtons()
{
// this method checks if the button should be highlighted or not.
Func<Button, object> check = (Button button) =>
{
try
{
// the button has two costum properties that allow to determine which text property should be
// applied to the selected text.
string propString = ToolBarButton.GetDocumentProperty(button);
// e.g. "TextDecorations"
DependencyProperty dependency = this.getPropertyByString(propString);
// e.g. TextDecorationsProperty
string propertyValue = ToolBarButton.GetDocumentPropertyValue(button);
// e.g. "Underline"
if (dependency != null)
{
TextRange selectionRange = new TextRange(this.richTextBox.Selection.Start, this.richTextBox.Selection.End);
object selectedProperty = selectionRange.GetPropertyValue(dependency);
if (selectedProperty.GetType() == typeof(TextDecorationCollection) && ((TextDecorationCollection)selectedProperty).Count > 0)
{
if (selectedProperty.Equals(TextDecorations.Underline))
{
// this code is never reached
selectedProperty = "Underline";
}
else if (selectedProperty.Equals(TextDecorations.Strikethrough))
{
// this code is never reached
selectedProperty = "Strikethrough";
}
}
if (selectedProperty.ToString() == propertyValue)
{
button.Background = new SolidColorBrush(Colors.Yellow);
}
else
{
button.Background = new SolidColorBrush(Colors.LightGray);
}
}
}
catch (Exception ex)
{
}
return null;
};
foreach (FrameworkElement ctrl in toolBar.Children)
{
if (ctrl.GetType() == typeof(StackPanel))
{
foreach (Button button in ((Panel)ctrl).Children)
{
check(button);
}
}
else if (ctrl.GetType() == typeof(Button))
{
check((Button)ctrl);
}
}
}
/// <summary>
/// converts a string to a DependencyProperty
/// </summary>
/// <param name="propertyString"></param>
/// <returns></returns>
private DependencyProperty getPropertyByString(string propertyString)
{
switch (propertyString)
{
case ("FontStyleProperty"): return FontStyleProperty;
case ("FontWeightProperty"): return FontWeightProperty;
case ("TextDecorations"): return TextBlock.TextDecorationsProperty;
case ("TextAlignment"): return TextBlock.TextAlignmentProperty;
default:
break;
}
return null;
}
<UserControl x:Class="EasyControls.TextEditor"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:EasyControls"
mc:Ignorable="d" Height="236.318" Width="493.571">
<Border BorderThickness="1" BorderBrush="Blue">
<DockPanel Background="White">
<WrapPanel x:Name="toolBar" Orientation="Horizontal" Background="#FF2B2B8F" DockPanel.Dock="Top">
<StackPanel x:Name="textAlignPanel" Background="#FFF4F4F5" Height="21" Orientation="Horizontal" Margin="2">
<Button local:ToolBarButton.DocumentProperty="TextAlignment" local:ToolBarButton.DocumentPropertyValue="Left"
Margin="2 2 2 2" Click="ToolBarButton_Click" Width="20">
<Image Source="img/Left.png" />
</Button>
<Button local:ToolBarButton.DocumentProperty="TextAlignment" local:ToolBarButton.DocumentPropertyValue="Center"
Margin="2 2 2 2" Click="ToolBarButton_Click" Width="20">
<Image Source="img/Center.png" />
</Button>
<Button local:ToolBarButton.DocumentProperty="TextAlignment" local:ToolBarButton.DocumentPropertyValue="Right"
Margin="2 2 2 2" Click="ToolBarButton_Click" Width="20">
<Image Source="img/Right.png" />
</Button>
<Button local:ToolBarButton.DocumentProperty="TextAlignment" local:ToolBarButton.DocumentPropertyValue="Justify"
Margin="2 2 2 2" Click="ToolBarButton_Click" Width="20">
<Image Source="img/Justify.png" />
</Button>
</StackPanel>
<StackPanel x:Name="fontStylePanel" Background="#FFF4F4F5" Height="21" Orientation="Horizontal">
<Button local:ToolBarButton.DocumentProperty="FontWeightProperty" local:ToolBarButton.DocumentPropertyValue="Bold"
Margin="2 2 2 2" Click="ToolBarButton_Click" FontWeight="Bold" Width="20">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">b</TextBlock>
</Button>
<Button local:ToolBarButton.DocumentProperty="FontStyleProperty" local:ToolBarButton.DocumentPropertyValue="Italic"
Margin="1 2 2 2" Click="ToolBarButton_Click" FontStyle="Italic" Width="20">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">i</TextBlock>
</Button>
<Button local:ToolBarButton.DocumentProperty="TextDecorations" local:ToolBarButton.DocumentPropertyValue="Underline"
Margin="1 2 2 2" Click="ToolBarButton_Click" Width="20" >
<TextBlock TextDecorations="Underline" HorizontalAlignment="Center" VerticalAlignment="Center">u</TextBlock>
</Button>
<Button local:ToolBarButton.DocumentProperty="TextDecorations" local:ToolBarButton.DocumentPropertyValue="Strikethrough"
Margin="1 2 2 2" Click="ToolBarButton_Click" Width="20" >
<TextBlock TextDecorations="Strikethrough" HorizontalAlignment="Center" VerticalAlignment="Center">s</TextBlock>
</Button>
</StackPanel>
</WrapPanel>
<RichTextBox x:Name="richTextBox" Background="White" SelectionChanged="RichTextBox_SelectionChanged" IsDocumentEnabled="True" DockPanel.Dock="Bottom" VerticalAlignment="Stretch" BorderThickness="0" BorderBrush="{x:Null}">
<FlowDocument>
<Paragraph/>
</FlowDocument>
</RichTextBox>
</DockPanel>
</Border>
答案 0 :(得分:1)
您首先检查selectedProperty
是TextDecorationCollection
,然后在您期望它是TextDecorations.Underline
或TextDecorations.Strikethrough
之后立即检查吗?这是没有道理的。
您可能想将selectedProperty
强制转换为TextDecorationCollection
,然后对其进行迭代。像这样:
...
TextRange selectionRange = new TextRange(this.richTextBox.Selection.Start, this.richTextBox.Selection.End);
object selectedProperty = selectionRange.GetPropertyValue(TextBlock.TextDecorationsProperty);
TextDecorationCollection textDecorationCollection = selectedProperty as TextDecorationCollection;
if (textDecorationCollection != null)
{
foreach (TextDecoration textDecoration in textDecorationCollection)
{
if (textDecoration.Location == TextDecorationLocation.Underline)
{
// this code is never reached
selectedProperty = "Underline";
}
else if (textDecoration.Location == TextDecorationLocation.Strikethrough)
{
// this code is never reached
selectedProperty = "Strikethrough";
}
}
}