प्रत्येक नए चरित्र पर एक WPF TextBox बाध्यकारी आग बनाना?


85

जैसे ही टेक्स्टबॉक्स में एक नया चरित्र टाइप किया जाता है, मैं डेटा बाइंडिंग अपडेट कैसे कर सकता हूं?

मैं WPF में बाइंडिंग के बारे में सीख रहा हूं और अब मैं एक (उम्मीद) सरल मामले पर अटक गया हूं।

मेरे पास एक साधारण फाइललिस्टर क्लास है जहाँ आप एक पथ संपत्ति सेट कर सकते हैं, और तब यह आपको फाइलों की एक सूची देगा जब आप फ़ाइलनाम संपत्ति का उपयोग करते हैं। यहाँ वह वर्ग है:

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 घटनाओं को संभालना है?

जवाबों:


146

अपने टेक्स्टबॉक्स बाइंडिंग में, आपको बस इतना करना है UpdateSourceTrigger=PropertyChanged


1
धन्यवाद! बिल्कुल सरल समाधान के रूप में मैं के लिए उम्मीद कर रहा था :)
luddet

मेरे लिए यह काम नहीं किया ... मैं पाठ को उसके पिछले मूल्य पर वापस लाना चाहता हूं, अगर यह संख्या नहीं है। केवल जब IsAsync जोड़ा गया है = यह सही है काम किया।
इलंस

मैंने इसे विजुअल स्टूडियो डिजाइनर (VS2015) में स्थापित करने की कोशिश की। बाइंडिंग डायलॉग में विकल्प दिखाई देता है जब मैं 'अधिक सेटिंग्स' का विस्तार करता हूं। हालाँकि, UpdateSourceTrigger अक्षम है जब तक कि मैं डिफ़ॉल्ट के अलावा किसी अन्य चीज़ के लिए BindingDirection सेट नहीं करता।
मार्टिन ब्राउन

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 में पर्याप्त है, क्लास के लिए नहीं। तो, टेक्स्टब्लॉक की संपत्ति की निगरानी करना, जहां टेक्स्टबॉक्स की लंबाई लिखना: बाइंडिंग टेक्स्ट.लिफ्ट

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

-2

अचानक स्लाइडर और संबंधित टेक्स्टबॉक्स के बीच डेटा बाइंडिंग ने परेशानी खड़ी कर दी। आखिरकार मुझे इसका कारण मिल गया और मैं इसे ठीक कर सकता था। मैं जिस कन्वर्टर का उपयोग करता हूं:

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 x:Name="TextSlidVolume"
    Text="{Binding ElementName=SlidVolume, Path=Value,
        Converter={StaticResource ToOneDecimalConverter},Mode=TwoWay}"
/>

2
मुझे लगता है कि आपने गलत सवाल में अपना जवाब पोस्ट किया है। मूल प्रश्न में स्लाइडर के बारे में कोई जानकारी शामिल नहीं है।
ग्रांटबेयर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.