using BPASmartClient.Compiler; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Markup; using System.Windows.Threading; using System.Xml; namespace BPASmartClient.SCADAControl.CustomerControls { /// /// TheListBox.xaml 的交互逻辑 /// public partial class TheListBox :ListBox, IExecutable, IDisposable { public event EventHandler PropertyChange; //声明一个事件 public TheListBox() { InitializeComponent(); ResourceDictionary languageResDic = new ResourceDictionary(); languageResDic.Source = new Uri(@"/BPASmartClient.SCADAControl;component/Themes/Generic.xaml",UriKind.RelativeOrAbsolute); this.Resources.MergedDictionaries.Add(languageResDic); EditorHelper.Register(); Width = 100; Height = 100; } #region 属性 [Category("控件数据集合")] private ObservableCollection ItemsString { get { return (ObservableCollection)GetValue(ItemsStringProperty); } set { SetValue(ItemsStringProperty, value); } } private static readonly DependencyProperty ItemsStringProperty = DependencyProperty.Register("ItemsString", typeof(ObservableCollection), typeof(TheListBox), new PropertyMetadata(new ObservableCollection())); [Category("子控件模板XML格式")] public string ChildTemplateXml { get { return (string)GetValue(ChildTemplateXmlProperty); } set { SetValue(ChildTemplateXmlProperty, value); } } public static readonly DependencyProperty ChildTemplateXmlProperty = DependencyProperty.Register("ChildTemplateXml", typeof(string), typeof(TheListBox), new PropertyMetadata(string.Empty,new PropertyChangedCallback(onChildTemplateXmlChanged))); private static void onChildTemplateXmlChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) => (d as TheListBox)?.XmlRefresh(); public void XmlRefresh() { ; } [Category("数据绑定-数据来源")] public DataTypeEnum DataSouceType { get { return (DataTypeEnum)GetValue(DataSouceTypeProperty); } set { SetValue(DataSouceTypeProperty, value); } } public static readonly DependencyProperty DataSouceTypeProperty = DependencyProperty.Register("DataSouceType", typeof(DataTypeEnum), typeof(TheListBox), new PropertyMetadata(DataTypeEnum.API接口)); [Category("数据绑定-数据来源")] public int TimeCount { get { return (int)GetValue(TimeCountProperty); } set { SetValue(TimeCountProperty, value); } } public static readonly DependencyProperty TimeCountProperty = DependencyProperty.Register("TimeCount", typeof(int), typeof(TheListBox), new PropertyMetadata(500)); [Category("数据绑定-数据来源")] public string DataSouceInformation { get { return (string)GetValue(DataSouceInformationProperty); } set { SetValue(DataSouceInformationProperty, value); } } public static readonly DependencyProperty DataSouceInformationProperty = DependencyProperty.Register("DataSouceInformation", typeof(string), typeof(TheListBox), new PropertyMetadata("api0")); [Category("数据绑定")] public string FDataSouce { get { return (string)GetValue(FDataSouceProperty); } set { SetValue(FDataSouceProperty, value); } } public static readonly DependencyProperty FDataSouceProperty = DependencyProperty.Register("FDataSouce", typeof(string), typeof(TheListBox), new PropertyMetadata(string.Empty, new PropertyChangedCallback(onFDataSouceChanged))); private static void onFDataSouceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) => (d as TheListBox)?.DataSouceRefresh(); public void DataSouceRefresh() { try { GenerateData = (string)CSharpConfig.GetInstance().RunCSharp(Code, new object[] { FDataSouce }); if (PropertyChange != null) { PropertyChange(this, null); } } catch (Exception ex) { } } public static string _code = "public string main(string message) \n{ \n //请在此填写你的代码\n\n return message; \n}\n"; [Category("数据绑定")] public string Code { get { return (string)GetValue(CodeProperty); } set { SetValue(CodeProperty, value); } } public static readonly DependencyProperty CodeProperty = DependencyProperty.Register("Code", typeof(string), typeof(TheListBox), new PropertyMetadata(_code)); [Category("数据绑定")] public string GenerateData { get { return (string)GetValue(GenerateDataProperty); } set { SetValue(GenerateDataProperty, value); } } public static readonly DependencyProperty GenerateDataProperty = DependencyProperty.Register("GenerateData", typeof(string), typeof(TheListBox), new PropertyMetadata(string.Empty, new PropertyChangedCallback(onGenerateDataChanged))); private static void onGenerateDataChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) => (d as TheListBox)?.GenerateDataRefresh(); public void GenerateDataRefresh() { if (!string.IsNullOrEmpty(GenerateData) && GenerateData.Contains("data")) { try { Dictionary keys = JsonConvert.DeserializeObject>(GenerateData); ItemsString = JsonConvert.DeserializeObject>(keys["data"].ToString()); } catch (Exception ex) { } } else { //this.Items.Clear(); } } #endregion public string ControlType => "控件"; private bool isExecuteState; public bool IsExecuteState { get { return isExecuteState; } set { isExecuteState = value; if (IsExecuteState) { Register(); } } } DispatcherTimer timer = new DispatcherTimer(); /// /// 注册需要处理的事件 /// public void Register() { XmlToFrameworkElement(); if (DataSouceType == DataTypeEnum.API接口) { timer.Interval = TimeSpan.FromMilliseconds(TimeCount); timer.Tick += Timer_Tick; ; timer.Start(); } } /// /// 流转Xml /// /// public void FrameworkElementToXml(FrameworkElement framework) { StringBuilder outstr = new StringBuilder(); try { //this code need for right XML fomating XmlWriterSettings settings = new XmlWriterSettings { Indent = true, OmitXmlDeclaration = true }; var dsm = new XamlDesignerSerializationManager(XmlWriter.Create(outstr, settings)) { //this string need for turning on expression saving mode XamlWriterMode = XamlWriterMode.Expression }; XamlWriter.Save(framework, dsm); } catch (Exception ex) { } ChildTemplateXml = outstr.ToString(); } public void XmlToFrameworkElement() { var template = (DataTemplate)XamlReader.Parse(@" " + ChildTemplateXml + @" "); SetValue(ItemTemplateProperty, template); Binding binding = new Binding(); binding.RelativeSource = new RelativeSource() { Mode = RelativeSourceMode.Self }; binding.Path = new PropertyPath("ItemsString"); SetBinding(ItemsSourceProperty, binding); } public void Dispose() { timer.Stop(); FDataSouce = ""; GenerateDataRefresh(); } private void Timer_Tick(object? sender, EventArgs e) { if (!string.IsNullOrEmpty(DataSouceInformation)) { if (DataSouceType == DataTypeEnum.API接口) { if (Class_DataBus.GetInstance().Dic_APIData.ContainsKey(DataSouceInformation)) { FDataSouce = Class_DataBus.GetInstance().Dic_APIData[DataSouceInformation]; } } else if (DataSouceType == DataTypeEnum.Redis) { if (DataSouceInformation.Contains(".") && DataSouceInformation.Contains("{Binding ")) { string[] str = DataSouceInformation.Replace("{Binding ", "").Replace("}", "").Split("."); if (str.Length > 1) { if (Class_DataBus.GetInstance().Dic_RedisData.ContainsKey(str[0])) { Dictionary b = Class_DataBus.GetInstance().Dic_RedisData[str[0]]; if (b != null && b.ContainsKey(str[1])) FDataSouce = b[str[1]].ToString(); } } } } else if (DataSouceType == DataTypeEnum.静态数据) { FDataSouce = ""; } } } } internal class BindingConvertor : ExpressionConverter { public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { if (destinationType == typeof(MarkupExtension)) return true; else return false; } public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) { if (destinationType == typeof(MarkupExtension)) { BindingExpression bindingExpression = value as BindingExpression; if (bindingExpression == null) throw new Exception(); return bindingExpression.ParentBinding; } return base.ConvertTo(context, culture, value, destinationType); } } internal static class EditorHelper { public static void Register() { Attribute[] attr = new Attribute[1]; TypeConverterAttribute vConv = new TypeConverterAttribute(typeof(TC)); attr[0] = vConv; TypeDescriptor.AddAttributes(typeof(T), attr); } } }