4

我有一个简单的 WM7 页面,带有TextBox. 此外,我将EventToCommand(a RelayCommand<string>) 分配给 this ,对事件TextBox做出反应。TextChanged为了测试pourposes,我TextBox_TextChanged在页面后面的代码中做了额外的方法。命令并TextBox_TextChanged打印带有文本框内容的消息框。

TextBox的初始值为"ABC"。然后我按 D 并:

  1. TextBox_TextChanged打印ABCD
  2. 命令打印ABC. D 不见了。

为什么命令这么快?

命令声明:

public RelayCommand<string> TextChanged {get; private set;}

命令初始化:

TextChanged = new RelayCommand<string>((s) => MessageBox.Show(s));

命令绑定:

<TextBox x:Name="SearchTextBox" Margin="10,0" TextWrapping="Wrap" Text="{Binding SearchString, Mode=TwoWay}" FontStyle="Italic" TextChanged="SearchTextBox_TextChanged" >
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="TextChanged">
            <GalaSoft_MvvmLight_Command:EventToCommand Command="{Binding TextChanged, Mode=OneWay}" CommandParameter="{Binding Text, ElementName=SearchTextBox}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
</TextBox>
4

4 回答 4

6

我无法重现这种行为。我尝试过使用 EventToCommand 和 Behaviour(它只是监听 TextChanged 事件)。

在没有看到代码的情况下,我怀疑这可能与您获取搜索框文本的方式或其他地方的逻辑错误有关。

这是我如何使用 EventToCommand 的片段:

<TextBox Name="SearchTextBox">
  <i:Interaction.Triggers>
    <i:EventTrigger EventName="TextChanged">
      <cmd:EventToCommand Command="{Binding TestTextChangedCommand,Mode=OneWay}" CommandParameter="{Binding Path=Text, ElementName=SearchTextBox}"/>
    </i:EventTrigger>
  <i:Interaction.Triggers>
</TextBox>

在视图模型中

m_TestTextChangedCommand = new RelayCommand<string>(val => System.Diagnostics.Debug.WriteLine(val));

如您所见,我使用命令参数将文本框的值传递给视图模型。这样视图模型就不必知道文本框来获取文本值。

这种方法的替代方法是使用行为和双向绑定来更新属性:

<TextBox Name="SearchTextBox" Text="{Binding TextInViewModel, Mode=TwoWay}" >
  <i:Interaction.Behaviors>
    <sc:UpdateOnTextChangedBehavior/>
  </i:Interaction.Behaviors>
</TextBox>

UpdateOnTextChangedBehavior 类:

    public class UpdateOnTextChangedBehavior : Behavior<TextBox>
    {
        protected override void OnAttached()
        {
            base.OnAttached();

            this.AssociatedObject.TextChanged += 
                new TextChangedEventHandler(AssociatedObject_TextChanged);
        }

        void AssociatedObject_TextChanged(object sender, TextChangedEventArgs e)
        {
            System.Diagnostics.Debug.WriteLine(((TextBox)sender).Text);
            BindingExpression binding = 
                this.AssociatedObject.GetBindingExpression(TextBox.TextProperty);
            if (binding != null)
            {
                binding.UpdateSource();
            }
        }

        protected override void OnDetaching()
        {
            base.OnDetaching();

            this.AssociatedObject.TextChanged -= 
                new TextChangedEventHandler(AssociatedObject_TextChanged);
        }
    }

上面所做的是模仿桌面 WPF 的行为BindingUpdateSourceTrigger=PropertyChanged而 Silverlight 中缺少这种行为。那么会发生什么,每当您在文本框中输入内容时,TextInViewModel属性都会得到更新。此属性不必是DependencyProperty,它可能只是一个普通的 CLR 属性。

于 2010-05-02T10:53:56.807 回答
1

我有一个类似的问题,发现数据绑定操作在 TextBox 失去焦点之前并不总是触发。然而,指挥部将立即开火。

如果要保证在使用值之前已经发生数据绑定,可以调用BindingExpression.UpdateSource()控件上的方法。尝试这样的事情:

var bindTarget = SearchTextBox.GetBindingExpression(TextBox.TextProperty);
bindTarget.UpdateSource();

为避免直接在 ViewModel 中引用 TextBox(就像使用 MVVM 一样),您可以使用FocusManager.GetFocusedElement(). 这在处理 ApplicationBar 按钮时特别有用,因为它们在使用时似乎没有获得焦点。

于 2011-12-09T23:38:16.560 回答
1

这可以通过 RelayCommand 的参数与 TextBox 一起使用。爱荷华州 -RelayCommand<TextBox>

    <TextBox Height="72" HorizontalAlignment="Left" Margin="8,136,0,0" Name="txtFilter" Text="" VerticalAlignment="Top" Width="460" >
        <interactivity:Interaction.Triggers>
            <interactivity:EventTrigger EventName="TextChanged">
                <cmd:EventToCommand Command="{Binding SearchedTextChanged}" CommandParameter="{Binding ElementName=txtFilter}" />
            </interactivity:EventTrigger>
        </interactivity:Interaction.Triggers>
    </TextBox>

public RelayCommand<TextBox> SearchedTextChanged { get; set; }

SearchedTextChanged = new RelayCommand<TextBox>(OnSearchedTextChanged);

private void OnSearchedTextChanged(TextBox val)
    {
        if (val != null)
        {
            System.Diagnostics.Debug.WriteLine(val.Text);
        }
    }
于 2010-11-15T13:35:07.477 回答
0

我起诉的一些代码(类似于你的命令示例):

命令声明:

    public RelayCommand<string> TextChanged {get; private set;}

命令初始化:

TextChanged = new RelayCommand<string>((s) => MessageBox.Show(s));

命令绑定:

<TextBox x:Name="SearchTextBox" Margin="10,0" TextWrapping="Wrap" Text="{Binding SearchString, Mode=TwoWay}" FontStyle="Italic" TextChanged="SearchTextBox_TextChanged" >
<i:Interaction.Triggers>
    <i:EventTrigger EventName="TextChanged">
        <GalaSoft_MvvmLight_Command:EventToCommand Command="{Binding TextChanged, Mode=OneWay}" CommandParameter="{Binding Text, ElementName=SearchTextBox}"/>
    </i:EventTrigger>
</i:Interaction.Triggers>

由于某些原因,消息框会显示一个带有一个字符延迟的字符串。

于 2010-05-03T09:07:20.033 回答