欢迎来到个人简历网!永久域名:gerenjianli.cn (个人简历全拼+cn)
当前位置:首页 > 范文大全 > 实用文>Silverlight开发中的疑难杂症:如何实现一个EditorBox

Silverlight开发中的疑难杂症:如何实现一个EditorBox

2023-02-20 08:26:22 收藏本文 下载本文

“HamSean”通过精心收集,向本站投稿了5篇Silverlight开发中的疑难杂症:如何实现一个EditorBox,这次小编给大家整理后的Silverlight开发中的疑难杂症:如何实现一个EditorBox,供大家阅读参考。

Silverlight开发中的疑难杂症:如何实现一个EditorBox

篇1:Silverlight开发中的疑难杂症:如何实现一个EditorBox

EditorBox就是一个具有编辑和展示两种状态的TextBox,因为在最近的工作和学习项目中 ,多次碰到了需要将一个TextBox以编辑和展示两种不同的样式存在,于是就想到了制作一个 这样的控件来提高生产效率,同时也尝试一下自定义控件的开发,该控件包括如下功能:

l 能在编辑和展示状态之间切换;

l 可以设置是否能够编辑;

l 在展示状态双击控件,进入到编辑状态(如果支持编辑);

l 在编辑状态,输入完文本,回车后进入展示状态;

l 提供一个Text属性供外部使用;

l 能够设置展示状态下文本样式(设置指定区间的文本的字体、字体大小、字体颜色等) ;

基本的实现思路是这样的:首先,定义两个TemplatePart,分别为TextBox和TextBlock类 型,用来表示编辑框跟展示框,文本格式的处理通过动态计算所设置的格式,然后添加多个 Run元素来实现;然后,定一个两个TemplateVisualState,用来实现编辑状态和展示状态之 间的切换。附加的Attribute声明如下:

[TemplatePart(Name = “PART_Editor”, Type = typeof(TextBox))]

[TemplatePart(Name = “PART_View”, Type = typeof(TextBlock))]

[TemplateVisualState(Name = “Edit”, GroupName = “CommonStates”)]

[TemplateVisualState(Name = “View”, GroupName = “CommonStates”)]

为了使控件使用者能够对样式进行更好的控制,这里定义了一个TextFormat类,与单个的 样式设置对应,里面包括字体、字体大小、字体颜色、样式应用的起始索引、应用的总长度 ,具体的类实现如下:

TextFormat

///

/// 文本格式

///

public class TextFormat : DependencyObject

{

///

/// 字体

///

public FontFamily FontFamily

{

get { return (FontFamily)GetValue(FontFamilyProperty); }

set { SetValue(FontFamilyProperty, value); }

}

public static readonly DependencyProperty FontFamilyProperty =

DependencyProperty.Register(“FontFamily”, typeof(FontFamily), typeof(TextFormat), new PropertyMetadata(default(FontFamily)));

///

/// 字体大小

///

public double FontSize

{

get { return (double)GetValue(FontSizeProperty); }

set { SetValue(FontSizeProperty, value); }

}

public static readonly DependencyProperty FontSizeProperty =

DependencyProperty.Register(“FontSize”, typeof(double), typeof(TextFormat), new PropertyMetadata(10.0));

///

/// 字体颜色

///

public Brush Foreground

{

get { return (Brush)GetValue(ForegroundProperty); }

set { SetValue(ForegroundProperty, value); }

}

public static readonly DependencyProperty ForegroundProperty =

DependencyProperty.Register(“Foreground”, typeof(Brush), typeof(TextFormat), new PropertyMetadata(new SolidColorBrush (Colors.Black)));

///

/// 样式应用的起始索引

///

public int StartIndex

{

get { return (int)GetValue(StartIndexProperty); }

set { SetValue(StartIndexProperty, value); }

}

public static readonly DependencyProperty StartIndexProperty =

DependencyProperty.Register(“StartIndex”, typeof(int), typeof(TextFormat), new PropertyMetadata(0));

///

/// 样式应用的长度

///

public int Length

{

get { return (int)GetValue(LengthProperty); }

set { SetValue(LengthProperty, value); }

}

public static readonly DependencyProperty LengthProperty =

DependencyProperty.Register(“Length”, typeof(int), typeof (TextFormat), new PropertyMetadata(0));

}

///

/// 文本格式集合

///

public class TextFormatCollection : ObservableCollection

{

}

之后是依赖属性的定义,除了之前提到过的文本格式集合以及当前选择的模式之外,还包 括对外提供的文本和是否允许编辑选项,同时在文本格式集合以及当前选择的模式改变时进 行文本格式化处理,依赖属性的定义如下:

Dependency Properties

#region Dependency Properties

///

/// 文本格式集合

///

public TextFormatCollection TextFormats

{

get { return (TextFormatCollection)GetValue(TextFormatsProperty); }

set { SetValue(TextFormatsProperty, value); }

}

public static readonly DependencyProperty TextFormatsProperty =

DependencyProperty.Register(“TextFormats”, typeof (TextFormatCollection), typeof(EditorBox), new PropertyMetadata(new PropertyChangedCallback(OnTextFormatsChanged)));

///

/// 文本

///

public string Text

{

get { return (string)GetValue(TextProperty); }

set { SetValue(TextProperty, value); }

}

public static readonly DependencyProperty TextProperty =

DependencyProperty.Register(“Text”, typeof(string), typeof (EditorBox), new PropertyMetadata(string.Empty));

///

/// 是否允许编辑

///

public bool CanEdit

{

get { return (bool)GetValue(CanEditProperty); }

set { SetValue(CanEditProperty, value); }

}

public static readonly DependencyProperty CanEditProperty =

DependencyProperty.Register(“CanEdit”, typeof(bool), typeof (EditorBox), new PropertyMetadata(true));

///

/// 当前模式

///

public Mode CurrentMode

{

get { return (Mode)GetValue(CurrentModeProperty); }

set { SetValue(CurrentModeProperty, value); }

}

public static readonly DependencyProperty CurrentModeProperty =

DependencyProperty.Register(“CurrentMode”, typeof(Mode), typeof (EditorBox), new PropertyMetadata(Mode.View, new PropertyChangedCallback (OnCurrentModeChanged)));

#region Property Change Handler

private static void OnTextFormatsChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)

{

(obj as EditorBox).OnTextFormatsChanged(e.OldValue as TextFormatCollection, e.NewValue as TextFormatCollection);

}

///

/// 文本格式设置改变时,重新计算文本格式

///

///

///

protected virtual void OnTextFormatsChanged(TextFormatCollection oldCollection, TextFormatCollection newCollection)

{

if (oldCollection != null)

{

oldCollection.CollectionChanged -= new NotifyCollectionChangedEventHandler(TextFormats_CollectionChanged);

}

if (newCollection != null)

{

newCollection.CollectionChanged += new NotifyCollectionChangedEventHandler(TextFormats_CollectionChanged);

}

//集合改变时重新计算文本格式

ProcessTextFormat;

}

///

/// 集合项改变时,重新计算文本格式

///

///

///

void TextFormats_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)

{

ProcessTextFormat();

}

private static void OnCurrentModeChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)

{

(obj as EditorBox).OnCurrentModeChanged((Mode)e.OldValue, (Mode) e.NewValue);

}

///

/// 从编辑模式切换到视图模式,进行文本格式计算

///

///

///

protected virtual void OnCurrentModeChanged(Mode oldMode, Mode newMode)

{

if (newMode == Mode.View)

{

ProcessTextFormat();

}

}

#endregion

由于使用了TemplatePart定义实现了界面与控件行为逻辑之间的解耦,那么自然的需要在 运行时拿到在样式中所定义的TemplatePart。这里通过重载OnApplyTemplate方法来实现子控 件的查找,以及相应的处理事件的附加,实现代码如下:

OnApplyTemplate

public override void OnApplyTemplate()

{

base.OnApplyTemplate();

AttachToVisualTree();

}

///

/// 获取模板中的子控件,并附加处理

///

void AttachToVisualTree()

{

//获取模板中的子控件

_editor = GetChildControl(PART_Editor);

_viewer = GetChildControl(PART_View);

if (_editor != null)

{

//由于Silverlight的TextChanged事件只在Load之后才会触发,所以需 要在Load之后初始化文本格式

_editor.Loaded += new RoutedEventHandler (InitTextFormat);

//按下回车回到视图模式

_editor.KeyDown += new KeyEventHandler(EnterViewMode);

//设置绑定关系

_editor.Text = this.Text;

this.SetBinding(TextProperty, new Binding(“Text”) { Source = _editor, Mode = BindingMode.TwoWay });

}

ProcessTextFormat();

}

在实际测试时,这里发现了一个问题,当我在上面的方法中设置TextBox的Text属性后, 对应控件中注册的TextChanged事件并没有触发,经过多次的调试,发现似乎只有在控件Load 完之后进行的Text属性赋值操作,才会引起TextChanged事件;然而测试了WPF中的TextBox, 并没有发现有一样的问题,在网上也没有发现有类似的讨论,只好作罢。最后通过注册 TextBox的Loaded事件,并在里面重新进行了文本格式的处理。如果有对这个问题有所了解的 朋友,希望能够给我答疑解惑~

接下来是最重要的文本格式的处理,这部分的具体思路是这样的:

1.判断是否处于展示模式;

2.清楚原有的Inlines集合;

3.将TextFormats集合中的元素按照StartIndex从小到大进行排序;

4.循环处理TextFormats集合中的元素;

5.如果当前格式覆盖了前面的格式(StartIndex>LastIndex),则抛出异常;

6.如果当前格式与前面的格式之间有空隙,则将空隙单独设置为默认格式;

7.按照当前格式进行设置;

8.循环结束,如果还有剩余的文本,则全部用默认格式处理。

最后附上完整的代码以及默认的控件样式:

EditorBox

[TemplatePart(Name = “PART_Editor”, Type = typeof(TextBox))]

[TemplatePart(Name = “PART_View”, Type = typeof(TextBlock))]

[TemplateVisualState(Name = “Edit”, GroupName = “CommonStates”)]

[TemplateVisualState(Name = “View”, GroupName = “CommonStates”)]

public class EditorBox : Control

{

public const string PART_Editor = “PART_Editor”;

public const string PART_View = “PART_View”;

public const string VisualState_Edit = “Edit”;

public const string VisualState_View = “View”;

///

/// 模式

///

public enum Mode

{

///

/// 查看模式

///

View,

///

/// 编辑模式

///

Edit

}

#region Private Fields

private TextBox _editor;

private TextBlock _viewer;

#endregion

#region Dependency Properties

///

/// 文本格式集合

///

public TextFormatCollection TextFormats

{

get { return (TextFormatCollection)GetValue (TextFormatsProperty); }

set { SetValue(TextFormatsProperty, value); }

}

public static readonly DependencyProperty TextFormatsProperty =

DependencyProperty.Register(“TextFormats”, typeof (TextFormatCollection), typeof(EditorBox), new PropertyMetadata(new PropertyChangedCallback(OnTextFormatsChanged)));

///

/// 文本

///

public string Text

{

get { return (string)GetValue(TextProperty); }

set { SetValue(TextProperty, value); }

}

public static readonly DependencyProperty TextProperty =

DependencyProperty.Register(“Text”, typeof(string), typeof (EditorBox), new PropertyMetadata(string.Empty));

///

/// 是否允许编辑

///

public bool CanEdit

{

get { return (bool)GetValue(CanEditProperty); }

set { SetValue(CanEditProperty, value); }

}

public static readonly DependencyProperty CanEditProperty =

DependencyProperty.Register(“CanEdit”, typeof(bool), typeof (EditorBox), new PropertyMetadata(true));

///

/// 当前模式

///

public Mode CurrentMode

{

get { return (Mode)GetValue(CurrentModeProperty); }

set { SetValue(CurrentModeProperty, value); }

}

public static readonly DependencyProperty CurrentModeProperty =

DependencyProperty.Register(“CurrentMode”, typeof(Mode), typeof(EditorBox), new PropertyMetadata(Mode.View, new PropertyChangedCallback(OnCurrentModeChanged)));

#region Property Change Handler

private static void OnTextFormatsChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)

{

(obj as EditorBox).OnTextFormatsChanged(e.OldValue as TextFormatCollection, e.NewValue as TextFormatCollection);

}

///

/// 文本格式设置改变时,重新计算文本格式

///

///

///

protected virtual void OnTextFormatsChanged(TextFormatCollection oldCollection, TextFormatCollection newCollection)

{

if (oldCollection != null)

{

oldCollection.CollectionChanged -= new NotifyCollectionChangedEventHandler(TextFormats_CollectionChanged);

}

if (newCollection != null)

{

newCollection.CollectionChanged += new NotifyCollectionChangedEventHandler(TextFormats_CollectionChanged);

}

//集合改变时重新计算文本格式

ProcessTextFormat();

}

///

/// 集合项改变时,重新计算文本格式

///

///

///

void TextFormats_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)

{

ProcessTextFormat();

}

private static void OnCurrentModeChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)

{

(obj as EditorBox).OnCurrentModeChanged((Mode)e.OldValue, (Mode)e.NewValue);

}

///

/// 从编辑模式切换到视图模式,进行文本格式计算

///

///

///

protected virtual void OnCurrentModeChanged(Mode oldMode, Mode newMode)

{

if (newMode == Mode.View)

{

ProcessTextFormat();

}

}

#endregion

#endregion

public EditorBox()

{

this.DefaultStyleKey = typeof(EditorBox);

TextFormats = new TextFormatCollection();

//通过附加属性增加鼠标双击事件

this.SetValue(MouseEventHelper.MouseDoubleClickProperty, new MouseButtonEventHandler(MouseDoubleClick));

}

public override void OnApplyTemplate()

{

base.OnApplyTemplate();

AttachToVisualTree();

}

///

/// 获取模板中的子控件,并附加处理

///

void AttachToVisualTree()

{

//获取模板中的子控件

_editor = GetChildControl(PART_Editor);

_viewer = GetChildControl(PART_View);

if (_editor != null)

{

//由于Silverlight的TextChanged事件只在Load之后才会触发 ,所以需要在Load之后初始化文本格式

_editor.Loaded += new RoutedEventHandler (InitTextFormat);

//按下回车回到视图模式

_editor.KeyDown += new KeyEventHandler (EnterViewMode);

//设置绑定关系

_editor.Text = this.Text;

this.SetBinding(TextProperty, new Binding(“Text”) { Source = _editor, Mode = BindingMode.TwoWay });

}

ProcessTextFormat();

}

///

/// 第一次加载时,初始化文本格式

///

///

///

void InitTextFormat(object sender, RoutedEventArgs e)

{

ProcessTextFormat();

}

///

/// 进入视图模式

///

///

///

void EnterViewMode(object sender, KeyEventArgs e)

{

//按回车进入查看状态

if (e.Key == Key.Enter)

{

VisualStateManager.GoToState(this, VisualState_View, false);

CurrentMode = Mode.View;

}

}

///

/// 双击进入编辑模式(如果允许编辑)

///

///

///

void MouseDoubleClick(object sender, MouseButtonEventArgs e)

{

//更换VisualStatus 双击进入编辑状态

if (CanEdit)

{

VisualStateManager.GoToState(this, VisualState_Edit, false);

CurrentMode = Mode.Edit;

}

}

///

/// 处理文本格式

///

void ProcessTextFormat()

{

if (_viewer != null && CurrentMode == Mode.View && this.TextFormats != null)

{

_viewer.Inlines.Clear();

//先按照StartIndex排序

var formats = this.TextFormats.OrderBy((format) =>{ return format.StartIndex; }).ToList();

int startIndex = 0;

int length = 0;

for (int i = 0; i < formats.Count; i++)

{

if (startIndex >= this.Text.Length)

break;

TextFormat format = formats[i];

Run run = new Run();

//重叠部分

if (format.StartIndex < startIndex)

{

throw new Exception(“StartIndex不能 重叠”);

}

//不要求格式部分

else if (format.StartIndex > startIndex)

{

length = Math.Min(format.StartIndex - startIndex, this.Text.Length - startIndex);

run.Text = this.Text.Substring (startIndex, length);

startIndex += length;

i--;

}

//要求格式部分

else if (format.StartIndex == startIndex)

{

length = Math.Min(format.Length, this.Text.Length - startIndex);

run.Text = this.Text.Substring (startIndex, length);

if (format.FontFamily != null)

run.FontFamily = format.FontFamily;

run.FontSize = format.FontSize;

run.Foreground = format.Foreground;

startIndex += length;

}

_viewer.Inlines.Add(run);

}

//处理尾部的剩余部分

if (startIndex < this.Text.Length)

{

Run run = new Run();

length = this.Text.Length - startIndex;

run.Text = this.Text.Substring(startIndex, length);

_viewer.Inlines.Add(run);

}

}

}

///

/// 获取指定名字的控件,并转换为对应类型

///

/// 控件类型

///

控件名

/// 转换后的控件

protected T GetChildControl(string ctrlName) where T : class

{

T ctrl = GetTemplateChild(ctrlName) as T;

return ctrl;

}

}

默认样式

xmlns=“schemas.microsoft.com/winfx//xaml/presentation”

xmlns:x=“schemas.microsoft.com/winfx/2006/xaml”

xmlns:local=“clr-namespace:YQL.CustomControlLibs” xmlns:d=“schemas.microsoft.com/expression/blend/” xmlns:mc=“schemas.openxmlformats.org/markup-compatibility/2006” mc:Ignorable=“d” >

效果预览:

www.bbniu.com/matrix/ShowApplication.aspx?id=70

篇2:Silverlight 2中多语言支持实现(下)

引言

苦笑不得的缺陷

在Silverlight 2中多语言支持实现(上)文章的最后,我们通过修改项目文件中SupportedCultures 来实现了多语言的支持,之所以能够成功,是因为前面的示例中只有两种语言English和Chinese,现在我 们再添加一个资源文件Strings.fr-FR.resx,让它能够支持French,如下图所示:

感谢我的同事Fabien帮我翻译为French,同样我们打开项目文件,在SupportedCultures中添加一种语 言文化fr-FR,我们可以用逗号或者分号来分割,如下代码所示:

现在我们解压xap文件,可以看到fr-FR、zh-CN资源文件都正确的打包在了xap文件中,如下图:

现在运行程序时,却发现中文语言文化无法显示,而法文能够正常显示:

这就是Silverlight 2 Beta 2在本地化方面支持的一个Bug,它只能够支持除默认语言之外的一种语言 。有朋友可能会问,既然能够支持除默认语言之外的一种语言,为什么在这个示例中不是中文,而是法文 呢?这主要是在SupportedCultures中设置的语言文化,在编译后,打包到AppManifest.xaml中添加 AssemblyPart时是按照语言文化的字母顺序排列的,所以会默认支持最上面一种语言文化:

好了,现在大家知道了在Silverlight 2 Beta 2中最多只能支持两种语言,但愿在RTM时该问题已经不 复存在,

另类多语言实现

现在我们再来看一种另类的多语言实现,即如果为一个Silverlight项目同时生成支持不同语言文化的 多个xap文件。我们可以在解决方案中添加一个新的Build Tag,如下图所示:

然后我们可以编辑Silverlight项目文件.csproj,可以在我们新建的Build Tag下面添加一项 SupportedCultures配置,并指定一种语言文化:

现在我们在Web测试项目中,配置一下xap文件的输出,只需要点击Change按钮就可以了,使 Configuration Specific Folders变为Yes,如下图所示:

这样可以我们通过修改Build Tag,来实现在Web测试项目中同时输出多个xap文件,而这些xap文件将 支持不同的语言,并且不会互相覆盖,如下图所示:

这样我们就可以用一个Silverlight项目来输出支持不同的语言文化的xap文件。

总结

篇3:Silverlight 2中实现Deep Zoom

概述

对于Deep Zoom想必大家都已经不陌生了,在Silverlight 2 Beta 1时已经提供了支持,并且提供了相 应的工具Deep Zoom Composer,Silverlight 2 Beta 2中对于Deep Zoom又有了很大的改进,现在支持基 于XML的DeepZoom集合的Manifest文件,Beta2还对DeepZoom加了可扩展的MultiScaleTileSource支持,更 新之后的Deep Zoom Composer可以使我们不用编写一行代码直接可视化的生成Deep Zoom应用。

在开始之前,请先确保安装了如下工具:

1.Silverlight Tools Beta 2 for Visual Studio

2.Deep Zoom Composer

总体来说,利用Deep Zoom Composer实现Deep Zoom应用分为如下三个步骤:导入、组合、导出。这三 个步骤在打开Deep Zoom Composer之后可以看到:

导入

第一步导入图片,可以点击“Add Image”按钮,一次选择想要导入的图片,如下图所示:

导入图片后效果如下图所示:

组合

经过了第一步导入图片后,我们可以对图片进行组合,选择需要加入到Deep Zoom应用中的图片,并调 整其位置及大小,如果在第一步没有导入图片,同样可以通过“Add Image”按钮来导入,

如下图所示:

我们方便的对图片的布局等进行调整,如下图所示:

导出

在对图片组合完成后,我们可以进行导出操作,并设置一些导出规则,如应用的名称,导出的路径等 ,这里Deep Zoom Composer提供了一个非常方便的选项,我们可以直接导出图片及生成Silverlight项目 ,如下图所示:

效果

经过以上三步之后,就可以直接生成Deep Zoom应用了,不用编写一行代码,生成的Silverlight项目 结构如下:

可以直接打开DeepZoomProjectTestPage.html查看最终的效果,如下所示:

实际应用

新浪音乐在微软 4 月 14 日 “Silverlight 锋芒彰显” 发布会中展示了新浪音乐最新的乐库原型, 其中应用了 Silverlight 中的 Deep Zoom 技术。更详细的情形大家可以参考这篇文章中的视频:

新浪音乐地图之 Deep Zoom 应用

blogs.msdn.com/jijia/archive/2008/04/16/sina-musicmap-details.aspx

结束语

篇4:Silverlight实现A*寻径算法

建议在新窗口中查看:

www.dotnet.pp.ru/silverlight/SilverlightAStar.html

花了几天的时间研究A*算法,总算是搞出来了,放上来给大伙儿瞧瞧。

点击“StartPoint”指定开始点,点击“EndPoint”指定目标点。点击“Impediment”指定不可通过区域。

GridSize设置节点大小,节点越小,容器中的节点就越多,填好后点Set保存设置。

Clear清除所有。

StartFindPath 开始寻径

Completed Tim 显示寻径所耗时间。

Diagonals 设置是否可以斜着走。

自我感觉速度不错。

下面说说算法的大致流程

首先定义两个列表

private List

penedList = new List

; //开启列表

private List

colsedList = new List

(); //关闭列表

开启列表中存储待检测节点。关闭列表中存储已检测节点。

从开始点开始,拿到开始点周围4或8个方向的节点,把他们添加进开启列表中。

G等于当前节点的父节点加上10或者14,水平或垂直方向加10,对角线方向加14

H等于当前节点的X的差与目标的的X的差、Y与目标点Y的差的绝对值的和。

F = G + H。

把当前节点从开启列表中删除。并添加进关闭列表中。以“F”值为依据从小到大排序,把F值最小的节点拿出来,重复以上过程。

大致流程是这样的。细节方面已经有一篇文章写的非常详细,在此也没有必要赘述了。

传送门:data.gameres.com/message.asp?TopicID=25439

最后放上算法的代码,不多。直接以文本形式发出来算了。

PathFinder

using System;

using System.Net;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Documents;

using System.Windows.Ink;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Animation;

using System.Windows.Shapes;

using System.Collections.Generic;

namespace SilverlightAStar

{

public class PathNote

{

public int F; //F = G + H

public int G;

public int H;

public int X;

public int Y;

public PathNote parentNote;

}

public class PathFinder

{

///

/// 矩阵

///

private byte[,] matrix;

///

/// 开始点

///

private Point startPoint;

///

/// 结束点

///

private Point endPoint;

///

/// 开启列表

///

private List

penedList = new List

(); //开启列表

///

/// 关闭列表

///

private List

colsedList = new List

(); //关闭列表

///

/// 是否允许斜线行走

///

private bool diagonals;

///

/// 方向

///

private sbyte[,] direction = new sbyte[8, 2] { { 0, -1 }, { 1, 0 }, { 0, 1 }, { -1, 0 }, { 1, -1 }, { 1, 1 }, { -1, 1 }, { -1, -1 } }; //默认方向

///

/// 构造函数

///

///

待检测矩阵

///

开始点

///

结束点

public PathFinder(byte[,] matrix, Point startPoint, Point endPoint)

{

this.matrix = matrix;

this.startPoint = startPoint;

this.endPoint = endPoint;

}

///

/// 构造 函数

///

///

矩阵

///

开始点

///

结束 点

///

是否允许斜线行走

public PathFinder(byte[,] matrix, Point startPoint, Point endPoint, bool diagonals)

{

this.matrix = matrix;

this.startPoint = startPoint;

this.endPoint = endPoint;

this.diagonals = diagonals;

if (! diagonals)

{

direction = new sbyte[4, 2] { { 0, -1 }, { 0, 1 }, { -1, 0 }, { 1, 0 } }; //不允许穿角,4方向

}

}

///

/// 开始寻找路径

///

///

public List

StartFindPath()

{

var found = false;

var pathNote = new PathNote() { F = 0, G = 0, H = 0, X = (int)startPoint.X, Y = (int)startPoint.Y, parentNote = null };

List

resultPoints = null;

while (true)

{

for (int i = 0; i < (diagonals ? 8 : 4); i++) //找到pathNote四方向或八方向周围节点,取F值最小的那个继续此过程

{

var x = pathNote.X + direction[i, 0];

var y = pathNote.Y + direction[i, 1];

if (x < 0 || y < 0 || x >matrix.GetUpperBound(0) || y >matrix.GetUpperBound(1)) //坐标过界

continue;

var newPathNote = new PathNote();

newPathNote.parentNote = pathNote;

newPathNote.X = x;

newPathNote.Y = y;

bool isClosed = false;

bool isOpened = false;

PathNote theOpendandSameNote = null;

foreach (var closedNote in colsedList)

{

if (closedNote.X == newPathNote.X && closedNote.Y == newPathNote.Y)

{

isClosed = true; //节点已经在关闭列表中

}

}

foreach (var openedNote in openedList)

{

if (openedNote.X == newPathNote.X && openedNote.Y == newPathNote.Y)

{

isOpened = true; //节点已经在开启列 表中,稍后比较两条路径

theOpendandSameNote = openedNote;

}

}

if (matrix[newPathNote.X, newPathNote.Y] != 0 || isClosed) //不能通行或者已经在关闭列表中存在

continue;

if (Math.Abs(direction[i, 0] + direction[i, 1]) == 2) //G值

{

newPathNote.G = newPathNote.parentNote.G + 14;

}

else

{

newPathNote.G = newPathNote.parentNote.G + 10;

}

newPathNote.H = (int)(Math.Abs(endPoint.X - newPathNote.X) + Math.Abs(endPoint.Y - newPathNote.Y)) * 10; //H值

newPathNote.F = newPathNote.G + newPathNote.H; //F值

if (isOpened) //比较已在开启列表中的节点G值和准备创建的节点G值

{

if (newPathNote.G >= theOpendandSameNote.G)

{

this.openedList.Remove(pathNote);

continue;

}

else

{

this.openedList.Remove (theOpendandSameNote);

this.openedList.Add(newPathNote);

continue;

}

}

this.openedList.Add(newPathNote); // 创建节点(添加进开启列表)

}

this.colsedList.Add (pathNote); //把当前节点放进关闭列表

this.openedList.Remove(pathNote); //从开启列表移除 当前节点

foreach (var openedNote in openedList)

{

if (openedNote.X == (int)endPoint.X && openedNote.Y == (int)endPoint.Y) // 到达终点

{

resultPoints = GetPointListByParent(openedNote, null); //得到以Point构成的路径

found = true;

break;

}

}

if (found)

{

break;

}

else

{

if (openedList.Count == 0) //找不到路径

{

break;

}

else

{

openedList.Sort(Compare);

pathNote = openedList[0];

}

}

}

return resultPoints;

}

///

/// 组织传入的PathNote的所有父节点为List

///

///

PathNote

///

列表

/// 路径

private List

GetPointListByParent (PathNote pathNote, List

pathPoints)

{

if (pathPoints == null)

pathPoints = new List

();

if (pathNote.parentNote != null)

{

pathPoints.Add(new Point (pathNote.parentNote.X, pathNote.parentNote.Y));

GetPointListByParent (pathNote.parentNote, pathPoints);

}

return pathPoints;

}

///

/// 比较两个节点的F值

///

///

第一个节点

///

第二个节点

///

private int Compare(PathNote x, PathNote y)

{

if (x.F >y.F)

return 1;

else if (x.F < y.F)

return -1;

return 0;

}

}

}

篇5:Silverlight数据绑定:怎样实现数据绑定

一个数据绑定可以通过 Binding 对象来描述,其中包含数据源,要绑定的属性路径(Path),目标,目 标属性等,

其中目标属性必须是依赖属性(DependencyProperty)。

为了说明方便,首先定义一个数据类:

public class Person

{

public int Age { get; set; }

public string Name { get; set; }

}

例子1:

public partial class Page : UserControl

{

public Page()

{

InitializeComponent();

var persons = new List

();

for(var i=0; i< 5; i++)

{

persons.Add(new Person {Name = “Person ” + i.ToString(), Age = 20 + i});

}

list1.DataContext = persons;

}

}

这里仅指定了 list1 的 DataContext 属性 ,运行后发现页面没有显示。

如果在页面里改一改:

会发现绑定成功。但是数据项显示为默认的 Person 对象 ToString() 后的表示,不太友好。如下图 :

或者,也可以将后台代码改成:

list1.ItemsSource = persons;

而页面 markup 仍然是:

这样也能绑定成功。

这里的原因在于:ListBox 通过 ItemsSource 里的数据去填充数据项,所以直接给这个属性赋值是可 以的。

或者,通过空绑定语法 {Binding},指定 ItemsSource 属性绑定为数据源的对象本身(未指定绑定路 径)。而数据源就是通过 DataContext 获得的,并且这个属性的数据可以从父对象继承下来。

下面给 ListBox 指定列表项的数据模板,让它显示的好看一点:

显示如下:

还可以将 DataTemplate 定义到 App 的 Resource 里去,以便于重用,

App.xaml:

xmlns:x=“schemas.microsoft.com/winfx/2006/xaml”

x:Class=“SilverlightTestApp.App”

>

Page.xaml:

xmlns=“schemas.microsoft.com/winfx/2006/xaml/presentation”

xmlns:x=“schemas.microsoft.com/winfx/2006/xaml”

Width=“400” Height=“300”>

运行后效果一样。

【Silverlight开发中的疑难杂症:如何实现一个EditorBox】相关文章:

1.Word中如何实现小数点对齐

2.dede中实现文章正文添加广告 .

3.用python实现的可以拷贝或剪切一个文件列表中的所有文件

4.现代化视野中自我价值实现分析

5.园林绿化中建筑节能的实现策略论文

6.在线教育中多元智能的开发与培养

7.商业地产开发中的环境设计分析论文

8.略谈在开发农村作文题材中育人

9.紫阳县矿产资源开发中环境保护情况的调查报告

10.成长中的一个小脚印作文

下载word文档
《Silverlight开发中的疑难杂症:如何实现一个EditorBox.doc》
将本文的Word文档下载到电脑,方便收藏和打印
推荐度: 评级1星 评级2星 评级3星 评级4星 评级5星
点击下载文档

文档为doc格式

  • 返回顶部