Здійснюєте прив’язку WPF TextBox до кожного нового персонажа?


84

Як я можу зробити оновлення прив'язки даних, як тільки в текстовій коробці буде введено новий символ?

Я дізнаюся про прив'язки в WPF, і зараз я застряг у (сподіваюся) простому питанні.

У мене є простий клас 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));
        }
    }
}

Я використовую 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 на коробці?

Відповіді:


145

У прив'язці вашого текстового поля потрібно лише встановити UpdateSourceTrigger=PropertyChanged.


1
Дякую! Точно таке просте рішення, на яке я сподівався :)
luddet

Для мене це не спрацювало ... Я хочу повернути тексту попереднє значення, якщо це не число. Тільки при додаванні IsAsync = True це спрацювало.
ilans

Я спробував встановити це у дизайнері Visual Studio (VS2015). У діалоговому вікні прив'язки опція відображається, коли я розгортаю розширювач "Додаткові налаштування". Однак UpdateSourceTrigger вимкнено, якщо я також не встановив BindingDirection щось інше, ніж Default.
Мартін Браун,

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 # цього достатньо в XAML для TextBox, а не для класу. Отже, моніторинг властивості TextBlock, де пишеться довжина TextBox: 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.