WPF DEV CellTemplateSelector(一個正確使用DevExpress CellTemplateSelector的Demo)

来源:http://www.cnblogs.com/damon-xu/archive/2017/02/08/6376900.html
-Advertisement-
Play Games

說明 我在項目中根據需求需要用到WPF Dev CellTemplateSelector時,遇到不少坑。曾一度想要放棄使用模板轉換器,但又心有不甘,終於在不斷努力下,達到了需求的要求。所以寫下來和大家分享。如果有同樣困惑的人,可以少走些彎路。筆者第一次寫博客,文筆不好,還請見諒。 需求 需求很簡單, ...


說明

我在項目中根據需求需要用到WPF Dev CellTemplateSelector時,遇到不少坑。曾一度想要放棄使用模板轉換器,但又心有不甘,終於在不斷努力下,達到了需求的要求。所以寫下來和大家分享。如果有同樣困惑的人,可以少走些彎路。筆者第一次寫博客,文筆不好,還請見諒。

需求

 

需求很簡單,選擇方式下拉框選中時間控制方式或者價格控制方式,後面的控制點單元格對應顯示日期控制項或文本控制項。

思路

剛拿到這個需求,就想到了模板選擇器。但是之前也沒有用過模板轉換器,所以走了很多彎路。我們先看dev官方文檔的說明

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.

意思就是說模板控制項必須命名為“PART_Editor”,並且模板不需要綁定數據源,對應的GridControl的列綁定數據源即可,GridControl會自動將模板嵌入展示。我剛開始就是沒有命名規範,並且在模板控制項中綁定了數據源所以顯示一直有問題。根據需求寫出模板如下。

  <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>

同時CellTemplateSelector需要繼承DataTemplateSelector類,並且實現SelectTemplate方法根據條件返回一個你所需的Template.代碼如下

 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);
        }
    }

然後前臺xmal的CellTemplateSelector中引用選擇器,代碼如下

      <dxg:GridColumn x:Name="ControlPointDataTime" Binding="{Binding Path=ControlPoint,Mode=TwoWay}" Header="控制點" >
                    <dxg:GridColumn.CellTemplateSelector>
                        <local:SettingDataTemplateSelector
                                                             FirstTemplate="{StaticResource FirstTemplate}"
                                                             SecondTemplate="{StaticResource SecondTemplate}" />
                    </dxg:GridColumn.CellTemplateSelector>

                </dxg:GridColumn>

基本的需求就完成了,是不是看著很簡單。其實當你覺得簡單是因為你瞭解了DEV的一些機制,比如模板控制項的命名必須是“PART_Editor”,還有綁定的地方,任何一個地方出錯了前臺運行顯示都是不會稱心如意的,這個時候你就會找不到解決的辦法,從而達不到你想要的目的。上面的需求其實還有一個問題,比如:當你添加一條記錄是金額控制的,此時這條記錄已經添加到數據中了。如果你在界面上修改將下拉框選中改為時間控制,後面一列由於因為無法轉換為時間格式,所以顯示仍然有問題。此時怎麼辦呢,我想到了GridControl的CellValueChanged事件,當我切換控制方式時,後面一列我給它清空,這樣直接讓用戶輸入不就好了。在這裡我也將代碼貼出來。

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

到此,項目運行起來看著還行,雖然需求很簡單,但也折騰了我一段時間,今後我會不斷的寫博客來記錄我遇到的坑來和大家分享,同時也方便我自己查看。最後,我將完整的demo上傳供大家參考,我用的dev的版本是15.2.4,如果你的版本和我的不一樣,可以將demo中的引用刪除換成自己的就可以了。

補充:當系統時間設置如下時,前臺界面將顯示混亂。

前臺顯示如下

當我發現這個問題,我一時沒有更好的解決辦法。前臺模板DateEdit的Mask、DisplayFormatString以及MaskUseAsDisplayFormat都設為True。於是我向DevSupport尋求幫助。DevSupport給出解釋如下:

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

在此,我給出第二種方法的實現方式。

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;
        }
    }

前臺添加Convert轉化綁定

<dxg:GridColumn x:Name="ControlPointDataTime" Binding="{Binding Path=ControlPoint,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged,NotifyOnSourceUpdated=True,Converter={local:ConvertDateTime}}" Header="控制點" >

到此,問題就解決了。

補充2:對於上面的切換控制方式時,後面一列清空的需求這裡有更簡單的實現方式,只需要將你自定義的類中的屬性加上一些邏輯控制就好了,代碼如下:

   private int _ControlMode;

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

 將修改後的源碼重新上傳。

 源碼下載:http://files.cnblogs.com/files/damon-xu/demo.rar


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 打開終端,輸入su root,進入root賬戶 在/boot/grub2/下麵有個grub.cfg文件 在命令行輸入vim /boot/grub2/grub.cfg 在### BEGIN /etc/grub.d/10_linux ### 後面加上一段 menuentry 'Windows7'{ in ...
  • Linux系統信息存放在文件里,文件與普通的公務文件類似。每個文件都有自己的名字、內容、存放地址及其它一些管理信息,如文件的用戶、文件的大小等。文件可以是一封信、一個通訊錄,或者是程式的源語句、程式的數據,甚至可以包括可執行的程式和其它非正文內容。Linux文件系統具有良好的結構,系統提供了很多文件 ...
  • 用戶訪問示意圖: ...
  • 實例1:每1分鐘執行一次myCommand * * * * * myCommand 實例2:每小時的第3和第15分鐘執行 3,15 * * * * myCommand 實例3:在上午8點到11點的第3和第15分鐘執行 3,15 8-11 * * * myCommand 實例4:每隔兩天的上午8點到1 ...
  • 上篇我們學習了shell中條件選擇語句的用法。接下來本篇就來學習迴圈語句。在shell中,迴圈是通過for, while, until命令來實現的。下麵就分別來看看吧。 for for迴圈有兩種形式: for in語句 基本格式如下: for var in list do commands done ...
  • 1.安裝chocolatey打開cmd.exe執行@powershell -NoProfile -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://choco ...
  • 我一畢業進公司就接觸到了RPC,主要是使用前輩們搭建好的RPC框架以及封裝好的RPC函數進行業務開發,雖說使用RPC框架開發已經近半年了,但一直想知道如何從零開始搭建起這麼一個好用的分散式通信系統框架,近日心血來潮,雖說沒人教怎麼搭建,但自己在網上查閱了大量資料後,開始自己一手一腳從零搭建這麼一個R ...
  • 想要執行一次全局更新,發現屢次報錯: 提示的錯誤信息包含如下內容: 尋找解決方案未果。後來看到一個不相關的回答: ,腦洞大開想到可能是npm的modules文件夾下多出了一個npm debug.log的文件,導致查詢倉庫時把這個文件名也拿去查詢了。locate一下發現果真如此: 將這個文件刪掉後再次 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...