2012-05-16 7 views
50

TextBoxに新しい文字が入力されるとすぐにデータバインディングを更新できますか?

私はWPFのバインディングについて学んでいますが、今は(うまくいけば)簡単なことに固執してしまいました。新しい文字ごとにWPF TextBoxバインディングを作成しますか?

私は単純なFileListerクラスを持ち、Pathプロパティを設定することができます。次にFileNamesプロパティにアクセスするとファイルのリストが表示されます。

class FileLister:INotifyPropertyChanged { 
    private string _path = ""; 

    public string Path { 
     get { 
      return _path; 
     } 
     set { 
      if (_path.Equals(value)) return; 
      _path = value; 
      OnPropertyChanged("Path"); 
      OnPropertyChanged("FileNames"); 
     } 
    } 

    public List<String> FileNames { 
     get { 
      return getListing(Path); 
     } 
    } 

    private List<string> getListing(string path) { 
     DirectoryInfo dir = new DirectoryInfo(path); 
     List<string> result = new List<string>(); 
     if (!dir.Exists) return result; 
     foreach (FileInfo fi in dir.GetFiles()) { 
      result.Add(fi.Name); 
     } 
     return result; 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    protected void OnPropertyChanged(string property) { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) { 
      handler(this, new PropertyChangedEventArgs(property)); 
     } 
    } 
} 

私はこの非常にシンプルなアプリにStaticResourceとしてFileListerを使用しています:結合取り組んでいる

<Window x:Class="WpfTest4.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:WpfTest4" 
    Title="MainWindow" Height="350" Width="525"> 
    <Window.Resources> 
     <local:FileLister x:Key="fileLister" Path="d:\temp" /> 
    </Window.Resources> 
    <Grid> 
     <TextBox Text="{Binding Source={StaticResource fileLister}, Path=Path, Mode=TwoWay}" 
     Height="25" Margin="12,12,12,0" VerticalAlignment="Top" /> 
     <ListBox Margin="12,43,12,12" Name="listBox1" ItemsSource="{Binding Source={StaticResource ResourceKey=fileLister}, Path=FileNames}"/> 
    </Grid> 
</Window> 

は、ここでそのクラスです。テキストボックス内の値を変更して、その外をクリックすると、リストボックスの内容が更新されます(パスが存在する限り)。

問題は、新しい文字が入力されると直ちに更新し、テキストボックスがフォーカスを失うまで待つのではないということです。

どうすればいいですか? これをxamlで直接行う方法はありますか、またはボックスのTextChangedまたはTextInputイベントを処理する必要はありますか?

答えて

84

UpdateSourceTriggerプロパティを設定する必要があります。

+1

ありがとう!まさに私が望んでいたような簡単な解決策でした:) – luddet

+0

私にとってはうまくいかなかった...数字ではない場合に備えて、テキストを元の値に戻したい。 IsAsync = Trueを追加した場合のみ、それは機能しました。 – ilans

20

あなたは、あなたがしなければならないすべてはUpdateSourceTrigger=PropertyChangedに設定されている、結合あなたのテキストボックスにPropertyChanged

<TextBox Text="{Binding Source={StaticResource fileLister}, Path=Path, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
    Height="25" Margin="12,12,12,0" VerticalAlignment="Top" /> 
0

突然、スライダーと関連するTextBoxの間のデータバインディングが問題を引き起こしました。 最後に私はその理由を見つけ出し、修正することができました。私が使用 コンバータ:XAML

<Window.Resources> 
    <local:ToOneDecimalConverter x:Key="ToOneDecimalConverter"/> 
</Window.Resources> 

using System; 
using System.Globalization; 
using System.Windows.Data; 
using System.Threading; 

namespace SiderExampleVerticalV2 
{ 
    internal class FixCulture 
    { 
     internal static System.Globalization.NumberFormatInfo currcult 
       = Thread.CurrentThread.CurrentCulture.NumberFormat; 

     internal static NumberFormatInfo nfi = new NumberFormatInfo() 
     { 
      /*because manual edit properties are not treated right*/ 
      NumberDecimalDigits = 1, 
      NumberDecimalSeparator = currcult.NumberDecimalSeparator, 
      NumberGroupSeparator = currcult.NumberGroupSeparator 
     }; 
    } 

    public class ToOneDecimalConverter : IValueConverter 
    { 
     public object Convert(object value, 
      Type targetType, object parameter, CultureInfo culture) 
     { 
      double w = (double)value; 
      double r = Math.Round(w, 1); 
      string s = r.ToString("N", FixCulture.nfi); 
      return (s as String); 
     } 

     public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      string s = (string)value; 
      double w; 
      try 
      { 
       w = System.Convert.ToDouble(s, FixCulture.currcult); 
      } 
      catch 
      { 
       return null; 
      } 
      return w; 
     } 
    } 
} 

さらに定義されたテキストボックス

<TextBox x:Name="TextSlidVolume" 
    Text="{Binding ElementName=SlidVolume, Path=Value, 
     Converter={StaticResource ToOneDecimalConverter},Mode=TwoWay}" 
/> 
関連する問題