2011-01-28 11 views
34

के लिए समतुल्य है क्या बाध्यकारी को अपडेट करने के लिए विंडोज फोन 7 में टेक्स्टबॉक्स प्राप्त करने का कोई तरीका है क्योंकि उपयोगकर्ता फोकस खोने के बजाए प्रत्येक अक्षर टाइप करता है?"अपडेटसोर्स ट्रिगर = प्रॉपर्टी चेंज" विंडोज फोन 7 टेक्स्टबॉक्स

निम्नलिखित WPF पाठ बॉक्स की तरह करना होगा:

<TextBox Text="{Binding Path=TextProperty, UpdateSourceTrigger=PropertyChanged}"/> 
+1

+1:

Public Class TextBoxUpdate : Inherits TextBox Private Sub OnTextBoxTextChanged(sender As Object, e As TextChangedEventArgs) Handles Me.TextChanged Dim senderText As TextBox = DirectCast(sender, TextBox) Dim bindingExp As BindingExpression = senderText.GetBindingExpression(TextBox.TextProperty) bindingExp.UpdateSource() End Sub End Class 

फिर XAML में इस तरह फोन एफ सबसे आम WP समस्याएं –

+0

और अभी भी WP8 में गायब हैं :( – Jedidja

उत्तर

51

WP7 के लिए सिल्वरलाइट आपके द्वारा सूचीबद्ध वाक्यविन्यास का समर्थन नहीं करता है। निम्नलिखित के बजाय कार्य करें:

<TextBox TextChanged="OnTextBoxTextChanged" 
     Text="{Binding MyText, Mode=TwoWay, 
       UpdateSourceTrigger=Explicit}" /> 

UpdateSourceTrigger = Explicit यहाँ एक स्मार्ट बोनस है। यह क्या है?Explicit: केवल UpdateSource विधि को कॉल करते समय बाध्यकारी स्रोत अपडेट करें। जब उपयोगकर्ता TextBox छोड़ देता है तो यह आपको एक अतिरिक्त बाध्यकारी सेट बचाता है।

सी # में:

private void OnTextBoxTextChanged(object sender, TextChangedEventArgs e) 
{ 
    TextBox textBox = sender as TextBox; 
    // Update the binding source 
    BindingExpression bindingExpr = textBox.GetBindingExpression(TextBox.TextProperty); 
    bindingExpr.UpdateSource(); 
} 
+0

उपरोक्त "बाध्यकारी एक्सप्रेशन" कोड का उपयोग करके बाध्यकारी से संबंधित "एक विशिष्ट" समस्या हल हो गई है। मेरे कोड को खुश करने के लिए धन्यवाद के टन। – Jsinh

5

के माध्यम से नहीं बाध्यकारी वाक्य रचना, नहीं, लेकिन इसके बिना पर्याप्त आसान है। आपको टेक्स्ट चेंज किए गए ईवेंट को संभालना होगा और बाध्यकारी पर UpdateSource पर कॉल करना होगा।

private void TextBox_TextChanged(object sender, TextChangedEventArgs e) 
{ 
    ((TextBox) sender).GetBindingExpression(TextBox.TextProperty).UpdateSource(); 
} 

यह सुंदर भी आसानी से एक attached behavior में बदला जा सकता।

1

टेक्स्ट चेंज किए गए ईवेंट कॉल UpdateSource() में।

BindingExpression be = itemNameTextBox.GetBindingExpression(TextBox.TextProperty); 
be.UpdateSource(); 
23

मैं एक संलग्न संपत्ति का उपयोग कर पसंद है। बस अगर आप उन छोटे buggers में हैं।

<toolkit:DataField Label="Name"> 
    <TextBox Text="{Binding Product.Name, Mode=TwoWay}" c:BindingUtility.UpdateSourceOnChange="True"/> 
</toolkit:DataField> 

और फिर बैकिंग कोड।

public class BindingUtility 
{ 
public static bool GetUpdateSourceOnChange(DependencyObject d) 
{ 
    return (bool)d.GetValue(UpdateSourceOnChangeProperty); 
} 

public static void SetUpdateSourceOnChange(DependencyObject d, bool value) 
{ 
    d.SetValue(UpdateSourceOnChangeProperty, value); 
} 

// Using a DependencyProperty as the backing store for … 
public static readonly DependencyProperty 
    UpdateSourceOnChangeProperty = 
    DependencyProperty.RegisterAttached(
    "UpdateSourceOnChange", 
    typeof(bool), 
       typeof(BindingUtility), 
    new PropertyMetadata(false, OnPropertyChanged)); 

private static void OnPropertyChanged (DependencyObject d, 
    DependencyPropertyChangedEventArgs e) 
{ 
    var textBox = d as TextBox; 
    if (textBox == null) 
    return; 
    if ((bool)e.NewValue) 
    { 
    textBox.TextChanged += OnTextChanged; 
    } 
    else 
    { 
    textBox.TextChanged -= OnTextChanged; 
    } 
} 
static void OnTextChanged(object s, TextChangedEventArgs e) 
{ 
    var textBox = s as TextBox; 
    if (textBox == null) 
    return; 

    var bindingExpression = textBox.GetBindingExpression(TextBox.TextProperty); 
    if (bindingExpression != null) 
    { 
    bindingExpression.UpdateSource(); 
    } 
} 
} 
+1

इस तकनीक का उपयोग करके सावधान रहें, यह मेमोरी लीक पेश कर सकता है क्योंकि इवेंट हैंडलर को कभी अपंजीकृत नहीं किया जाता है। http://sharpfellows.com/post/Memory-Leaks-and- निर्भरता-Properties.aspx –

+0

@FlatlinerDOA: इस मामले में स्मृति रिसाव का कोई जोखिम नहीं है क्योंकि संदर्भ गैर स्थैतिक वस्तु (टेक्स्टबॉक्स) से है स्थैतिक घटना हैंडलर (बाइंडिंगउटिलिटी.ऑनटेक्स्ट चेंज)। समस्या तब होती जब संदर्भ दूसरी तरफ था। –

+0

@Parrhesia जो, मैं अपने टूलकिट पाठ बॉक्स में से अधिकांश में व्यवहार संलग्न किया है, एक पाठ बॉक्स में मैं 'का इस्तेमाल किया है <टूलकिट: PhoneTextBox सुझाव =" पिछले 10 डिजिट कार्ड नंबर " \t \t \t \t Grid.Row =" 0 " InputScope = "संख्या" MaxLength = "10" \t \t \t \t DisplayedMaxLength = "10" पाठ = "{CardNumber बाइंडिंग, मोड = TwoWay}" ActionIcon = "/ आस्तियों/Help.png" सहायकों: BindingUtility .UpdateSourceOnChange = "True" KeyDown = "PhoneTextBox_KeyDown" /> 'इसमें कुछ समस्याएं हैं, ऐसा लगता है जैसे कर्सर पहले आइटम पर जाता है जब मैं 0 दबाता हूं – Eldho

0

UpdateSourceTrigger = मेरे लिए स्पष्ट does not काम है, इसलिए पाठ बॉक्स

public class TextBoxEx : TextBox 
{ 
    public TextBoxEx() 
    { 
     TextChanged += (sender, args) => 
          { 
           var bindingExpression = GetBindingExpression(TextProperty); 
           if (bindingExpression != null) 
           { 
            bindingExpression.UpdateSource(); 
           } 
          }; 
    } 

} 
0

से derivated कस्टम वर्ग का उपयोग कर इम यह कोड की केवल एक पंक्ति है!

(sender as TextBox).GetBindingExpression(TextBox.TextProperty).UpdateSource(); 

आप अपने पृष्ठ का पीछे कोड में एक सामान्य TextChanged घटना (उदाहरण के लिए "ImmediateTextBox_TextChanged") बना सकते हैं और अधिक से पेज में किसी भी पाठ बॉक्स से लिंक करें।

1

आप TextChanged पर अद्यतन को संभालने के लिए अपने स्वयं के पाठ बॉक्स व्यवहार लिख सकते हैं:

यह PasswordBox करने के लिए अपने नमूना है, लेकिन आप साधारण परिवर्तन यह किसी भी वस्तु के किसी भी संपत्ति को संभालने के लिए कर सकते हैं।

public class UpdateSourceOnPasswordChangedBehavior 
    : Behavior<PasswordBox> 
{ 
    protected override void OnAttached() 
    { 
     base.OnAttached(); 
     AssociatedObject.PasswordChanged += OnPasswordChanged; 
    } 

    protected override void OnDetaching() 
    { 
     base.OnDetaching(); 
     AssociatedObject.PasswordChanged -= OnPasswordChanged; 
    } 

    private void OnPasswordChanged(object sender, RoutedEventArgs e) 
    { 
     AssociatedObject.GetBindingExpression(PasswordBox.PasswordProperty).UpdateSource(); 
    } 
} 

Ussage:

<PasswordBox x:Name="Password" Password="{Binding Password, Mode=TwoWay}" > 
    <i:Interaction.Behaviors> 
     <common:UpdateSourceOnPasswordChangedBehavior/> 
    </i:Interaction.Behaviors> 
</PasswordBox> 
0

मैं Praetorian's answer लिया और एक विस्तार वर्ग विरासत कि TextBox तो आप इस व्यवहार के साथ पीछे अपने दृश्य के कोड को अव्यवस्था की जरूरत नहीं है बनाया है।

सी तीव्र:

public class TextBoxUpdate : TextBox 
{ 
    public TextBoxUpdate() 
    { 
     TextChanged += OnTextBoxTextChanged; 
    } 
    private void OnTextBoxTextChanged(object sender, TextChangedEventArgs e) 
    { 
     TextBox senderText = (TextBox)sender; 
     BindingExpression bindingExp = senderText.GetBindingExpression(TextBox.TextProperty); 
     bindingExp.UpdateSource(); 
    } 
} 

VisualBasic: एक ओ पूछने के लिए

<local:TextBoxUpdate Text="{Binding PersonName, Mode=TwoWay}"/> 
संबंधित मुद्दे