silverlight 4之RichTextBox小试牛刀。

Silverlight4继续摸索中,这回来到了RichTextBox,MS提供的类库中提供了RichTextBox,但是并没有带工具栏,需要的话必须自己实现,好在在Silverlight4的文档中自带一个叫Issue Tracker的示例程序,里面有应用RichTextBox的例子,但是缺少了字体颜色,文本对齐和插入图片的功能,我摸索着加上这三个功能,我是在Issue Tracker的例子上修改的,Issue Tracker在Silverlight4 文档 - 入门 - Silverlight实例 - 行业示例中。

如图所示:

首先我删掉了ReadOnly按钮,没啥理由。

1, 选择颜色

颜色面板用WrapPanel最合适不过了,只要按规律把R,G,B(红绿蓝)不用组合全部塞入到Panel里就好了。
<UserControl xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit" x:Class="Vega.Controls.ColorControl"
xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d
="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc
="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable
="d"
d:DesignHeight
="240" d:DesignWidth="360">
<toolkit:WrapPanel x:Name="panel" Width="360" />
</UserControl>

 

public partial class ColorControl : UserControl
{
public EventHandler SelectColor;

public ColorControl()
{
InitializeComponent();

int granularity = 51;
for (int r = 0; r <= 255; r += granularity)
{
for (int g = 0; g <= 255; g += granularity)
{
for (int b = 0; b <= 255; b += granularity)
{
var rectangle
=new Rectangle
{
Width
= 20,
Height
= 20,
Cursor
= Cursors.Hand,
Fill
= new SolidColorBrush(Color.FromArgb(255, (byte)r, (byte)g, (byte)b))
};
rectangle.MouseLeftButtonUp
+= new MouseButtonEventHandler(rectangle_MouseLeftButtonUp);
this.panel.Children.Add(rectangle);
}
}
}
}

private void rectangle_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
this.Visibility = System.Windows.Visibility.Collapsed;
if (this.SelectColor != null)
{
this.SelectColor(sender, e);
}
}
}

 

显示效果,颜色有点乱,还不知道有没有更好算法:
加一个按钮,点击的时候显示颜色面板。
将选择的颜色应用到Section:

private void colorButton_Click(object sender, RoutedEventArgs e)
{
this.color.Visibility = System.Windows.Visibility.Visible;
this.color.SelectColor = (senderObj, eventArgs) => {
var rectangle
= senderObj as Rectangle;
this.richTextBox.Selection.ApplyPropertyValue(Run.ForegroundProperty, rectangle.Fill);
this.richTextBox.Focus();
};
}

 

2,对齐

加入个ComboBox先。

 

<ComboBox x:Name="alignmentComboBox"
Margin
="0,2,2,2"
Height
="25"
Width
="65"
xmlns:sys
="clr-namespace:System;assembly=mscorlib" SelectionChanged="alignmentComboBox_SelectionChanged">
<sys:String>左对齐</sys:String>
<sys:String>居中</sys:String>
<sys:String>右对齐</sys:String>
</ComboBox>

 

对齐也很简单
private void alignmentComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
TextAlignment align
= TextAlignment.Left;
switch (this.alignmentComboBox.SelectedItem.ToString())
{
case "左对齐":
align
= TextAlignment.Left;
break;
case "居中":
align
= TextAlignment.Center;
break;
case "右对齐":
align
= TextAlignment.Right;
break;
}
this.richTextBox.Selection.ApplyPropertyValue(Block.TextAlignmentProperty, align);
}

 

记得修改richTextBox_SelectionChanged方法,在用户移动光标的时候修改ComboBox的选择状态

try
{
switch ((TextAlignment)this.richTextBox.Selection.GetPropertyValue(Block.TextAlignmentProperty))
{
case TextAlignment.Left:
this.alignmentComboBox.SelectedItem = "左对齐";
break;
case TextAlignment.Center:
this.alignmentComboBox.SelectedItem = "居中";
break;
case TextAlignment.Right:
this.alignmentComboBox.SelectedItem = "右对齐";
break;
}
}
catch { }

 

3,添加图片功能

新建一个子窗口,用于添加,上传图片用。
这个窗口有三个属性,图片的URL,宽度和高度。
public string Source
{
get { return (string)GetValue(SourceProperty); }
set { SetValue(SourceProperty, value); }
}

public int ImageWidth
{
get { return (int)GetValue(ImageWidthProperty); }
set { SetValue(ImageWidthProperty, value); }
}

public int ImageHeight
{
get { return (int)GetValue(ImageHeightProperty); }
set { SetValue(ImageHeightProperty, value); }
}

public static readonly DependencyProperty SourceProperty =
DependencyProperty.Register(
"Source", typeof(string), typeof(ImageAttributeWindow), new PropertyMetadata("http://"));

public static readonly DependencyProperty ImageWidthProperty =
DependencyProperty.Register(
"ImageWidth", typeof(int), typeof(ImageAttributeWindow), new PropertyMetadata(100));

public static readonly DependencyProperty ImageHeightProperty =
DependencyProperty.Register(
"ImageHeight", typeof(int), typeof(ImageAttributeWindow), new PropertyMetadata(100));

 

窗口布局
<controls:ChildWindow xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit" x:Class="Vega.Controls.ImageAttributeWindow"
xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls
="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
Width
="504" Height="178"
Title
="图片属性" Name="imageAttributeWindow">
<toolkit:BusyIndicator x:Name="busyIndicator">
<Grid x:Name="LayoutRoot" Margin="2">
<Grid.RowDefinitions>
<RowDefinition Height="10" />
<RowDefinition Height="*" />
<RowDefinition Height="40" />
</Grid.RowDefinitions>
<Grid Grid.Row="1" Name="grid1">
<Grid.RowDefinitions>
<RowDefinition Height="25" />
<RowDefinition Height="25" />
<RowDefinition Height="25" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock HorizontalAlignment="Right" Text="源地址:" VerticalAlignment="Center" />
<TextBlock HorizontalAlignment="Right" Text="宽度:" VerticalAlignment="Center" Grid.Row="1" />
<TextBlock HorizontalAlignment="Right" Text="宽度:" VerticalAlignment="Center" Grid.Row="2" />
<TextBox Grid.Column="1" Margin="2,2,60,2" Text="{Binding Path=Source, Mode=TwoWay, ElementName=imageAttributeWindow}" />
<Button Content="上传" Width="50" Grid.Column="1" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="2" Name="uploadButton" Click="uploadButton_Click" />
<toolkit:NumericUpDown HorizontalAlignment="Left" Grid.Column="1" Grid.Row="1" Margin="2,2,0,0" Value="{Binding Path=ImageWidth, Mode=TwoWay, ElementName=imageAttributeWindow}" Maximum="1000" Height="22" VerticalAlignment="Top" />
<toolkit:NumericUpDown HorizontalAlignment="Left" Grid.Column="1" Grid.Row="2" Margin="2" Value="{Binding Path=ImageHeight, Mode=TwoWay, ElementName=imageAttributeWindow}" Maximum="1000" />
</Grid>
<Button x:Name="CancelButton" Content="取消" Click="CancelButton_Click" Width="75" Height="23" HorizontalAlignment="Right" Margin="0,12,0,0" Grid.Row="2" />
<Button x:Name="OKButton" Content="确定" Click="OKButton_Click" Width="75" Height="23" HorizontalAlignment="Right" Margin="0,12,79,0" Grid.Row="2" />
</Grid>
</toolkit:BusyIndicator>
</controls:ChildWindow>

 

我把图片URL,宽度,高度都和子窗口的Source,ImageWidth,ImageHeight绑定了起来,效果如下
上传图片的代码
private void uploadButton_Click(object sender, RoutedEventArgs e)
{
var fileDialog
= new OpenFileDialog()
{
Filter
= "图片(.jpg)|*.jpg|图片(.jpeg)|*.jpeg|图片(.png)|*.png",
Multiselect
= false
};

var result
= fileDialog.ShowDialog();
if (result.HasValue && result.Value)
{
using (var stream = fileDialog.File.OpenRead())
{
var imgSource
= new BitmapImage();
imgSource.SetSource(stream);
var bitmap
= new WriteableBitmap(imgSource);
this.ImageWidth = bitmap.PixelWidth;
this.ImageHeight = bitmap.PixelHeight;

stream.Seek(
0, SeekOrigin.Begin);
var bytes
= new byte[stream.Length];
stream.Read(bytes,
0, bytes.Length);
this.busyIndicator.IsBusy = true;
var op
= this.uploadContext.Upload(bytes, fileDialog.File.Extension);
op.Completed
+= (opSender, opE) => {
var source
= Application.Current.Host.Source;
this.Source = String.Format("{0}://{1}:{2}{3}", source.Scheme, source.Host, source.Port, op.Value);
this.busyIndicator.IsBusy = false;
};
}
}
}

 

负责上传的uploadContext在上一篇随笔 http://www.cnblogs.com/subwayline13/archive/2010/09/01/1813836.html 有提到,很简单。区别是,silvelight 客户端有加上通过WriteableBitmap读取宽度和高度方法,读取到长和宽之后记得归位stream.Seek(0, SeekOrigin.Begin);不然stream.Read不到,因为指针已经到尾部了。

调用添加图片子窗口的代码
private void imageButton_Click(object sender, RoutedEventArgs e)
{
var window
= new ImageAttributeWindow();
window.Closed
+= (senderObj, ea) =>
{
if (!window.DialogResult.HasValue || !window.DialogResult.Value)
{
return;
}

InlineUIContainer container
= new InlineUIContainer();
container.Child
= new Image()
{
Stretch
= Stretch.Uniform,
Width
= window.ImageWidth,
Height
= window.ImageHeight,
Source
= new BitmapImage(new Uri(window.Source,UriKind.Absolute))
};
this.richTextBox.Selection.Insert(container);
};
window.Show();
}

 

网上搜了一下,发现RichTextBox还不少,有一个免费开源的http://www.vectorlight.net/demos/richtextbox.aspx,不过存储的不是XAML的,是自定义的XML的。
posted @ 2010-09-06 18:35  subwayline13  阅读(3783)  评论(4编辑  收藏  举报