在TextChange上调用命令不会立即更新文本源

时间:2014-05-21 12:38:34

标签: mvvm-light windows-phone-8.1 relaycommand commandbinding

我在Windows Phone 8.1中使用MVVM灯这里是代码

XAML

    <TextBox Text="{Binding SearchText, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" >
        <Interactivity:Interaction.Behaviors>
            <Core:EventTriggerBehavior EventName="TextChanged">
                <Core:InvokeCommandAction Command="{Binding SearchTextChanged}"></Core:InvokeCommandAction>
            </Core:EventTriggerBehavior>
        </Interactivity:Interaction.Behaviors>
    </TextBox>

这是我的VM

    private RelayCommand _searchTextChanged;

    /// <summary>
    /// Gets the SearchTextChanged.
    /// </summary>
    public RelayCommand SearchTextChanged
    {
        get
        {
            return _searchTextChanged
                ?? (_searchTextChanged = new RelayCommand(
                                      () =>
                                      {
                                          LoadContents(this.SearchText);

                                      }));
        }
    }

每次更改文本时,SearchTextChanged命令都正常触发,但SearchText属性中的文本未更新,它只减少了一个字符。例如如果文本框中的文本是A而不是SearchText包含null。如果文本框中的文本是'aaa'而不是SearchText中的文本只是'aa',则始终缺少最后一个字符。

任何想法?

2 个答案:

答案 0 :(得分:5)

好的,基于评论,这里的答案是 - 不要使用InvokeCommandAction但是双向绑定。

<TextBox Text="{Binding SearchText, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />

在这背后的viewmodel中,有一个名为SearchText的属性,它有一个可以调用LoadContents方法的setter,就像这样...

public string SearchText
{
    get { return this.searchText; }
    set
    {
        this.searchText = value;
        NotifyPropertyChanged("SearchText");
        LoadContents(this.searchText);
    }
}

每次TextBox中的字符串发生更改时,都会调用setter,LoadContents方法也会被调用。

答案 1 :(得分:0)

陷入了非常类似的情况,但在我的情况下,给定的解决方法并不是解决方案!所以发现了另一种更新价值的方法。

解决方案: 将元素作为参数传递给命令并更新源,然后调用方法。

public string SearchText
{
get { return this.searchText; }
set
{
    this.searchText = value;
    NotifyPropertyChanged("SearchText");
}
}
public RelayCommand SearchTextChanged
{
    get
    {
        return _searchTextChanged
            ?? (_searchTextChanged = new RelayCommand(
                                  () =>
                                  {
                                      someCommandAction();

                                  }));
    }
}

private void someCommandAction(object obj)
{
    TextBox textBox = (obj as TextBox);
    if (textBox != null)
     {
        var be = textBox.GetBindingExpression(TextBox.TextProperty);
        if (be != null)
            be.UpdateSource();
     }
     LoadContents(textBox.Text); //textBox.text or the SearchTextproperty itself
}

XAML部分:

<TextBox x:Name="textBoxName" Text="{Binding SearchText,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" >
    <Interactivity:Interaction.Behaviors>
        <Core:EventTriggerBehavior EventName="TextChanged">
            <Core:InvokeCommandAction Command="{Binding SearchTextChanged}"
                                      CommandParameter="{Binding ElementName=textBoxName}" />
        </Core:EventTriggerBehavior>
    </Interactivity:Interaction.Behaviors>
</TextBox>