각각의 새 문자에서 WPF TextBox 바인딩을 실행합니까?


86

새 문자가 TextBox에 입력되는 즉시 데이터 바인딩 업데이트를 만들려면 어떻게해야합니까?

나는 WPF의 바인딩에 대해 배우고 있으며 이제 (희망적으로) 간단한 문제에 갇혀 있습니다.

Path 속성을 설정할 수있는 간단한 FileLister 클래스가 있으며 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));
        }
    }
}

이 매우 간단한 앱에서 FileLister를 StaticResource로 사용하고 있습니다.

<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 이벤트를 처리해야합니까?

답변:


147

텍스트 상자 바인딩에서해야 할 일은 설정하는 것뿐입니다 UpdateSourceTrigger=PropertyChanged.


1
감사! 내가 기대했던 것만 큼의 간단한 해결책 :)
luddet

나를 위해 그것은 작동하지 않았다 ... 나는 숫자가 아닌 경우 텍스트를 이전 값으로 되돌리고 싶습니다. IsAsync = True를 추가했을 때만 작동했습니다.
ilans

Visual Studio 디자이너 (VS2015)에서 설정을 시도했습니다. 바인딩 대화 상자에서 '추가 설정'확장기를 확장하면 옵션이 표시됩니다. 그러나 BindingDirection을 Default가 아닌 다른 것으로 설정하지 않으면 UpdateSourceTrigger가 비활성화됩니다.
Martin Brown

32

UpdateSourceTrigger속성을 다음과 같이 설정해야 합니다.PropertyChanged

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

-1

C #이 없으면 클래스가 아닌 TextBox 용 XAML로 충분합니다. 따라서 TextBox의 길이를 쓰는 TextBlock의 속성을 모니터링합니다. Binding Text.Length

<StackPanel>
  <TextBox x:Name="textbox_myText" Text="123" />
  <TextBlock x:Name="tblok_result" Text="{Binding Text.Length, ElementName=textbox_myText}"/>
</StackPanel>

-2

갑자기 슬라이더와 관련 TextBox 간의 데이터 바인딩이 문제를 일으켰습니다. 마침내 그 이유를 찾아서 고칠 수있었습니다. 내가 사용하는 변환기 :

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;
        }
    }
}

XAML에서

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

추가로 정의 된 TextBox

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

2
잘못된 질문에 답변을 올린 것 같습니다. 원래 질문에는 슬라이더에 대한 정보가 포함되어 있지 않습니다.
GrantByrne
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.