diff --git a/lib/app/communications/customer.js b/lib/app/communications/customer.js
index 1963dd9..7650055 100644
--- a/lib/app/communications/customer.js
+++ b/lib/app/communications/customer.js
@@ -790,9 +790,9 @@ export default class CustomerCommunication {
                                             div.style.display = 'none';
                                         }
                                         div.className = 'contacts-record';
-                                        div.style.maxHeight = '200px';
+                                        // div.style.maxHeight = '200px';
                                         div.style.width = '675px';
-                                        div.style.overflow = 'auto';
+                                        // div.style.overflow = 'auto';
                                     }),
                                     createElement('div', div => {
                                         div.style.fontWeight = 'bold';
@@ -800,9 +800,9 @@ export default class CustomerCommunication {
                                     }),
                                     createElement('div', div => {
                                         div.className = 'contacts-wo';
-                                        div.style.maxHeight = '200px';
+                                        // div.style.maxHeight = '200px';
                                         div.style.width = '675px';
-                                        div.style.overflow = 'auto';
+                                        // div.style.overflow = 'auto';
                                     })
                                 )
                             });
diff --git a/lib/app/communications/style.scss b/lib/app/communications/style.scss
index 318b475..4f975a4 100644
--- a/lib/app/communications/style.scss
+++ b/lib/app/communications/style.scss
@@ -16,6 +16,7 @@
 
         >.ui-grid {
             overflow-x: visible;
+            max-height: 200px;
         }
     }
 }
diff --git a/lib/element/schedule.js b/lib/element/schedule.js
index 18520f6..7a8bf73 100644
--- a/lib/element/schedule.js
+++ b/lib/element/schedule.js
@@ -206,10 +206,16 @@ export default class ScheduleItem {
                 createElement('legend', legend => legend.innerText = 'Duration'),
                 createElement('div', 'schedule-item-line schedule-item-line-duration',
                     createElement('span', span => span.innerText = 'Start date'),
-                    createElement('input', i => { i.type = 'date', i.className = 'ui-input schedule-id-duration-start', i.maxLength = 10 }),
+                    validation(
+                        createElement('input', i => { i.type = 'date', i.className = 'ui-input schedule-id-duration-start', i.maxLength = 10, i.required = true, i.min = '1753-01-01', i.max = '9999-12-31' }),
+                        /^[1-9][0-9]{3}-(1[0-2]|0[1-9])-(3[0-1]|[1-2][0-9]|0[1-9])$/
+                    ),
                     createElement('div', 'schedule-item-placeholder'),
                     createElement('span', span => span.innerText = 'End date'),
-                    createElement('input', i => { i.type = 'date', i.className = 'ui-input schedule-id-duration-end', i.maxLength = 10 })
+                    validation(
+                        createElement('input', i => { i.type = 'date', i.className = 'ui-input schedule-id-duration-end', i.maxLength = 10, i.required = true, i.min = '1753-01-01', i.max = '9999-12-31' }),
+                        /^[1-9][0-9]{3}-(1[0-2]|0[1-9])-(3[0-1]|[1-2][0-9]|0[1-9])$/
+                    )
                 ),
                 createElement('div', 'schedule-item-line',
                     createCheckbox({ className: 'schedule-id-enabled', checked: true, label: 'Enabled' })
diff --git a/lib/element/style.scss b/lib/element/style.scss
index f7a7b35..5c9c758 100644
--- a/lib/element/style.scss
+++ b/lib/element/style.scss
@@ -18,6 +18,12 @@
         .ui-input {
             line-height: 20px;
             height: 20px;
+            text-indent: 0;
+
+            &.validation-error,
+            &:invalid {
+                color: #0000004d;
+            }
         }
 
         .schedule-item-monthly {
diff --git a/lib/ui/date.js b/lib/ui/date.js
index e3ca45d..81d249a 100644
--- a/lib/ui/date.js
+++ b/lib/ui/date.js
@@ -22,9 +22,13 @@ export function createDateInput(min, max, element) {
     date.type = 'date';
     if (min != null) {
         date.min = min;
+    } else {
+        date.min = '1753-01-01';
     }
     if (max != null) {
         date.max = max;
+    } else {
+        date.max = '9999-12-31';
     }
     return date;
 }
diff --git a/lib/ui/dropdown.d.ts b/lib/ui/dropdown.d.ts
index b69dbcc..927c1f4 100644
--- a/lib/ui/dropdown.d.ts
+++ b/lib/ui/dropdown.d.ts
@@ -117,8 +117,10 @@ export class Dropdown {
      * 选中某个条目
      * @param selected 选中的值
      * @param silence 是否静默选中,即不触发 {@linkcode onSelected} 事件
+     * @param ignoreCase 是否不区分大小写
+     * @returns 是否选中
      */
-    select(selected: string, silence?: boolean): void;
+    select(selected: string, silence?: boolean, ignoreCase?: boolean): boolean | undefined;
     /**
      * 选中条目列表
      * @param selectedlist 选中的值的列表
diff --git a/lib/ui/dropdown.js b/lib/ui/dropdown.js
index 78df616..9799ef0 100644
--- a/lib/ui/dropdown.js
+++ b/lib/ui/dropdown.js
@@ -281,18 +281,21 @@ export class Dropdown {
 
     get selectedList() { return this._var.selectedList || [] }
 
-    select(selected, silence) {
+    select(selected, silence, ignoreCase) {
         if (typeof selected !== 'string') {
             selected = String(selected);
         }
+        if (ignoreCase) {
+            selected = selected.toLowerCase();
+        }
         if (this._var.lastSelected === selected) {
-            return false;
+            return;
         }
         this._var.lastSelected = selected;
         const valuekey = this._var.options.valueKey;
         const textkey = this._var.options.textKey;
         const htmlkey = this._var.options.htmlKey;
-        let item = this.source.find(it => String(it[valuekey]) === selected);
+        let item = this.source.find(it => (ignoreCase ? String(it[valuekey]).toLowerCase() : String(it[valuekey])) === selected);
         if (this._var.options.input) {
             if (item == null) {
                 item = { [valuekey]: selected };
@@ -322,7 +325,7 @@ export class Dropdown {
             }
             if (expanded) {
                 for (let li of this._var.container.querySelectorAll('li[data-value]')) {
-                    if (li.dataset.value === selected) {
+                    if ((ignoreCase ? li.dataset.value.toLowerCase() : li.dataset.value) === selected) {
                         li.classList.add('selected');
                         break;
                     }
@@ -338,6 +341,7 @@ export class Dropdown {
         if (!silence && typeof this.onSelected === 'function') {
             this.onSelected(item);
         }
+        return true;
     }
 
     selectlist(selectedlist, silence) {
diff --git a/lib/ui/grid/column.js b/lib/ui/grid/column.js
index cb0385f..46467b5 100644
--- a/lib/ui/grid/column.js
+++ b/lib/ui/grid/column.js
@@ -445,8 +445,9 @@ export class GridDropdownColumn extends GridColumn {
      * @param {any} val 
      * @param {GridItemWrapper} wrapper 
      * @param {GridColumnDefinition} col 
+     * @param {Grid} grid 
      */
-    static setValue(element, val, wrapper, col) {
+    static setValue(element, val, wrapper, col, grid) {
         if (element.tagName !== 'DIV') {
             let source = this._getSource(wrapper, col);
             if (source instanceof Promise) {
@@ -460,19 +461,42 @@ export class GridDropdownColumn extends GridColumn {
         if (drop == null) {
             return;
         }
+        const ignoreCase = col.dropRestrictCase !== true;
         if (drop.source == null || drop.source.length === 0) {
             let source = this._getSource(wrapper, col);
             if (source instanceof Promise) {
                 source.then(s => {
                     drop.source = s;
-                    drop.select(val, true);
+                    drop.select(val, true, ignoreCase);
                 })
                 return;
             } else if (source != null) {
                 drop.source = source;
             }
         }
-        drop.select(val, true);
+        if (typeof val === 'string' && val !== '') {
+            const lVal = String(val).toLowerCase();
+            const item = drop.source.find(s => {
+                let v = s[col.dropOptions?.valueKey ?? 'value'];
+                if (ignoreCase) {
+                    return String(v).toLowerCase() === lVal;
+                }
+                return v === val;
+            });
+            if (item == null) {
+                let text;
+                if (col.text == null && typeof col.filter === 'function') {
+                    text = col.filter(wrapper.values, false, grid._var.refs.body);
+                } else {
+                    text = val;
+                }
+                drop.source.push({
+                    [col.dropOptions?.textKey ?? 'text']: text,
+                    [col.dropOptions?.valueKey ?? 'value']: val
+                });
+            }
+        }
+        drop.select(val, true, ignoreCase);
     }
 
     /**
diff --git a/lib/ui/grid/grid.js b/lib/ui/grid/grid.js
index d7e4902..63b725f 100644
--- a/lib/ui/grid/grid.js
+++ b/lib/ui/grid/grid.js
@@ -258,6 +258,7 @@ let r = lang;
  * @property {boolean} [filterAsValue=false] - 列头过滤强制使用 `Value` 字段
  * @property {GridItemSortCallback} [sortFilter] - 自定义列排序函数
  * @property {DropdownOptions} [dropOptions] - 列为下拉列表类型时以该值设置下拉框的参数
+ * @property {boolean} [dropRestrictCase=false] - 下拉列表是否区分大小写
  * @property {(GridSourceItem[] | Promise<GridSourceItem[]> | GridDropdownSourceCallback)} [source] - 列为下拉列表类型时以该值设置下拉列表数据源,支持返回异步对象,也支持调用函数返回
  * @property {boolean} [sourceCache=false] - 下拉列表数据源是否缓存结果(即行数据未发生变化时仅从source属性获取一次值)
  * @property {("fa-light" | "fa-regular" | "fa-solid")} [iconType=fa-light] - 列为图标类型时以该值设置图标样式
@@ -1924,7 +1925,8 @@ export class Grid {
         }
         const it = this._var.currentSource[index];
         // clear dropdown source cache
-        delete it.source;
+        // FIXME: 清除缓存会导致选中状态下动态数据源下拉列表显示为空
+        // delete it.source;
         it.values = item;
         if (this.sortIndex >= 0) {
             this.sortColumn();
@@ -4127,7 +4129,8 @@ export class Grid {
             return;
         }
         const vals = this._var.currentSource[this._var.startIndex + index];
-        delete vals.source;
+        // FIXME: 清除缓存会导致选中状态下动态数据源下拉列表显示为空
+        // delete vals.source;
         const item = vals.values;
         if (item == null) {
             return;