devexpress sheduler control labelid 如何绑定到数据库

devexpress sheduler control labelid 如何绑定到数据库_第1张图片为什么我只用winform控件:

用devExpress控件,只要的原因是开发速度快。现在一般开发原形,后台用lightswitch,前端用devexpress来做。

这样,客户能在最短的时间,看到效果。然后再讨论,以确保数据模型,不会出太大的错误。


而尝试过许多之后,发现在方面,devExpress还是相当快的。WPF也试过,但我的机器,带不动。

效率永远是放在第一位的。无法忍受天天等着IDE启动吧?

所以,一直以来只用winForm.


今天,我们来说说如何解决sheduler control的一个缺陷。这个缺陷,比较严重,而且最新的版本14.1试过之后,发现仍然没有解决,而且,没有要解决的迹象。

也许是这家公司,正在向移动UI转型,没得工夫在winform上。


问题提出


devExpress 控件中,有一个控件,总的来说,做得还算是不错的:Scheduler control.

不过这个控件,有一个严重的缺陷:

许多信息,与label是绑定的。


这本身就不是很正确。风格应当与元素分离(的确有例表,展现了这方面的特点,但label相对简单得多)。

但用labelid来描述颜色,也并无不可。

可是问题在于,labelid本身是不存在的,是一个数组的下标。


这样一来,就给实现的程序员,带来的极大的麻烦。


如何实现label与数据库绑定


这个简单且重要的需求,devexpress并不支持。

而且,这个设计级别的错误,至少8年也没能得到解决。


看来,devexpress,最好还是用于快速开发为好。devexpress这种态度,实在是难以令人信服。


先列一下相关的文章

Obtain labels from a datasource like the resources

https://www.devexpress.com/Support/Center/Example/Details/E2028


还有这个,这里,前几天,去抱怨了一下(用我蹩脚的英文,关键是提交了就不能改)。后来我自己想了个办法解决了,今天想起来,就把这些事写一写。

Labels must have arbritrary indexes

https://www.devexpress.com/Support/Center/Question/Details/S137108#answer-037dbb2a-cade-4dee-beec-714c5ff3d7d3


关键的一个错误是,界面是以index为准,而数据库的条目则可能被删减,这显然是无法完成任务的。


我的解决办法

原理


这里,我的解决办法是,建两个map,一个从index 到uid,一个相反。

然后,初始化时,以数据库里的信息来装载。

当用户需要改变时,在弹出的对话框前,对数据做点手脚,这样看起来就一直对了。


代码


declare two map:

        int[] arLabelToWorkTypeId ;
        Dictionary<int, int> mapWorktypeId2LabelIndex=null;

load labes from database when from load:


private void Your_Load(object sender, EventArgs e)
        {


            // TODO: This line of code loads data into the 'schedulerDBDataSet.Resources' table. You can move, or remove it, as needed.
            this.resourcesTableAdapter.Fill(this.schedulerDBDataSet.Resources);
            // TODO: This line of code loads data into the 'schedulerDBDataSet.Appointments' table. You can move, or remove it, as needed.
            this.appointmentsTableAdapter.Fill(this.schedulerDBDataSet.Appointments);


            InitializeLabels();
            //////////////////////////////////////////////////////////////////////////
            schedulerControl.ActiveViewType = DevExpress.XtraScheduler.SchedulerViewType.Timeline;

            schedulerControl.GroupType = SchedulerGroupType.Resource;
            AdjustResourceHeaders();


            cbView.EditValue = schedulerControl.ActiveViewType;
            cbGrouping.EditValue = schedulerControl.GroupType;


        }

        private void InitializeLabels()
        {

            this.workTypeTableAdapter.Fill(this.schedulerDBDataSet.WorkType);
            DataTable labels = this.schedulerDBDataSet.WorkType;

            if (labels.Rows.Count == 0)
                return;
            schedulerControl.Storage.Appointments.Labels.Clear();

            schedulerControl.Storage.Appointments.Labels.BeginUpdate();
           arLabelToWorkTypeId  = new int[labels.Rows.Count];

           mapWorktypeId2LabelIndex = new Dictionary<int, int>();

            for (int i = 0; i < labels.Rows.Count; i++)
            {
                Color color = Color.FromArgb(Int32.Parse(labels.Rows[i]["Color"].ToString()));
                string dislayName = labels.Rows[i]["name"].ToString();
                string menuCaption = labels.Rows[i]["name"].ToString();
                AppointmentLabel aptLabel = new AppointmentLabel(color, dislayName, menuCaption);
                schedulerControl.Storage.Appointments.Labels.Add(aptLabel);
                arLabelToWorkTypeId[i] = int.Parse(labels.Rows[i]["WorktypeID"].ToString());
                mapWorktypeId2LabelIndex.Add(arLabelToWorkTypeId[i],i);
            }
            schedulerControl.Storage.Appointments.Labels.EndUpdate();
        }


private void schedulerControl_EditAppointmentFormShowing(object sender, AppointmentFormEventArgs e)
       {
           DevExpress.XtraScheduler.SchedulerControl scheduler = ((DevExpress.XtraScheduler.SchedulerControl)(sender));

           //appoint make a copy

           DevExpress.XtraScheduler.Appointment tmpAppointment = e.Appointment;
           //converty to worktype
           int originalId = tmpAppointment.LabelId;

           int labelIdx=0;

           if (true == mapWorktypeId2LabelIndex.TryGetValue(tmpAppointment.LabelId,out labelIdx))
           {
               tmpAppointment.LabelId = labelIdx;
           }

            DevExpress.XtraScheduler.Demos.Modules.CustomAppointmentForm form = new DevExpress.XtraScheduler.Demos.Modules.CustomAppointmentForm(scheduler, tmpAppointment, e.OpenRecurrenceForm);
           try
           {       
               e.DialogResult = form.ShowDialog();
               if (DialogResult.OK == e.DialogResult)
               {
 
                   e.Appointment.LabelId = arLabelToWorkTypeId[tmpAppointment.LabelId];
               }
               else
               {
                   e.Appointment.LabelId = originalId;
               }

               e.Handled = true;
           }
           finally
           {
               form.Dispose();
           }

       }

       //新生成一个
       private void schedulerControl_InitNewAppointment(object sender, AppointmentEventArgs e)
       {
           //赋到第一个值
           e.Appointment.LabelId = arLabelToWorkTypeId[0];

       }

=====================
后记
在我写完这个文章之后,在devexpress上面的回复,得到了回应:

  • Yulia (DevExpress Support) 14 hours ago

    Hi,
    Thank you for sharing your solution.

    In addition, I recommend that you review the How to provide the capability to bind appointment labels to a datasource example that illustrates how to accomplish this task at the SchedulerControl descendant level. The main idea of the approach described in the example is to define a separate data source for appointment labels (the LabelsDataSource property) and map field names for Id, Color and DisplayName (the LabelIdMappedName, LabelColorMappedName and LabelDisplayNameMappedName properties). If the data source is not specified, the default label items are used (see the PopulateDefaultLabels method in the example). Otherwise, labels from a data source are used. 

    I hope you will find the How to provide the capability to bind appointment labels to a datasource example useful.

    Feel free to contact us in the future. We are happy to help you at any time.


示例里的解决方案,相当复杂,所以说这的确是一个设计级错误。不是bug.
看来有拖延症的,不止我一个人,哈。
不过,结局是好的。
感谢devexpress.
那个示例的版本是14.1,我在13.6上测过。没有问题。
当然,就我个人,就不改了。用自己写的这个吧,简单。

你可能感兴趣的:(DevExpress)