WPF实现新手引导
1. 半透明灰的遮罩层
- 新建一个遮盖的window窗体
- canvas是后期可以在思显示高亮区域
//定义一个window将它的样式设置透明等可以覆盖到其他窗体上,其中遮罩层使用border控件
//原因
//1. 支持圆角和方向可以适应不同的窗体样式 2. 支持阴影效果
2. 汽包的设置
- 建一个"自定义控件(UserControl)"设置自定义汽包样式
- 规划好样式设置
点击查看代码
3. 汽包出现的位置
- 通过TransformToAncestor方法拿到控件坐标之后从左上角(0,0)点的位置在带入控件的宽高计算出起点的坐标
点击查看代码
//汽包应该显示在那个位置 public void StartGuide(GuideModel guide) { //这个是拿到自定义控件 var focusElemt = guide.UserControl; var window = Window.GetWindow(focusElemt); var point = focusElemt.TransformToAncestor(window).Transform(new Point(0, 0)); var rectangleGeometry = new RectangleGeometry(); rectangleGeometry.Rect = new Rect(0, 0, this.Width, this.Height); borderGeometry = Geometry.Combine(borderGeometry, rectangleGeometry, GeometryCombineMode.Union, null); var rectangleGeometry1 = new RectangleGeometry(); //自适应一下 rectangleGeometry1.Rect = new Rect(point.X - 5, point.Y - 5, focusElemt.ActualWidth + 10, focusElemt.ActualHeight + 10); rectangleGeometry1.RadiusX = 5; rectangleGeometry1.RadiusY = 5; borderGeometry = Geometry.Combine(borderGeometry, rectangleGeometry1, GeometryCombineMode.Exclude, null); border.Clip = borderGeometry; //将初始化完的汽包传进来 InitHintControl(guide, point); //实现步骤的一个累加 currentStep++; }
初始化汽包
new一个新的对象传入自定义控件“Steptip”以及传入对应的参数
private async void InitHintControl(GuideModel guideModel, Point point) {
//传入对应的参数
stepTip = new StepTip(guideModel.ArrowDirection, guideModel.TipText, guideModel.ButtonContent, guideModel.Step, guideModel.TotalStep);
//这个是解决“步骤引导”每个都从左上角(0,0)开始寻找 这个是让它寻找完后再显示出来
stepTip.Visibility = Visibility.Hidden;
stepTip.OnNext += StepTip_OnNext;
stepTip.OnClosed += StepTip_OnClosed;
canvas.Children.Add(stepTip);
//防止未生成
await Task.Delay(50);
//对自定义控件每个方向的确定 寻找以及位置的显示的高亮区域
switch (guideModel.ArrowDirection) {
case StepTip.Direction.Top:
Canvas.SetLeft(stepTip, point.X + 5 - ((stepTip.ActualWidth - guideModel.UserControl.ActualWidth) / 2));
Canvas.SetTop(stepTip, point.Y + 5 + guideModel.UserControl.ActualHeight);
break;
case StepTip.Direction.Bottom:
Canvas.SetLeft(stepTip, point.X + ((guideModel.UserControl.ActualWidth - stepTip.ActualWidth) / 2));
Canvas.SetBottom(stepTip, this.ActualHeight - point.Y + 5);
break;
case StepTip.Direction.Left:
Canvas.SetLeft(stepTip, point.X + 5 + guideModel.UserControl.ActualWidth);
Canvas.SetTop(stepTip, point.Y + 5 + ((guideModel.UserControl.ActualHeight - stepTip.ActualHeight) / 2));
break;
case StepTip.Direction.Right:
Canvas.SetLeft(stepTip, point.X-5 - stepTip.ActualWidth);
Canvas.SetTop(stepTip, point.Y + 5 + ((guideModel.UserControl.ActualHeight - stepTip.ActualHeight) / 2));
break;
default:
break;
}
stepTip.Visibility = Visibility.Visible;
}
步骤的下一步进行与关闭操作
点击查看代码
private void StepTip_OnClosed() {
this.Close();
MainWindow.Instance.Activate();
}
private void StepTip_OnNext() {
if (guideWindows.Count == 0)
return;
var beforGuide = guideWindows[currentStep - 1];
if (guideWindows.Count == currentStep) {
EndStep();
return;
}
var currentGuide = guideWindows[currentStep];
if (beforGuide != null) {
canvas.Children.Clear();
}
if (currentGuide != null) {
StartGuide(currentGuide);
}
}
实行如何找到要提示的内容
- 在要执行的页面建一个“Loaded”事件
- 初始化InitGuideWindow();
点击查看代码
private void EditPage_Loaded(object sender, RoutedEventArgs e) { InitGuideWindow(); } private void InitGuideWindow() { var allGuide = new List
(); allGuide.AddRange(InitWelecome()); var akkGuides = allGuide.OrderBy(i => i.Step).ToList(); guideWindow = new GuideWindow(MainWindow.Instance, akkGuides); guideWindow.Owner = MainWindow.Instance; guideWindow.ShowDialog(); } } //寻找控件 List InitWelecome() { var lstWelecome = new List (); var findCtrl = ControlHelper.FindControl ("optionPanel", optionGrid); var createModel = new GuideModel() { Step = 1, TipText = LangEx.Get("MoreFeatures"), UserControl = findCtrl, ArrowDirection = Controls.StepTip.Direction.Left, TotalStep = 3, ButtonContent = LangEx.Get("Know") }; lstWelecome.Add(createModel); var findCtrl1 = ControlHelper.FindControl