Xaml EventTrigger中的命令参数

Xaml EventTrigger中的命令参数,xaml,windows-runtime,mvvmcross,eventtrigger,commandparameter,Xaml,Windows Runtime,Mvvmcross,Eventtrigger,Commandparameter,我正在使用mvmmcrossv3框架和 我想要一个在事件TextChanged上带有EventTrigger的文本框,用于启动命令。还有,我想在CommandParameter中输入文本框的文本 所以我有这个密码 <i:EventTrigger EventName="TextChanged"> <i:InvokeCommandAction Command="{Binding UpdateText}" CommandParamete

我正在使用mvmmcrossv3框架和

我想要一个在事件TextChanged上带有EventTrigger的文本框,用于启动命令。还有,我想在CommandParameter中输入文本框的文本

所以我有这个密码

   <i:EventTrigger EventName="TextChanged">
                    <i:InvokeCommandAction  Command="{Binding UpdateText}" CommandParameter="{Binding Text}"/>
                </i:EventTrigger>


public ICommand UpdateText
{
    get
    {
        return new MvxCommand<object>((textSearch) =>
            {
                // code...
            });
    }
}
但它也失败了


谢谢

您真的需要处理
TextChanged
事件吗?只需绑定到
文本
属性即可通知您更改:

<TextBox Text="{Binding TextValue, Mode=TwoWay}" />
编辑:

如果要从
命令中获取
文本
值,有两件事需要注意:

首先,您需要修复
命令参数
绑定。通过使用
{Binding Text}
实际上是试图绑定到视图模型中的属性,即首先需要将
TextBox.Text
属性绑定到同一视图模型属性。正如你在评论中所说的,这对你没有好处,因为你需要的是关于每一次改变的信息,而不仅仅是关于失去焦点的信息,所以你得到的价值不够及时

因此,正确的方法是第二次尝试,即使用
ElementName
语法直接绑定到
TextBox
。不幸的是,触发器不是可视化树的一部分,因此它们无法访问XAML名称范围(您可以在中了解更多信息)。您可以从以下位置使用
NameScopeBinding
解决此问题:

您还有第二个问题。您绑定到的
Text
值仅在焦点丢失时更新,因此在处理
TextChanged
事件时无法获得正确的值。解决方案是绑定到
文本框本身:

<i:InvokeCommandAction Command="{Binding UpdateText}" 
    CommandParameter="{Binding Source, Source={StaticResource MyTextBox}}"/>
编辑2:

要使上述代码与PCL中的视图模型一起工作,可以采取以下几种方法

最简单的技巧是使用反射。由于它在PCL中可用,因此您可以访问
Text
属性并读取其值:

private void OnUpdateText(object parameter)
{
    var textProperty = textSearch.GetType().GetProperty("Text");
    var value = textProperty.GetValue(parameter, null) as string;
    // process the Text value as you need to.
}
一个更干净的解决方案是将特定于WinRT的代码放入通过接口抽象的单独程序集中。首先在PCL库中创建一个接口:

public interface IUiService
{
    string GetTextBoxText(object textBox);
}
并修改视图模型以在构造函数中接受此接口:

public ViewModel(IUiService uiService)
{
    _uiService = uiService;
}
在命令处理程序中,您将使用接口中的方法:

private void OnUpdateText(object parameter)
{
    var value = _uiService.GetTextBoxText(parameter);
    // process the Text value as you need to.
}
您可以在WinRT库中实现该接口:

public class UiService : IUiService
{
    public string GetTextBoxText(object textBox)
    {
        var typedTextBox = textBox as TextBox;
        return typedTextBox.text;
    }
}
在应用程序中,引用此库并将实现传递给视图模型:

private string _textValue;
public string TextValue
{
    get
    {
        return _textValue;
    }
    set
    {
        if (_textValue == value)
            return;
        _textValue = value;
        OnTextChanged(value); // react to the changed value
    }
}
var viewModel = new ViewModel(new UiService);
我最喜欢的方法不同:我会创建一个
行为
公开一个
文本
属性,每次触发
文本更改
事件时自动更新该属性:

public class TextChangedBehavior : Behavior<TextBox>
{
    public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
        "Text", 
        typeof(string), 
        typeof(TextChangedBehavior), 
        new PropertyMetadata(null));

    public string Text
    {
        get { return (string) GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }


    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.TextChanged += OnTextChanged;
        Text = AssociatedObject.Text;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.TextChanged -= OnTextChanged;
    }

    private void OnTextChanged(object sender, TextChangedEventArgs textChangedEventArgs)
    {
        Text = AssociatedObject.Text;
    }
}

你能分享一个复制项目吗?我会尽快做的,在那里你可以看到GitHub项目谢谢你的回答,但是我真的需要改变文本,因为使用简单的绑定我们必须失去焦点才能抛出绑定。在我的例子中,它是在一个大列表中搜索某个项目,我真的需要在每次用户输入密钥时更新我的列表。@DevCrosser我更新了我的帖子,解释了你的绑定不起作用,并展示了如何使它按你的需要工作。非常感谢你的帮助,它只适用于一个简单的项目。但是我使用PCL内核,所以在我的ViewModels中不能使用TextBox类。在debug中,我看到我的参数带有文本属性wich,但正如我所说的,我不能在代码中强制转换它。我试图在NameScopeBinding中添加Path=Text,但在输入文本时,输出延迟了一个字母。@DevCrosser我添加了一些建议,以便使用PCL使一切正常工作。我不愿意将MVVMHelpers添加到我的项目中,只是为了尝试一下,但它确实起了作用,我的CommandParameter引用了一个元素名。我使用了通用的MVVMHelpers包,而不是Win 8.1特定包,以及您的
CommandParameter=“{Binding Source.Text,Source={StaticResource MyTextBox}}”
。我的控件名是
userControl
,我得到了一个名为
BumpAmount
的依赖属性:

private void OnUpdateText(object parameter)
{
    var value = _uiService.GetTextBoxText(parameter);
    // process the Text value as you need to.
}
public class UiService : IUiService
{
    public string GetTextBoxText(object textBox)
    {
        var typedTextBox = textBox as TextBox;
        return typedTextBox.text;
    }
}
var viewModel = new ViewModel(new UiService);
public class TextChangedBehavior : Behavior<TextBox>
{
    public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
        "Text", 
        typeof(string), 
        typeof(TextChangedBehavior), 
        new PropertyMetadata(null));

    public string Text
    {
        get { return (string) GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }


    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.TextChanged += OnTextChanged;
        Text = AssociatedObject.Text;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.TextChanged -= OnTextChanged;
    }

    private void OnTextChanged(object sender, TextChangedEventArgs textChangedEventArgs)
    {
        Text = AssociatedObject.Text;
    }
}
<TextBox>
    <i:Interaction.Behaviors>
        <b:TextChangedBehavior Text="{Binding TextValue, Mode=TwoWay}" />
    </i:Interaction.Behaviors>
</TextBox>