• 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的。
  • 相关阅读:
    三部曲搭建本地nuget服务器(图文版)
    用批处理编译*.sln工程
    一组无序的整数找出出现次数大于一半的数字
    程序打怪升级之旅
    web开发有那些牛逼东西可以用
    Visual Studio for mac从入门到放弃1
    svn自动更新服务器最新代码
    WinRT支持GB2312
    初试Node —— node.js的安装
    为什么要重写equals方法和hashcode方法
  • 原文地址:https://www.cnblogs.com/subwayline13/p/1819554.html
Copyright © 2020-2023  润新知