首页 新闻 会员 周边

c#如何实现站场图

0
悬赏园豆:20 [待解决问题]

c#通过读取xml配置环境,实现站场形式,且可以在图上添加按钮。

c#
天明宝的主页 天明宝 | 初学一级 | 园豆:170
提问于:2020-11-30 15:23
< >
分享
所有回答(2)
0

自己画图,灵活性高,事件也自定义

jqw2009 | 园豆:2439 (老鸟四级) | 2020-11-30 16:45
0

这是画布,其他的自己补:

namespace L.Bussiness.画布图元s
{
    public class CanvasForPrimitives : Canvas, IPrimitiveContainer
    {
        public CanvasForPrimitives CurrentRootCanvas { get; set; }
        public bool IsRoot => ReferenceEquals(this, CurrentRootCanvas);
        public PropertyGridEx PropertyGrid { get; private set; }

        public CanvasForPrimitives()
        {
            PropertyGrid = MainWindow.PropertyGrid;
            CurrentRootCanvas = this;
            AllowDrop = true;
            ClipToBounds = true;
            Focusable = true;
            Scale = 1d;
            this.LayoutTransform = _scaleTransform;

            if (IsRoot)
            {
                WidthEx = 800;
                HeightEx = 600;
            }
        }

        [Filed]
        [Category("1.基本属性")]
        [DisplayName("宽度")]
        [Description("尺寸.")]
        public virtual double WidthEx { get => base.Width; set => base.Width = value < MinWidth ? base.Width : value; }

        [Filed]
        [Category("1.基本属性")]
        [DisplayName("高度")]
        [Description("尺寸.")]
        public virtual double HeightEx { get => base.Height; set => base.Height = value < MinHeight ? base.Height : value; }

        private readonly ScaleTransform _scaleTransform = new ScaleTransform();
        public double Scale
        {
            get => _scaleTransform.ScaleX;
            set
            {
                if(value<0d)return;
                var minDistance = Math.Min(ActualHeight, ActualWidth) * value;
                if(minDistance < 40 || value>50d)return;
                _scaleTransform.ScaleX = _scaleTransform.ScaleY = value;
                _scaleTransform.CenterX = ActualWidth / 2;
                _scaleTransform.CenterY = ActualHeight / 2;
                LayoutTransform = _scaleTransform;
            }
        }

        public double ScaleTick { get; set; } = 0.05d;
        protected override void OnMouseWheel(MouseWheelEventArgs e)
        {
            base.OnMouseWheel(e);

            if (Keyboard.IsKeyDown(Key.LeftCtrl))
            {
                if (!IsRoot) return;
                if (e.Delta < 0) Scale -= ScaleTick;
                else Scale += ScaleTick;
            }
        }

        [Filed]
        public virtual IList Primitives
        {
            get => base.Children;
            set
            {
                if(value == null || value.Count<1) return;//{base.Children.Clear();return;}
                value.OfType<PrimitiveBase>().ToList().ForEach(t=>InsertPrimitive(t));
            }
        }


        private PrimitiveBase _primitiveLastSelect;//暂时还没用
        /// <summary>
        /// 除设置Children(反序列化)使用,所有Primitive的添加应该从此处
        /// </summary>
        /// <param name="primitive"></param>
        /// <param name="index">默认-1添加到尾部</param>
        public virtual void InsertPrimitive(PrimitiveBase primitive,int index=-1)
        {
            if(index<-1 || index>=Primitives.Count)throw new IndexOutOfRangeException("Invalidate index for the Canvas.");
            if(primitive==null)return;
            primitive.WhenSelected = sender =>
            {
                //_primitiveLastSelect?.IsSelected
                //安全起见,把除自己的状态UnSelected一下,并通知设置面板
                this.CurrentRootCanvas.GetAllPrimitives().Where(t => t != sender).ToList().ForEach(t => t.ForceUnselect());
                if (CurrentRootCanvas.PropertyGrid != null) CurrentRootCanvas.PropertyGrid.SelectedObject = primitive;
                _primitiveLastSelect = sender;
            };

            if (index < 0) base.Children.Add(primitive);
            else base.Children.Insert(index,primitive);

            //告诉当前节点Canvas是谁,如果当前节点是Container,需要告诉所有子元素Canvas是谁
            primitive.CurrentRootCanvas = this;
            primitive.AsType<PrimitiveAndContainerBasic>()?.GetAllPrimitives().ForEach(t=>t.CurrentRootCanvas = this);
        }

        protected override void OnDrop(DragEventArgs e)
        {
            base.OnDrop(e);
            this.DoOnDrop(e);
        }

        public string Save(string filePath)
        {
            var content = this.ToJsonString(new JsonSerializerSettings()
            {
                TypeNameHandling = TypeNameHandling.All,
                ContractResolver = new LimitPrimitivePropertyContractResolver()
            });
            System.IO.File.WriteAllText(filePath,content);
            return content;
        }

        public static CanvasForPrimitives OpenCreate(string filePath)
        {
            try
            {
                var content = System.IO.File.ReadAllText(filePath);
                var bean = content.ToEntityFromJsonString<CanvasForPrimitives>(new JsonSerializerSettings()
                {
                    TypeNameHandling = TypeNameHandling.All,
                    ContractResolver = new LimitPrimitivePropertyContractResolver()
                });

                ReDoOnCreatedByFile(bean);
                return bean;
            }
            catch (Exception e)
            {
                Loger.Log.Error(e);
                throw e;
            }
        }

        static void ReDoOnCreatedByFile(IPrimitiveContainer primitiveContainer)
        {
            var items = primitiveContainer.Primitives.OfType<PrimitiveBase>().ToList();
            primitiveContainer.Primitives.Clear();
            items.ForEach(t =>
            {
                primitiveContainer.InsertPrimitive(t);
                if(t is IPrimitiveContainer) ReDoOnCreatedByFile(t.AsType<IPrimitiveContainer>());
            });
        }
    }
}
花飘水流兮 | 园豆:13560 (专家六级) | 2020-12-01 09:52
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册