Wpf dev CellTemplateSelector (a Demo that correctly uses DevExpress CellTemplateSelector), wpfdevexpress

Source: Internet
Author: User
Tags parse string

Wpf dev CellTemplateSelector (a Demo that correctly uses DevExpress CellTemplateSelector), wpfdevexpress

Description

I encountered many pitfalls when using WPF Dev CellTemplateSelector as needed in the project. I once wanted to abandon the use of the template converter, But I was unwilling to use it. I finally made constant efforts to meet the requirements. So write it down and share it with you. If you are confused, you can avoid detours. I wrote a blog for the first time, but it is not a good document. Sorry.

Requirement

 

The requirement is very simple. Select the time control mode or price control mode from the drop-down list box. The control point cell is displayed as the date control or text control.

Ideas

Just getting this requirement, I thought of the template selector. However, no template converter has been used before, so many detours have taken place. Let's take a look at the description in the dev official documentation.

When using CellTemplate (or DataViewBase.CellTemplate) note the following:To enable data editing, use an editor shipped with the DevExpress Data Editors Library for WPF. The editor's Name must be set to 'PART_Editor'.When the editor's Name is set to PART_Editor, the grid automatically adjusts its appearance and synchronizes the editor with a source field specified by the FieldName or Binding properties.Standard controls can be used in CellTemplate only for display purposes. Data editing is not allowed.Templates specified via the DisplayTemplate and/or EditTemplate are ignored.A column's in-place editor specified via EditSettings, is also ignored.

This means that the template control must be named "PART_Editor" and the template does not need to be bound to the data source. The corresponding GridControl column is bound to the data source. GridControl automatically embeds the template for display. At the beginning, I had no naming rules and bound the data source to the template control, so there was always a problem with the display. Write the template as follows.

  <Window.Resources>        <DataTemplate x:Key="FirstTemplate">            <StackPanel>                <dxe:DateEdit x:Name="PART_Editor"  Mask="yyyy-MM-dd" MaskUseAsDisplayFormat="True">                </dxe:DateEdit>            </StackPanel>        </DataTemplate>        <DataTemplate x:Key="SecondTemplate">            <StackPanel>                <dxe:TextEdit x:Name="PART_Editor"                              MaskType="Numeric" Mask="n" MaskUseAsDisplayFormat="True" AllowNullInput="False" >                </dxe:TextEdit>            </StackPanel>        </DataTemplate>    </Window.Resources>

At the same time, CellTemplateSelector needs to inherit the ememplateselector class, and implement the SelectTemplate method to return a Template you need according to the conditions. The Code is as follows:

 public  class SettingDataTemplateSelector: DataTemplateSelector    {        public DataTemplate FirstTemplate        {            get;            set;        }        public DataTemplate SecondTemplate        {            get;            set;        }         public override DataTemplate SelectTemplate(object item, DependencyObject container)        {            FrameworkElement element = container as FrameworkElement;            EditGridCellData data = (EditGridCellData)item;            Setting setting = data.RowData.Row as Setting;            if (setting != null)            {                if (setting.ControlMode == 1)                    return element.FindResource("FirstTemplate") as DataTemplate;                else                    return element.FindResource("SecondTemplate") as DataTemplate;            }            return base.SelectTemplate(item, container);        }    }

Then, the selector is referenced in CellTemplateSelector of xmal. The Code is as follows:

<Dxg: GridColumn x: Name = "ControlPointDataTime" Binding = "{Binding Path = ControlPoint, Mode = TwoWay}" Header = "Control Point"> <dxg: GridColumn. cellTemplateSelector> <local: SettingDataTemplateSelector FirstTemplate = "{StaticResource FirstTemplate}" SecondTemplate = "{StaticResource SecondTemplate}"/> </dxg: GridColumn. cellTemplateSelector> </dxg: GridColumn>

The basic requirements have been completed. Is it easy to look. In fact, when you think it is simple because you understand some DEV mechanisms, for example, the template control must be named as "PART_Editor", and there must be some binding points, if an error occurs in any part of the page, the front-end running display will not be satisfactory. At this time, you will not find a solution to achieve your goal. There is another problem with the above requirement. For example, when you add a record to control the amount, this record has been added to the data. If you change the drop-down box selected on the interface to time control, the display in the next column is still incorrect because it cannot be converted to the time format. What should I do now? I thought of the CellValueChanged event of GridControl. when I switched the control mode, I cleared it from the next column so that the user could not input it directly. I also paste the code here.

   private void ViewSimulate_CellValueChanged(object sender, CellValueChangedEventArgs e)        {            if (e.Column == ComControlMode)            {                ((GridControl) e.Source.DataControl).SetCellValue(e.RowHandle,ControlPointDataTime,null);            }        }

At this point, the project looks okay, although the demand is very simple, but it has been tossing me for a while. In the future, I will keep writing blogs to record the pitfalls I encountered and share them with you, it is also convenient for me to view. Finally, I upload the complete demo for your reference. The dev version I use is 15.2.4. If your version is different from mine, you can delete the reference in the demo and replace it with your own.

Supplement:When the system time is set as follows, the foreground interface is messy.

The foreground is shown as follows:

When I find this problem, I have no better solutions at the moment. Set Mask, DisplayFormatString, and MaskUseAsDisplayFormat of the front-end template DateEdit to True. So I asked DevSupport for help. DevSupport provides the following explanations:

The cause of the issue is that date values are stored as string values. In this scenario, DXGrid posts the values in the current culture to maintain end-user input. 
DateEdit editors, however, use an invariant culture to parse string values.To resolve this issue, you can either store the date values as DateTime or additionally convert posted values. With your current implementation,
the second approach can be implemented by setting Binding.Converter to a custom converter

Here, I provide the implementation method of the second method.

public class ConvertDateTime : MarkupExtension, IValueConverter    {        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)        {            return value;        }        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)        {            DateTime date;            if (value is string && DateTime.TryParse((string)value, out date))                return date.ToString(CultureInfo.InvariantCulture);            return value;        }        public override object ProvideValue(IServiceProvider serviceProvider)        {            return this;        }    }

Add Convert conversion binding on the foreground

<Dxg: GridColumn x: Name = "ControlPointDataTime" Binding = "{Binding Path = ControlPoint, Mode = TwoWay, UpdateSourceTrigger = PropertyChanged, NotifyOnSourceUpdated = True, Converter = {local: convertDateTime }}" Header = "Control Point">

At this point, the problem is solved.

Supplement 2:For the above switching control mode, there is a simpler implementation method for the needs to be cleared in the next column. You just need to add some logical control to the attributes of your custom class, the Code is as follows:

   private int _ControlMode;        public int ControlMode        {            get { return _ControlMode; }            set { _ControlMode = value;                ControlPoint = null;            }        }

Upload the modified source code again.

Source code download: http://files.cnblogs.com/files/damon-xu/demo.rar

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.