DevExpress DashBoard 添加自定义组件(Web浏览器)

自定义Dashbarod组件

最近由于项目需要,需要在原有DevExpress DashBoard配置的基础上提高可配置元素,研究一下DashBoard源码,总结出了一个可以实践的方法。

自定义Winform 设计器组件

首先我们需要顶一个组件模型和组件的数据模型:WebDashBoardItemWebDashBoardViewModel。这两个类我们在设计器以及viewer中都会用到,用来识别组件类型以及传递数据。
然后我们组件的可视化控件WebDashBoardItemViewer,这个用于设计器以及WinForm的viewer中。下面我们从操作流程来说:

  1. InsertWebCommand ,创建自定义组件,通过创建该命令来执行创建组件操作;
  2. EditUrlCommand ,编辑自定义组件,通过创建该命令来执行组件数据或配置的编辑操作;
  3. 我们需要在设计器界面人为添加两个菜单按钮,用于执行创建和编辑操作。
  4. 自定义新的设计器用于承载自定义的命令以及组件MyDashBoardDesigner
新增命令InsertWebCommand
public class InsertWebCommand: InsertItemCommand<WebDashBoardItem>
    {
        public InsertWebCommand(DashboardDesigner control) : base(control) { }
        public override DashboardCommandId Id
        {
            get
            {
                return new DashboardCommandId(19909);
            }
        }

        public override DashboardWinStringId MenuCaptionStringId
        {
            get
            {
                return DashboardWinStringId.AddDashboardParameter;
            }
        }

        public override DashboardWinStringId DescriptionStringId
        {
            get
            {
                return DashboardWinStringId.AddDashboardParameter;
            }
        }

        protected override DashboardStringId DefaultNameId
        {
            get
            {
                return DashboardStringId.CustomItems;
            }
        }
    } 
}
编辑命令EditUrlCommand
public class EditUrlCommand: DashboardItemCommand<WebDashBoardItem>
    {
        public override DashboardCommandId Id { get { return new DashboardCommandId(9999); } }
        public override DashboardWinStringId MenuCaptionStringId { get { return DashboardWinStringId.CommandImageLoadCaption; } }
        public override DashboardWinStringId DescriptionStringId { get { return DashboardWinStringId.CommandImageLoadDescription; } }
        public override string ImageName { get { return "ImageLoad"; } }
        public EditUrlCommand(DashboardDesigner control) : base(control)
        {
        }

        protected override void ExecuteInternal(ICommandUIState state)
        {
            using (UrlEditor dialog = new UrlEditor(base.DashboardItem))
            {
                if(dialog.ShowDialog() == DialogResult.OK)
                {
                    WebUrlHistoryItem historyItem = GetHistoryItem(DashboardItem, dialog.Url);
                    if (historyItem != null)
                    {
                        historyItem.Redo(Control);
                    }
                }
            }
        }

        private WebUrlHistoryItem GetHistoryItem(WebDashBoardItem dashBoardItem,string url)
        {
            WebUrlHistoryItem urlHistoryItem = new WebUrlHistoryItem(dashBoardItem, url);
            return urlHistoryItem;
        }
    }

    public class WebUrlHistoryItem : DashboardItemHistoryItem<WebDashBoardItem>
    {
        private WebDashBoardItem prev;
        private string next;
        protected override DashboardWinStringId CaptionId { get { return DashboardWinStringId.HistoryItemImageOpen; } }
        public WebUrlHistoryItem(WebDashBoardItem dashboardItem, string uri) : base(dashboardItem)
        {
            prev = dashboardItem;
            next = uri;
        }
        protected override void PerformUndo()
        {
            (base.DashboardItem as WebDashBoardItem).Url = prev.Url;
        }
        protected override void PerformRedo()
        {
            (base.DashboardItem as WebDashBoardItem).Url = next;
        }
    }
自定义设计器MyDashBoardDesigner
public class MyDashBoardDesigner : DashboardDesigner
    {
        public MyDashBoardDesigner() : base()
        {
            base.AddCommand(new DashboardCommandId(9999), typeof(EditUrlCommand));
            base.AddCommand(new DashboardCommandId(10000), typeof(InsertWebCommand));
        }
    }

下面就是组件相关控件以及模型

可视化控件 WebDashBoardItemViewer
[DXToolboxItem(false)]
    public class WebDashBoardItemViewer : DashboardItemViewer
    {
        readonly WebBrowser web = new WebBrowser();
        protected override Control GetUnderlyingControl()
        {
            return web;
        }
        protected override void PrepareViewControl()
        {
            
        }
        protected override void UpdateViewer()
        {
            base.UpdateViewer();
            WebDashBoardViewModel vm = ViewModel as WebDashBoardViewModel;
            web.Navigate(vm.url);
        }
        public WebDashBoardItemViewer() : base()
        {
        }
       
        private void OnControlMouseWheel(object sender, MouseEventArgs e)
        {
            RaiseMouseWheel();
        }
        private void OnControlMouseHover(object sender, EventArgs e)
        {
            RaiseMouseHover();
        }
        private void OnControlMouseUp(object sender, MouseEventArgs e)
        {
            RaiseMouseUp(e.Location);
        }
        private void OnControlMouseDown(object sender, MouseEventArgs e)
        {
            RaiseMouseDown(e.Location);
        }
        private void OnControlMouseLeave(object sender, EventArgs e)
        {
            RaiseMouseLeave();
        }
        private void OnControlMouseEnter(object sender, EventArgs e)
        {
            RaiseMouseEnter();
        }
        private void OnControlMouseMove(object sender, MouseEventArgs e)
        {
            RaiseMouseMove(e.Location);
        }
        private void OnControlMouseDoubleClick(object sender, MouseEventArgs e)
        {
            RaiseDoubleClick(e.Location);
        }
        private void OnControlMouseClick(object sender, MouseEventArgs e)
        {
            RaiseClick(e.Location);
        }

        protected override Control CreateViewControl()
        {
            return web;
        }

        protected override void PrepareClientState(ItemViewerClientState state)
        {
            state.ViewerArea = GetControlClientArea(web);
        }
    }

组件模型 WebDashBoardItem
[DashboardItemType("Web")]
    public class WebDashBoardItem : DashboardItem
    {
        public string url = "https://www.baidu.com/";
        protected override string CaptionPrefix
        {
            get
            {
                return "Web";
            }
        }

        protected override DashboardItemViewModel CreateViewModel()
        {
            return new WebDashBoardViewModel(this);
        }

        [DefaultValue("https://www.baidu.com/")]
        public string Url
        {
            get { return url; }
            set
            {
                if (url != value)
                {
                    url = value;
                    base.OnChanged(ChangeReason.View, this, null);
                }
            }
        }

        protected override void SaveToXml(XElement element)
        {
            base.SaveToXml(element);
            element.Add(new XAttribute("url", url));
        }

        protected override XElement SaveToXml()
        {
            return base.SaveToXml();
        }

        protected override void LoadFromXmlInternal(XElement element)
        {
            base.LoadFromXmlInternal(element);
            this.Url = element.GetAttributeValue("url");
        }
    }

组件数据模型 WebDashBoardViewModel
public class WebDashBoardViewModel : DashboardItemViewModel
    {
        public string url { get; set; }
        public WebDashBoardViewModel() : base()
        { }

        public WebDashBoardViewModel(WebDashBoardItem item) : base(item)
        {
            url = item.Url;
        }
    }


自定义WPF显示组件

首先我们先顶一个组件样式模板 WebItemThemeKeyExtension,用于识别可视化组件的控件模板以及样式。
然后我们需要基于WPF渲染加载组件模板机制,重新自定义一套新的渲染模板。

WPF 自定义设计器及相关类
[DXToolboxBrowsable]
    public class MyDashBoardControl : DashboardControl
    {
        protected override BaseDashboardViewModelXpf CreateDashboardViewModel(Dashboard dashboard)
        {
            return ViewModelSource.Create(() => new MyDashboardViewModelXpf(new XPFService(this, this, Dashboard)) { AllowPrintDashboardItems = AllowPrintDashboardItems });
        }
    }

    public class MyDashboardViewModelXpf: BaseDashboardViewModelXpf
    {
        public MyDashboardViewModelXpf(XPFService dataService) : base(dataService)
        {
            
        }

        protected override IDashboardItemViewModelXpf CreateViewModel(string itemName)
        {
            BaseDashboardItemViewModelXpf viewModelXpf;
            XpfItemModel itemModel = XpfDataService.GetItemModel(itemName);
            switch (itemModel.ItemType)
            {
                case "Web":
                    viewModelXpf = ViewModelSource.Create(() => new WebItemViewModelXpf(this, itemName));
                    break;
                default:
                    viewModelXpf = new CustomItemViewModelXpf(this, itemName);
                    break;
            }
            return viewModelXpf;
        }
    }
	……
    public class WebItemViewModelXpf : BaseDashboardItemViewModelXpf
    {
        public WebItemViewModelXpf(object parent, string itemName)
            : base(parent, itemName)
        {
        }

        WebDashBoardViewModel ViewModel { get { return (WebDashBoardViewModel)ItemViewModel; } }

        public override DevExpress.DashboardXpf.DashboardItemType ItemType
        {
            get
            {
                return DevExpress.DashboardXpf.DashboardItemType.Custom;
            }
        }

        public string Url
        {
            get
            {
                return ViewModel.url;
            }
        }

        public override DevExpress.DashboardXpf.DashboardLayoutItem CreateLayoutItem()
        {
            return new WebDashboardLayoutItem();
        }
    }

WPF 样式文件
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:dxdash="http://schemas.devexpress.com/winfx/2008/xaml/dashboard"
                    xmlns:dxdashi="clr-namespace:DevExpress.DashboardXpf.Internal;assembly=DevExpress.Xpf.Dashboard.v17.2"  xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm">
    <Style x:Key="webBrowserStyle" TargetType="{x:Type chrome:ChromiumWebBrowser}">
        <Setter Property="Address" Value="{Binding Url}" />
    </Style>

    <DataTemplate x:Key="webBrowserTemplate">
        <chrome:ChromiumWebBrowser Style="{Binding Path=(dxdash:DashboardLayoutItem.ViewStyle), RelativeSource={RelativeSource TemplatedParent}}"/>
    </DataTemplate>
    <Style x:Key="sddd" TargetType="{x:Type mydash:WebDashboardLayoutItem}" BasedOn="{StaticResource ResourceKey={x:Type dxdash:DashboardLayoutItem}}">
        <Setter Property="ContentTemplate" Value="{StaticResource webBrowserTemplate}"/>
        <Setter Property="ViewStyle" Value="{StaticResource webBrowserStyle}"/>
    </Style>
   ……
</ResourceDictionary>

以上参考DevExpress 17.2源码完成

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值