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

Xamarin.Forms中DevExpress TextEdit无法绑定XCT UserStoppedTypingBehavior的问题

问题

在Xamarin.Forms应用中使用DevExpress Editor的TextEdit控件时,无法将其绑定到XCT的UserStoppedTypingBehavior,使用的代码如下:

<dxe:TextEdit
             Margin="2"
             LabelText="Evrak Seri"
             LabelFontSize="16"
             LabelColor="Black"
             IsVisible="{Binding EvrakSeriSiraGorunum}"
             BackgroundColor="White"
             BorderColor="Black"
             WidthRequest="300" 
             Text="{Binding EvrakseriText}"
             ReserveBottomTextLine="True"
             IsLabelFloating="False"
        x:Name="evrakSeriText1"
        
        >
            <dxe:TextEdit.Behaviors>
                    <xct:UserStoppedTypingBehavior Command="{Binding SearchCommand}" />
                </dxe:TextEdit.Behaviors>
                <dxe:TextEdit.Triggers>
                    <DataTrigger TargetType="dxe:TextEdit" Value="-1" Binding="{Binding Source={x:Reference evrakSeriText1},
                               Path=Text.Length}" >

                        
                    </DataTrigger>

                </dxe:TextEdit.Triggers>
            </dxe:TextEdit>

出现的错误:

System.InvalidOperationException Message=bindable not an instance of AssociatedType

怀疑是TargetType设置错误,但找不到正确类型。想知道TextEdit是否有类似XCT UserStoppedTypingBehavior的功能?如果没有,该如何解决这个问题?

解决方案

1. 错误根源

XCT的UserStoppedTypingBehavior是专为Xamarin.Forms原生Entry/Editor控件设计的,它的关联类型是原生Entry。而DevExpress的TextEdit是自定义控件,并非原生Entry的子类,直接挂载会触发类型不匹配的错误,也就是你看到的bindable not an instance of AssociatedType。

2. 使用TextEdit自带的事件实现等效功能

DevExpress的TextEdit本身没有现成的“停止输入触发命令”的内置行为,但可以通过TextChanged事件结合延迟执行来实现相同效果:

实现步骤:

  • 在ViewModel中维护一个CancellationTokenSource,用于取消未执行的延迟任务
  • 每次文本变化时,取消之前的延迟任务,重新创建新的延迟任务(延迟时间可自定义,比如500ms)
  • 延迟结束后执行你的SearchCommand

示例代码:

ViewModel部分:

private CancellationTokenSource _typingCts;

public ICommand SearchCommand { get; }

public YourViewModel()
{
    SearchCommand = new Command(ExecuteSearch);
    _typingCts = new CancellationTokenSource();
}

private void OnTextChanged(string newText)
{
    // 取消之前的延迟任务
    _typingCts.Cancel();
    _typingCts.Dispose();
    _typingCts = new CancellationTokenSource();

    // 延迟500ms后执行搜索命令
    Task.Delay(500, _typingCts.Token)
        .ContinueWith(t =>
        {
            if (!t.IsCanceled)
            {
                SearchCommand.Execute(null);
            }
        }, TaskScheduler.FromCurrentSynchronizationContext());
}

private void ExecuteSearch()
{
    // 你的搜索逻辑
}

XAML部分:

<dxe:TextEdit
    ...
    TextChanged="OnTextEditTextChanged"
    >
</dxe:TextEdit>

Code-Behind部分:

private void OnTextEditTextChanged(object sender, DevExpress.XamarinForms.Editors.TextChangedEventArgs e)
{
    var viewModel = BindingContext as YourViewModel;
    viewModel?.OnTextChanged(e.NewTextValue);
}

3. 自定义适配TextEdit的行为(复用模式)

如果想沿用XCT行为的使用方式,可以自定义一个针对TextEdit的UserStoppedTypingBehavior:

public class TextEditUserStoppedTypingBehavior : Behavior<TextEdit>
{
    public static readonly BindableProperty CommandProperty =
        BindableProperty.Create(nameof(Command), typeof(ICommand), typeof(TextEditUserStoppedTypingBehavior));

    public static readonly BindableProperty StoppedDelayProperty =
        BindableProperty.Create(nameof(StoppedDelay), typeof(int), typeof(TextEditUserStoppedTypingBehavior), 500);

    private CancellationTokenSource _cts;

    public ICommand Command
    {
        get => (ICommand)GetValue(CommandProperty);
        set => SetValue(CommandProperty, value);
    }

    public int StoppedDelay
    {
        get => (int)GetValue(StoppedDelayProperty);
        set => SetValue(StoppedDelayProperty, value);
    }

    protected override void OnAttachedTo(TextEdit bindable)
    {
        base.OnAttachedTo(bindable);
        bindable.TextChanged += OnTextChanged;
    }

    protected override void OnDetachingFrom(TextEdit bindable)
    {
        base.OnDetachingFrom(bindable);
        bindable.TextChanged -= OnTextChanged;
        _cts?.Cancel();
    }

    private void OnTextChanged(object sender, DevExpress.XamarinForms.Editors.TextChangedEventArgs e)
    {
        _cts?.Cancel();
        _cts?.Dispose();
        _cts = new CancellationTokenSource();

        Task.Delay(StoppedDelay, _cts.Token)
            .ContinueWith(t =>
            {
                if (!t.IsCanceled && Command != null && Command.CanExecute(null))
                {
                    Command.Execute(null);
                }
            }, TaskScheduler.FromCurrentSynchronizationContext());
    }
}

在XAML中使用这个自定义行为:

<dxe:TextEdit
    ...
    >
    <dxe:TextEdit.Behaviors>
        <local:TextEditUserStoppedTypingBehavior Command="{Binding SearchCommand}" StoppedDelay="500" />
    </dxe:TextEdit.Behaviors>
</dxe:TextEdit>

内容的提问来源于stack exchange,提问作者Mert Altiparmak

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 10:22:48