You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Microsoft Dynamics 365 F&O中使用扩展技术实现即时搜索过滤器?

Real-Time Search Filter for Grouped Lists in Modern D365 F&O (Using Extensions)

Absolutely! You can replicate that real-time, as-you-type filtering functionality for grouped lists using modern D365 F&O extension techniques—no outdated overlay hacks needed. This approach uses form extensions, event handlers, and dynamic query filtering, which aligns with Microsoft's recommended development practices and keeps your solution upgrade-safe.

Here's a step-by-step breakdown to implement it:

Step 1: Extend the Target Form & Add a Search Control

First, create a form extension for the form where you want the real-time filter:

  • Open the Form Designer in Visual Studio and locate the base form you want to modify.
  • Right-click the form and select Create extension to generate an extension project.
  • Add a StringEdit control to a suitable location (like the top toolbar or header section of the form). Name it something descriptive, e.g., FilterName, and set these properties:
    • Label: Filter by Name
    • ShowLabel: Yes
    • AllowEdit: Yes

Step 2: Implement Real-Time Filter Logic with Event Handlers

Next, add event handlers to trigger filtering as the user types. We'll use the TextChange event for immediate updates (or add a timer delay if you want to reduce server calls):

Basic Immediate Filtering

Add this code to your form extension's class:

[FormControlEventHandler(formControlStr(YourBaseForm, FilterName), FormControlEventType::TextChange)]
public static void FilterName_OnTextChange(FormControl sender, FormControlEventArgs e)
{
    FormStringEdit filterControl = sender as FormStringEdit;
    FormDataSource targetDataSource = filterControl.formRun().dataSource(FormDataStr(YourBaseForm, YourDataSource));
    Query query = targetDataSource.query();
    QueryBuildDataSource qbds = query.dataSourceTable(tableNum(YourTargetTable));
    QueryBuildRange nameRange;

    // Clear existing filters on the Name field
    qbds.clearRanges(fieldNum(YourTargetTable, Name));

    // Apply new filter if input isn't empty
    if (filterControl.text() != '')
    {
        nameRange = qbds.addRange(fieldNum(YourTargetTable, Name));
        // Use wildcard matching for partial matches
        nameRange.value(strFmt('*%1*', filterControl.text()));
        nameRange.status(RangeStatus::Open);
    }

    // Refresh the data source to update the grouped list
    targetDataSource.executeQuery();
}

Optional: Add a Delay to Reduce Server Load

If you want to avoid firing a query on every single keystroke (better for performance), add a TimerControl to your form extension:

  1. Add a Timer control to the form, name it FilterTimer, and set Interval to 500 (milliseconds).
  2. Update the event handlers:
// Triggered on every keystroke—resets the timer
[FormControlEventHandler(formControlStr(YourBaseForm_Extension, FilterName), FormControlEventType::TextChange)]
public static void FilterName_OnTextChange(FormControl sender, FormControlEventArgs e)
{
    FormStringEdit filterControl = sender as FormStringEdit;
    FormTimerControl filterTimer = filterControl.formRun().control(formControlStr(YourBaseForm_Extension, FilterTimer));
    filterTimer.reset();
}

// Runs the filter logic once the timer finishes counting down
[FormControlEventHandler(formControlStr(YourBaseForm_Extension, FilterTimer), FormControlEventType::Tick)]
public static void FilterTimer_OnTick(FormControl sender, FormControlEventArgs e)
{
    FormTimerControl timer = sender as FormTimerControl;
    FormStringEdit filterControl = timer.formRun().control(formControlStr(YourBaseForm_Extension, FilterName));
    FormDataSource targetDataSource = timer.formRun().dataSource(FormDataStr(YourBaseForm, YourDataSource));
    Query query = targetDataSource.query();
    QueryBuildDataSource qbds = query.dataSourceTable(tableNum(YourTargetTable));
    QueryBuildRange nameRange;

    qbds.clearRanges(fieldNum(YourTargetTable, Name));

    if (filterControl.text() != '')
    {
        nameRange = qbds.addRange(fieldNum(YourTargetTable, Name));
        nameRange.value(strFmt('*%1*', filterControl.text()));
        nameRange.status(RangeStatus::Open);
    }

    targetDataSource.executeQuery();
}

Step 3: Verify Grouped List Behavior

Since the grouped list (whether it's a grid with grouping enabled or a tree control) is bound to the same form data source, calling executeQuery() will automatically refresh the grouped view to match the filtered data. If you're using a tree control, ensure its data source is linked correctly to the filtered form data source.

Key Benefits Over Overlay Techniques

  • Upgrade-safe: Extensions don't modify base application code, so your changes won't be overwritten during D365 updates.
  • Maintainable: Event-based logic is easier to debug and modify than overlay hacks.
  • Performance: You can optimize the filtering (like adding a timer) to reduce unnecessary server requests.

内容的提问来源于stack exchange,提问作者Brian Kessler

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 20:59:09