wpf图形设计器-续

举报
Amrf 发表于 2019/12/18 14:51:54 2019/12/18
【摘要】 前面一篇关于wpf设计器的文章的后续,(https://bbs.huaweicloud.com/blogs/123716)为了使我们的设计器开启后能够自动加载保存的特定xml图形文件,可以在主窗口加载后关闭上挂载函数:Loaded="Window_Loaded"Closing="Window_Closing"private void Window_Loaded(object sender, ...

前面一篇关于wpf设计器的文章的后续,(https://bbs.huaweicloud.com/blogs/123716)

  • 为了使我们的设计器开启后能够自动加载保存的特定xml图形文件,可以在主窗口加载后关闭上挂载函数:

Loaded="Window_Loaded"
Closing="Window_Closing"
private void Window_Loaded(object sender, RoutedEventArgs e)
{
    var designer = (DesignerCanvas)this.FindName("MyDesigner");
    DesignerCanvas.InitView.Execute(null, designer);
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
    var designer = (DesignerCanvas)this.FindName("MyDesigner");
    DesignerCanvas.SaveView.Execute(null, designer);
}

相应的需要在DesignerCanvas.Commands.cs中添加两个RoutedCommand InitView和SaveView, 其实现分别对于原始的Open和Save,只不过其中的路径指定过程不再来自对话框中的用户选择,而来自参数;

  • ctrl+e切换工具栏显示状态

<RowDefinition Height="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=toolH}"/>
public int toolH
{
    get { return (int)this.GetValue(toolHProperty); }
    set { this.SetValue(toolHProperty, value); }
}
public static readonly DependencyProperty toolHProperty = DependencyProperty.Register("toolH", typeof(int), typeof(Window1), new PropertyMetadata(120));
private void Window_KeyUp(object sender, KeyEventArgs e){
    if (Keyboard.Modifiers == ModifierKeys.Control && e.Key == Key.E){
        if (toolH > 0){
            toolH = 0;
        }else{
            toolH = 120;
        }
    }
}
  • 隐藏GroupBox的头部

https://stackoverflow.com/questions/2110148/wpf-groupbox-with-no-header-space


Right click on GroupBox > Edit Template > Edit Copy > OK

备注:

需要注意的是,测试发现DesignerItem序列化后再次打开宽度和高度始终不变,

定位发现原来写测试代码绑定的时候p.Width写成了指定值,修改成如下代码后可以正常保存并还原宽高

Test1Property p  = (this.Parent as DesignerItem).property as Test1Property;

p.Text = "Test1";

p.Width = (this.Parent as DesignerItem).Width;

p.Height = (this.Parent as DesignerItem).Height;

/***************************************************************************************************/

DesignerCanvas多实例改造

  • 首先在window1中添加Tab,并在其TabItem中分别放入Designer

<TabControl Grid.Column="1" HorizontalAlignment="Stretch" Margin="0,0,0,0" VerticalAlignment="Stretch" SelectionChanged="TabControl_SelectionChanged">

  • 当tab切换时

TabControl_SelectionChanged中执行ClearSelection清除当前选择

  • 为DesignerCanvas添加配置文件地址属性,并在window1.xaml中传入

storePath="C:\\xxxx\\tt1.xml"//临时使用绝对地址

  • 改写Window_Loaded/Window_Closing

foreach (DesignerCanvas designer in UIChildFinder.GetLogicalChildCollection<DesignerCanvas>((((this.Content as Grid).Children[1] as Grid).Children[2] as TabControl)))

{

    DesignerCanvas.xxx.Execute(null, designer);

}

  • 修改windows中的MyDesigner_SelectionChanged提起RaisePropertyChanged

  • 为window1添加currentDesigner属性,并在TabControl_SelectionChanged中修改currentDesigner

TabItem selectedTab = e.AddedItems[0] as TabItem;

foreach (DesignerCanvas designer in UIChildFinder.GetLogicalChildCollection<DesignerCanvas>(selectedTab))

{

    currentDesigner = designer;

}

  • 修改ApplicationToolbar.xaml中所有涉及到MyDesigner的绑定

{Binding ElementName=MyDesigner}

=>

{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=currentDesigner}

/***************************************************************************************************************/

连接线Connection虚实线切换和序列化

  • 我们可以看到Connection.xaml中的绑定StrokeDashArray="{Binding StrokeDashArray}",为Connection增加一个defaultStrokeDashArray属性,并在构造函数中将默认值赋值给StrokeDashArray,增加toggleDash函数使default在实虚之间切换,并赋值给StrokeDashArray;

  • 为了方便测试切换我们再Connection.xaml中的ContextMenu中再增加一个菜单,并绑定到DesignerCanvas.ToggleDash命令,命令中调用toggleDash;

  • 上述步骤实现的虚实线的绑定和切换,但是修改并不会被序列化,需要在SerializeConnections和InitView_Executed中添defaultStrokeDashArray序列化、反序列化逻辑;

  • 当tab切换时Designer隐藏会触发Connection的Unload时间,导致后面Connection序列化过程异常,可以在Connection_Unloaded处理中添加this.Parent != null判断,区分到底是控件删除导致的Unload还是隐藏导致的;

/*******************************************************************************************************/

移除连接线阴影效果,Canvas.BitmapEffect

/*******************************************************************************************************/

DependencyProperty的默认值会使的多个实例共用一个属性对象,从而导致从xml中序列化时出现问题,需要在构造函数中各自设置各自的初值属性对象;

参考:

https://mlog.club/article/2741844

https://www.skcircle.com/%3Fid%3D728

https://cloud.tencent.com/developer/article/1200300

https://www.cnblogs.com/zlgcool/archive/2008/06/19/1225952.html


【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。