WPF笔记汇总之富文本控件与标签页控件

WPF富文本控件与标签页控件

接着上一篇《WPF笔记汇总之杂项控件与样式》,来总结下一个WPF知识点,这篇主要汇总富文本控件与选项卡控件,包括一些常用的用法属性及相关控件样式的自定义实例。

1. FlowDocument 控件

就是编辑这些加载的富文本用的控件。就是FlowDocument系列控件,负责渲染富文本,这包括图片、列表、表格,以及其他可以浮动、调整等的元素。使用FlowDocument,可以在设计时像HTML一样指定富文本内容,并能直接在你的WPF应用中渲染。FlowDocument并不是单独的组件。

1.1 FlowDocumentScrollViewer

FlowDocument的最简单的包装,它简单地把文档显示成一份长文本文档,允许滚动浏览。可以在按住Ctrl键时使用鼠标滚轮放大和缩小。也可以在FlowDocumentScrollViewer上将IsToolBarVisible属性设置为true,显示缩放的工具栏。通过设置ScrollViewer.VerticalScrollBarVisibility属性为Auto,滚动条将被置为不可见,TextAlignment属性设置对其方式,IsOptimalParagraphEnabled属性使文本尽量在前,。 IsHyphenationEnabled 允许WPF使用连字符分割单词。

<FlowDocumentScrollViewer>
	<FlowDocument>
		<Paragraph FontSize="36">Hello, world!</Paragraph>
		<Paragraph FontStyle="Italic" TextAlignment="Left" FontSize="14" Foreground="Gray">The ultimate programming greeting!</Paragraph>
	</FlowDocument>
</FlowDocumentScrollViewer>

<!--显示缩放工具栏-->
<FlowDocumentScrollViewer IsToolBarVisible="True" Zoom="80" ScrollViewer.VerticalScrollBarVisibility="Auto">
	<FlowDocument>
		<Paragraph FontSize="36">Hello, world!</Paragraph>
		<Paragraph FontStyle="Italic" TextAlignment="Left" FontSize="14" Foreground="Gray">The ultimate programming greeting!</Paragraph>
	</FlowDocument>
</FlowDocumentScrollViewer>

<!--文本对齐-->
<FlowDocumentScrollViewer ScrollViewer.VerticalScrollBarVisibility="Auto">
		<FlowDocument>
			<Paragraph FontStyle="Italic" FontSize="14" Foreground="Gray">
				By setting the
				<Bold>IsOptimalParagraphEnabled</Bold> property to true,
                  you will allow WPF to look ahead on the lines to come, before deciding
                  where to break. This will usually result in a more pleasant reading
                  experience. It works especially well in combination with the
				<Bold>IsHyphenationEnabled</Bold> property.
			</Paragraph>
		</FlowDocument>
	</FlowDocumentScrollViewer>

<FlowDocumentScrollViewer ScrollViewer.VerticalScrollBarVisibility="Auto">
	<FlowDocument IsOptimalParagraphEnabled="True" IsHyphenationEnabled="True">
		<Paragraph FontStyle="Italic" FontSize="14" Foreground="Gray">
			By setting the
			<Bold>IsOptimalParagraphEnabled</Bold> property to true,
                  you will allow WPF to look ahead on the lines to come, before deciding
                  where to break. This will usually result in a more pleasant reading
                  experience. It works especially well in combination with the
			<Bold>IsHyphenationEnabled</Bold> property.
		</Paragraph>
	</FlowDocument>
</FlowDocumentScrollViewer>
1.2 FlowDocumentPageViewer

该控件会自动把你的文档分割成页,以便在页之间浏览,支持Ctrl+F键盘快捷键来启动搜索,但要确保有足够的水平控件,否则看不到搜索框

<DockPanel>
	<WrapPanel DockPanel.Dock="Top">
		<Button Name="btnSearch" Click="btnSearch_Click">Search</Button>
	</WrapPanel>
	<FlowDocumentPageViewer Name="fdViewer">
		<FlowDocument>
			<Paragraph>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce faucibus odio arcu, luctus vestibulum tortor congue in. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce nec lacinia neque. Donec malesuada, ligula non vestibulum cursus, urna purus pellentesque orci, aliquet accumsan dui velit ac justo. Phasellus sagittis ligula in leo dapibus, vel vestibulum felis mattis. Fusce vitae auctor nibh. Ut sit amet fringilla turpis. Aenean tincidunt feugiat sapien, quis scelerisque enim pretium commodo. Mauris fermentum posuere nulla, vitae fermentum quam malesuada in. Cras ultrices bibendum nulla eu mollis. Sed accumsan pretium magna, non sodales velit viverra id. Sed eu elit sit amet sem ullamcorper rhoncus.</Paragraph>
			<Paragraph>Nulla vitae suscipit tellus. Nunc sit amet tortor fermentum, sollicitudin enim cursus, sagittis lacus. Pellentesque tincidunt massa nisl, nec tempor nulla consequat a. Proin pharetra neque vel dolor congue, at condimentum arcu varius. Sed vel luctus enim. Curabitur eleifend dui et arcu faucibus, sit amet vulputate libero suscipit. Vestibulum ultrices nisi id metus ultrices, eu ultricies ligula rutrum. Phasellus rhoncus aliquam pretium. Quisque in nunc erat. Etiam mollis turpis cursus, sagittis felis vel, dignissim risus. Ut at est nec tellus lobortis venenatis. Fusce elit mi, gravida sed tortor at, faucibus interdum felis. Phasellus porttitor dolor in nunc pellentesque, eu hendrerit nulla porta. Vestibulum cursus placerat elit. Nullam malesuada dictum venenatis. Interdum et malesuada fames ac ante ipsum primis in faucibus.</Paragraph>
		</FlowDocument>
	</FlowDocumentPageViewer>
</DockPanel>

也可以在后置代码中调用搜索按钮

private void btnSearch_Click(object sender, RoutedEventArgs e)
{
	fdViewer.Find();
}
1.3 FlowDocumentReader

前两种控件的结合体。它有一些比较重要的属性,ViewingMode - 控制初始查看模式。 默认值为Page,但如果您需要其他默认视图,则可以将其更改为Scroll或TwoPage。 除非明确禁用,否则最终用户仍可以更改此设置。IsFindEnabled - 使您能够禁用文档中的搜索。 如果禁用,搜索按钮将从工具栏中删除。IsTwoPageViewEnabled, IsPageViewEnabled 和 IsScrollViewEnabled - 允许关闭阅读器的特定查看模式。 设置为false时,此模式不再适用于阅读器,并且该按钮将从工具栏中删除。
Zoom - 允许设置默认缩放级别。 标准是100%,但可以使用Zoom属性更改此值。

<Grid>
	<FlowDocumentReader>
		<FlowDocument>
			<Paragraph>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce faucibus odio arcu, luctus vestibulum tortor congue in. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce nec lacinia neque. Donec malesuada, ligula non vestibulum cursus, urna purus pellentesque orci, aliquet accumsan dui velit ac justo. Phasellus sagittis ligula in leo dapibus, vel vestibulum felis mattis. Fusce vitae auctor nibh. Ut sit amet fringilla turpis. Aenean tincidunt feugiat sapien, quis scelerisque enim pretium commodo. Mauris fermentum posuere nulla, vitae fermentum quam malesuada in. Cras ultrices bibendum nulla eu mollis. Sed accumsan pretium magna, non sodales velit viverra id. Sed eu elit sit amet sem ullamcorper rhoncus.</Paragraph>
			<Paragraph>Nulla vitae suscipit tellus. Nunc sit amet tortor fermentum, sollicitudin enim cursus, sagittis lacus. Pellentesque tincidunt massa nisl, nec tempor nulla consequat a. Proin pharetra neque vel dolor congue, at condimentum arcu varius. Sed vel luctus enim. Curabitur eleifend dui et arcu faucibus, sit amet vulputate libero suscipit. Vestibulum ultrices nisi id metus ultrices, eu ultricies ligula rutrum. Phasellus rhoncus aliquam pretium. Quisque in nunc erat. Etiam mollis turpis cursus, sagittis felis vel, dignissim risus. Ut at est nec tellus lobortis venenatis. Fusce elit mi, gravida sed tortor at, faucibus interdum felis. Phasellus porttitor dolor in nunc pellentesque, eu hendrerit nulla porta. Vestibulum cursus placerat elit. Nullam malesuada dictum venenatis. Interdum et malesuada fames ac ante ipsum primis in faucibus.</Paragraph>
		</FlowDocument>
	</FlowDocumentReader>
</Grid>

也可以从后置代码进行设置

<Grid>
	<FlowDocumentScrollViewer Name="fdViewer" />
</Grid>
public MainWindow()
{
	InitializeComponent();

	FlowDocument doc = new FlowDocument();
	Paragraph p = new Paragraph(new Run("Hello, world!"));
	p.FontSize = 36;
	doc.Blocks.Add(p);
	
	p = new Paragraph(new Run("The ultimate programming greeting!"));
	p.FontSize = 14;
	p.FontStyle = FontStyles.Italic;
	p.TextAlignment = TextAlignment.Left;
	p.Foreground = Brushes.Gray;
	doc.Blocks.Add(p);
	fdViewer.Document = doc;
}
1.4 高级FlowDocument内容

可以在FlowDocument中包含任何WPF控件。 使用BlockUIContainer元素包含他们,就可以访问所有控件了。

<Window.Resources>
	<x:Array x:Key="UserArray" Type="{x:Type local:User}">
		<local:User Name="John Doe" Age="42"/>
		<local:User Name="Jane Doe" Age="36"/>
	</x:Array>
</Window.Resources>
<Grid>
	<FlowDocumentScrollViewer>
		<FlowDocument>
			<Paragraph FontSize="36" Margin="0">Users</Paragraph>
			<Paragraph FontStyle="Italic" TextAlignment="Left" FontSize="14" Foreground="Gray">Here's a list of our users, inside our FlowDocument, in a completely interactive ListView control!</Paragraph>
			<BlockUIContainer>
				<ListView BorderThickness="0" ItemsSource="{StaticResource UserArray}">
					<ListView.View>
						<GridView>
							<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" Width="150" />
							<GridViewColumn Header="Age" DisplayMemberBinding="{Binding Age}" Width="75" />
						</GridView>
					</ListView.View>
				</ListView>
			</BlockUIContainer>
			<Paragraph FontStyle="Italic" TextAlignment="Left" FontSize="14" Foreground="Gray">More content can go here...</Paragraph>
		</FlowDocument>
	</FlowDocumentScrollViewer>
</Grid>
public class User
{
	public String Name { get; set; }
	public int Age { get; set; }
}

2. RichTextBox 控件

FlowDocument通常是只读的,但将其放入一个RichTextBox控件后,你就可以像在Word那样的文档编辑器上一样编辑这些文本了。比较麻烦的是,RichTextBox 不能直接访问RichTextBox的文本属性,只能使用来自RichTextBox的TextPointer的TextRange对象来获取控件中的文本或控件中的选择。此外还需要设置一下段落的间距。

<DockPanel>
	<WrapPanel DockPanel.Dock="Top">
	<Button Name="btnGetText" Click="btnGetText_Click">Get text</Button>
	<Button Name="btnSetText" Click="btnSetText_Click">Set text</Button>
	<Button Name="btnGetSelectedText" Click="btnGetSelectedText_Click">Get sel. text</Button>
	<Button Name="btnSetSelectedText" Click="btnSetSelectedText_Click">Replace sel. text</Button>
	</WrapPanel>
<TextBox DockPanel.Dock="Bottom" Name="txtStatus" />
<RichTextBox Name="rtbEditor" SelectionChanged="rtbEditor_SelectionChanged">
	<RichTextBox.Resources>
		<Style TargetType="{x:Type Paragraph}">
			<Setter Property="Margin" Value="0" />
		</Style>
	</RichTextBox.Resources>
	<FlowDocument>
			<Paragraph FontSize="36">Hello, world!</Paragraph>
			<Paragraph FontStyle="Italic" TextAlignment="Left" FontSize="14" Foreground="Gray">Thanks to the RichTextBox control, this FlowDocument is completely editable!</Paragraph>
	</FlowDocument>
</RichTextBox>
</DockPanel>

3. TabControl 控件

TabControl 就是标签页控件。其中TabStripPlacement 属性可以改变选项卡的位置,结合样式与模板可以改变标签选项卡的位置及标签页头文字的方向。

3.1 常规用法
<!--简单标签页-->
<Grid>
	<TabControl>
		<TabItem Header="General">
			<Label Content="Content goes here..." />
		</TabItem>
		<TabItem Header="Security" />
		<TabItem Header="Details" />
	</TabControl>
</Grid>

<!--自定义标题-->
<Grid>
	<TabControl>
		<TabItem>
			<TabItem.Header>
				<StackPanel Orientation="Horizontal">
					<Image Source="/images/file.png" />
					<TextBlock Text="Blue" Foreground="Blue" />
				</StackPanel>
			</TabItem.Header>
			<Label Content="Content goes here..." />
		</TabItem>
		<TabItem>
			<TabItem.Header>
				<StackPanel Orientation="Horizontal">
					<Image Source="/images/file.png" />
					<TextBlock Text="Red" Foreground="Red" />
				</StackPanel>
			</TabItem.Header>
		</TabItem>
		<TabItem>
			<TabItem.Header>
				<StackPanel Orientation="Horizontal">
					<Image Source="/images/file.png" />
					<TextBlock Text="Green" Foreground="Green" />
				</StackPanel>
			</TabItem.Header>
		</TabItem>
	</TabControl>
</Grid>

<!--控制标签页-->
<DockPanel>
	<StackPanel Orientation="Horizontal" DockPanel.Dock="Bottom" Margin="2,5">
		<Button Name="btnPreviousTab" Click="btnPreviousTab_Click">Prev.</Button>
		<Button Name="btnNextTab" Click="btnNextTab_Click">Next</Button>
		<Button Name="btnSelectedTab" Click="btnSelectedTab_Click">Selected</Button>
	</StackPanel>
	<TabControl Name="tcSample">
		<TabItem Header="General">
			<Label Content="Content goes here..." />
		</TabItem>
		<TabItem Header="Security" />
		<TabItem Header="Details" />
	</TabControl>
</DockPanel>
private void btnPreviousTab_Click(object sender, RoutedEventArgs e)
{
	int newIndex = tcSample.SelectedIndex - 1;
	if (newIndex < 0)
		newIndex = tcSample.Items.Count - 1;
	tcSample.SelectedIndex = newIndex;
}
private void btnNextTab_Click(object sender, RoutedEventArgs e)
{
	int newIndex = tcSample.SelectedIndex + 1;
	if (newIndex >= tcSample.Items.Count)
		newIndex = 0;
	tcSample.SelectedIndex = newIndex;
}
private void btnSelectedTab_Click(object sender, RoutedEventArgs e)
{
	MessageBox.Show("Selected tab: " + (tcSample.SelectedItem as TabItem).Header);
}
3.2 改变标签页方向

<TabControl TabStripPlacement="Left">
	<TabControl.Resources>
		<Style TargetType="{x:Type TabItem}">
			<Setter Property="HeaderTemplate">
				<Setter.Value>
					<DataTemplate>
						<ContentPresenter Content="{TemplateBinding Content}">
							<ContentPresenter.LayoutTransform>
								<RotateTransform Angle="270" />
							</ContentPresenter.LayoutTransform>
						</ContentPresenter>
					</DataTemplate>
				</Setter.Value>
			</Setter>
			<Setter Property="Padding" Value="3" />
		</Style>
	</TabControl.Resources>
	
	<TabItem Header="General">
		<Label Content="Content goes here..." />
	</TabItem>
	<TabItem Header="Security" />
	<TabItem Header="Details" />
</TabControl>

标签选项卡改变位置截图

3.3 自定义标签页

可以通过使用Style更改ControlTemplate来实现自定义的样式。 通过添加ContentPresenter 控件,指定TabItem的内容应放在何处。

<Grid>
    <TabControl Margin="10" BorderBrush="Gainsboro">
        <TabControl.Resources>
            <Style TargetType="TabItem">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="TabItem">
                            <Border Name="Border" BorderThickness="1,1,1,0" BorderBrush="Gainsboro" CornerRadius="4,4,0,0" Margin="2,0">
                                <ContentPresenter x:Name="ContentSite"
                                    VerticalAlignment="Center"
                                    HorizontalAlignment="Center"
                                    ContentSource="Header"
                                    Margin="10,2"/>
                            </Border>
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsSelected" Value="True">
                                    <Setter TargetName="Border" Property="Background" Value="LightSkyBlue" />
                                </Trigger>
                                <Trigger Property="IsSelected" Value="False">
                                    <Setter TargetName="Border" Property="Background" Value="GhostWhite" />
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </TabControl.Resources>
        <TabItem Header="General">
            <Label Content="Content goes here..." />
        </TabItem>
        <TabItem Header="Security" />
        <TabItem Header="Details" />
    </TabControl>
</Grid>
  • 效果运行截图
    自定义TabControl
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值