【问题标题】:Windows 8/RT/Store TextBox - update text binding after each key strokeWindows 8/RT/Store TextBox - 每次击键后更新文本绑定
【发布时间】:2012-08-31 13:06:15
【问题描述】:

有没有办法在每次击键后更新文本绑定?

我的 WPF 自定义文本框使用 KeyUp 事件

private void MyTextBox_KeyUp(object sender, System.Windows.Input.KeyEventArgs e)
{
    BindingExpression BE = GetBindingExpression(TextBox.TextProperty);
    if (BE != null)
        BE.UpdateSource();
}

BindingExpressionWindows 8/RT/Store 中不存在。

【问题讨论】:

  • 下面有一些很好的答案。请将其中一个标记为您接受的解决方案。

标签: wpf data-binding mvvm windows-store-apps


【解决方案1】:

我知道这个问题有点老了,但是我今天遇到了这个问题并找到了一个非常简单的解决方案。 也许它可以帮助某人:

<TextBox Text="{Binding BindingSource, UpdateSourceTrigger=PropertyChanged}"/>

将 UpdateSourceTrigger-Property 设置为“PropertyChanged”,每次文本更改时都会调用 UpdateSource()-方法(即使焦点没有丢失)。

【讨论】:

  • 这仅适用于 Windows 8.1。最初的问题是针对 Windows 8 发布的,缺少 UpdateSourceTriggerGetBindingExpression API 被认为是一个(可怕的)错误并已修复。实际上,截至 2014 年,这是最好/正确的答案,即转换为 8.1。
  • 哦,不知道这仅适用于 Win 8.1 - 感谢您提供更多信息。
【解决方案2】:

那么,您确定文本已正确绑定吗?确保您绑定的对象继承了 INotifyPropertyChanged 接口,并且您正在调用 NotifyProperty() 事件的公共字符串属性。

因此,如果您已正确绑定所有内容,则只需设置 TextBox 文本,XAML 将自动更新该值。

这里是数据绑定教程:http://msdn.microsoft.com/en-us/library/ms752347.aspx

【讨论】:

  • 当然绑定正确。我只希望在每次更改/击键后更新(并采取行动)VM 中的绑定属性,而不必等到 TextBox 失去焦点。正如我所说,这是 WPF 中相对简单的任务,但 Windows 8 缺少这么多功能。
  • 那么只需在 TextChanged 事件上设置文本?
  • 如果我想在事件处理程序后面编写无穷无尽的代码,我就不会使用 MVVM ...
  • 无尽的代码?它实际上是 1 行:TextBox.TextChanged +=(o,e)=>{text = TextBox.Text;}
【解决方案3】:

您应该使用TextChanged 而不是KeyUpKeyDown

How to immediately update the source of a TextBox in WinRT with C#

【讨论】:

    【解决方案4】:

    有办法使用附加属性来解决您的问题。查看How To Make TextBox.Text Work 文章。

    【讨论】:

      【解决方案5】:

      我可以建议您一种完成此任务的方法,这在其他版本的 Silverlight 上会更容易(WPF 和 Windows Phone在 primis)... p>

      如您所见,Windows RT/Store 应用程序没有BindingExpression!...

      实现此代码,与您兼容MVVM 模式...

      using System;
      using Windows.UI.Xaml;
      using Windows.UI.Xaml.Controls;
      
      namespace YourProject
      {
          public static class TextBoxEx
          {
              public static string GetRealTimeText(TextBox obj)
              {
                  return (string)obj.GetValue(RealTimeTextProperty);
              }
      
              public static void SetRealTimeText(TextBox obj, string value)
              {
                  obj.SetValue(RealTimeTextProperty, value);
              }
      
              public static readonly DependencyProperty RealTimeTextProperty = DependencyProperty.RegisterAttached("RealTimeText", typeof(string), typeof(TextBoxEx), null);
      
              public static bool GetIsAutoUpdate(TextBox obj)
              {
                  return (bool)obj.GetValue(IsAutoUpdateProperty);
              }
      
              public static void SetIsAutoUpdate(TextBox obj, bool value)
              {
                  obj.SetValue(IsAutoUpdateProperty, value);
              }
      
              public static readonly DependencyProperty IsAutoUpdateProperty =
                  DependencyProperty.RegisterAttached("IsAutoUpdate", typeof(bool), typeof(TextBoxEx), new PropertyMetadata(false, OnIsAutoUpdateChanged));
      
              private static void OnIsAutoUpdateChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
              {
                  var textbox = (TextBox)sender;
      
                  if ((bool)e.NewValue)
                      textbox.TextChanged += textbox_TextChanged;
                  else
                      textbox.TextChanged -= textbox_TextChanged;
              }
      
              private static void textbox_TextChanged(object sender, TextChangedEventArgs e)
              {
                  var textbox = (TextBox)sender;
      
                  textbox.SetValue(TextBoxEx.RealTimeTextProperty, textbox.Text);
              }
          }
      }
      

      ...然后只需在您的 XAML 中使用它,有一个小技巧(双重绑定),如下所示...

      1) 声明新的“实用程序”类:

      <common:LayoutAwarePage x:Name="pageRoot"
          x:Class="YourProject.YourPage"
          DataContext="{Binding Path=DefaultViewModel, RelativeSource={RelativeSource Self}}"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
          xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
          xmlns:local="YourProject"
          ...
          xmlns:extra="using:YourProject.YourNameSpace"
          mc:Ignorable="d">
      

      2) 在您的控件中实现:

      <TextBox extra:TextBoxEx.IsAutoUpdate="True"
               extra:TextBoxEx.RealTimeText="{Binding Path=YourTextProperty, Mode=TwoWay}">
          <TextBox.Text>
              <Binding Path="YourTextProperty"
                       Mode="OneWay" />
          </TextBox.Text>
      </TextBox>
      

      这对我来说很好,我希望可以帮助你!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-18
        • 1970-01-01
        • 2022-01-19
        • 1970-01-01
        相关资源
        最近更新 更多