2012-06-27 13 views
15

मैं TextBoxdoubleUpdateSourceTrigger=PropertyChanged के साथ कुछ ऑब्जेक्ट की संपत्ति को बांधने की कोशिश कर रहा हूं। लक्ष्य स्वीकार्य सीमा में होने के लिए मान्य प्रवेश मूल्य के संपादन के दौरान तुरंत है (और यदि कोई त्रुटि नहीं है)। मैं मॉडल स्तर पर सत्यापन लागू करना चाहता हूं, यानी IDataErrorInfo के माध्यम से।सत्यापन के साथ डबल फ़ील्ड को बाध्यकारी

जब मैं int संपत्ति से जुड़ता हूं तो सभी महान काम करते हैं, लेकिन अगर संपत्ति दोगुना हो तो निराशाजनक संपादन व्यवहार प्रकट होता है: संख्या के आंशिक भाग में अंतिम महत्वपूर्ण अंक को मिटाने के बाद - दशमलव विभाजक स्वचालित रूप से मिटा दिया जाता है (सभी संभावित fractional शून्यों के साथ) । उदाहरण के लिए, '12 .03 'संख्या से अंक' 3 'को मिटाने के बाद पाठ को '12 .0' के बजाय '12' में बदल दिया गया है।

कृपया, सहायता करें।

MainWindow.xaml:

<Window x:Class="BindWithValidation.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="80" Width="200" WindowStartupLocation="CenterOwner"> 

    <StackPanel> 
    <TextBox Width="100" Margin="10" Text="{Binding DoubleField, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"> 
     <TextBox.Style> 
     <Style TargetType="TextBox"> 
      <Style.Triggers> 
      <Trigger Property="Validation.HasError" Value="true"> 
       <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/> 
      </Trigger> 
      </Style.Triggers> 
     </Style> 
     </TextBox.Style> 
    </TextBox> 
    </StackPanel> 
</Window> 

MainWindow.xaml.cs:

namespace BindWithValidation 
{ 
    public partial class MainWindow : Window 
    { 
    private UISimpleData _uiData = new UISimpleData(); 

    public MainWindow() 
    { 
     InitializeComponent(); 
     DataContext = _uiData; 
    } 
    } 
} 

UISimpleData.cs:

namespace BindWithValidation 
{ 
    public class UISimpleData : INotifyPropertyChanged, IDataErrorInfo 
    { 
    private double _doubleField = 12.03; 

    public double DoubleField 
    { 
     get 
     { 
     return _doubleField; 
     } 
     set 
     { 
     if (_doubleField == value) 
      return; 

     _doubleField = value; 
     RaisePropertyChanged("DoubleField"); 
     } 
    } 

    public string this[string propertyName] 
    { 
     get 
     { 
     string validationResult = null; 
     switch (propertyName) 
     { 
      case "DoubleField": 
      { 
      if (DoubleField < 2 || DoubleField > 5) 
       validationResult = "DoubleField is out of range"; 
      break; 
      } 

      default: 
      throw new ApplicationException("Unknown Property being validated on UIData"); 
     } 

     return validationResult; 
     } 
    } 

    public string Error { get { return "not implemented"; } } 

    public event PropertyChangedEventHandler PropertyChanged; 

    protected void RaisePropertyChanged(string property) 
    { 
     if (PropertyChanged != null) 
     PropertyChanged(this, new PropertyChangedEventArgs(property)); 
    } 
    } 
} 
+0

मुझे लगता है कि यह फ़ॉर्मेटिंग के साथ करना है - क्योंकि 12 12.00 के बराबर है, क्या आपने बाध्यकारी पर स्ट्रिंगफॉर्मेट का उपयोग करने का प्रयास किया है? – Charleh

+0

हां, मैंने कोशिश की है, लेकिन यह पसंद नहीं है कि संपादन इसके साथ कैसे काम करता है। स्ट्रिंगफॉर्मेट प्रस्तुत करने के लिए अच्छा है, लेकिन संपादन के दौरान मैं इससे बचना चाहता हूं। – arudoy

उत्तर

1

कोशिश

यहाँ नमूना कोड है अपने द्विपक्षीय पर स्ट्रिंगफॉर्मेट का उपयोग करना nding:

<TextBox Width="100" Margin="10" Text="{Binding DoubleField, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, StringFormat='0.0'}"> 

सुनिश्चित नहीं हैं कि स्ट्रिंग प्रारूप भी सही है के बाद से मैं थोड़ी देर के लिए एक नहीं किया है, लेकिन यह सिर्फ एक उदाहरण

+0

आपके सुझाव के लिए धन्यवाद, लेकिन स्ट्रिंगफॉर्मैट सुविधाजनक नहीं है (ऊपर मेरी टिप्पणी देखें)। यदि वास्तव में, मैं टेक्स्टबॉक्स फोकस खोने के बाद स्ट्रिंगफॉर्मेट लागू करने जा रहा हूं, लेकिन जब यह फोकस करता है तो मैं स्ट्रिंगफॉर्मैट – arudoy

5

दशमलव स्थानों के साथ मूल्य स्वरूपण की कोशिश की है?

यह अजीब हो सकता है हालांकि आपके पास हमेशा एन दशमलव स्थान होंगे।

<TextBox.Text> 
    <Binding Path="DoubleField" StringFormat="{}{0:0.00}" UpdateSourceTrigger="PropertyChanged" ValidatesOnDataErrors="True"/> 
</TextBox.Text> 

तो तय दशमलव स्थानों के लिए होने पर्याप्त नहीं है, तो आप एक कनवर्टर है कि एक स्ट्रिंग के रूप में मूल्य व्यवहार करता है और इसे वापस धर्मान्तरित एक डबल करने के लिए लिखने के लिए हो सकता है।

+0

से बचना चाहता हूं हां, मैंने कोशिश की है। सक्षम स्ट्रिंगफॉर्मेट संपादन कार्यों के साथ भी बहुत अच्छा नहीं है। उदाहरण के लिए, '12 .00 'से डिलीट कुंजी के साथ दशमलव विभाजक को मिटाने वाले स्ट्रिंगफॉर्मैट के साथ' 12 'के बाद कर्सर के साथ' 1200.00 'होता है। इसलिए, पूरे आंशिक भाग को मिटाना असंभव है जो उपयोगकर्ता के लिए आश्चर्यजनक हो सकता है। – arudoy

+0

मैंने अपना स्वयं का कनवर्टर लिखने की भी कोशिश की है। स्ट्रिंग से डबल कामों में रूपांतरण ठीक है, लेकिन बैक रूपांतरण के साथ कोई समस्या है: कनवर्टर कैसे जान सकता है कि इसे दशमलव विभाजक को मूल्य 12 के स्ट्रिंग प्रस्तुति में डालना चाहिए? उपयोगकर्ता '12' या '12 'टाइप कर सकता है। या यहां तक ​​कि '12 .0 'और इन सभी में मूल्य 12 है जो कनवर्टर – arudoy

+0

को पास किया गया है, यही कारण है कि डिफ़ॉल्ट व्यवहार यह कर रहा है कि यह कैसे करता है। यह अनुमान लगाना मुश्किल होगा कि यूआई के पास "राज्य" नहीं होने पर दृश्यमान मूल्य क्या होना चाहिए - शायद एक कस्टम नियंत्रण काम कर सकता है:/ –

9

मुझे एहसास है कि मैं पार्टी के लिए थोड़ा देर हो चुकी हूं लेकिन मुझे इस समस्या के लिए एक साफ समाधान मिला है (मुझे लगता है)।

एक चालाक कनवर्टर जो अंतिम स्ट्रिंग को डबल में परिवर्तित करता है और लौटाता है कि अगर यह मौजूद है तो वह सब कुछ करना चाहिए जो आप चाहते हैं।

ध्यान दें कि जब उपयोगकर्ता टेक्स्टबॉक्स की सामग्री को बदलता है, तो कनवर्टबैक उपयोगकर्ता इनपुट स्ट्रिंग को स्टोर करेगा, स्ट्रिंग को डबल के लिए पार्स करेगा, और उस मान को व्यू मॉडल में पास करेगा। तुरंत बाद, कनवर्ट को नए बदले गए मूल्य को प्रदर्शित करने के लिए बुलाया जाता है। इस बिंदु पर, संग्रहीत स्ट्रिंग शून्य नहीं है और वापस आ जाएगी।

यदि उपयोगकर्ता के बजाय एप्लिकेशन को डबल बदलने के कारण केवल कनवर्ट कहा जाता है। इसका मतलब है कि कैश्ड स्ट्रिंग शून्य हो जाएगी और एक मानक ToString() को डबल पर बुलाया जाएगा।

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

public class DoubleToPersistantStringConverter : IValueConverter 
{ 
    private string lastConvertBackString; 

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     if (!(value is double)) return null; 

     var stringValue = lastConvertBackString ?? value.ToString(); 
     lastConvertBackString = null; 

     return stringValue; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     if (!(value is string)) return null; 

     double result; 
     if (double.TryParse((string)value, out result)) 
     { 
      lastConvertBackString = (string)value; 
      return result; 
     } 

     return null; 
    } 
} 
+0

यह एक अच्छा समाधान है। हालांकि, इस कनवर्टर का उपयोग करते हुए एक से अधिक टेक्स्टबॉक्स पर एक ही समय में NotifyProperty को कॉल करते समय यह गड़बड़ कर देगा। मैं कनवर्टर के लिए पैरामीटर के रूप में संपत्ति को पास करने का सुझाव देता हूं और 'आखिरी कन्वर्टबैकस्ट्रिंग' को 'डिक्शनरी <स्ट्रिंग, स्ट्रिंग>' द्वारा बदलता हूं। इस तरह आप प्रत्येक संपत्ति के लिए अंतिम स्ट्रिंग याद कर सकते हैं। – Octan

2

मैं एक ही समस्या में पड़ गए हैं, और एक काफी सरल समाधान मिल गया है: "।" एक कस्टम validator, जो वापस नहीं करता है "वैध" जब पाठ में समाप्त होता है का उपयोग या "0":

double val = 0; 
string tmp = value.ToString(); 

if (tmp.EndsWith(",") || tmp.EndsWith("0") || tmp.EndsWith(".")) 
{ 
    return new ValidationResult(false, "Enter another digit, or delete the last one."); 
} 
else 
{ 
    return ValidationResult.ValidResult; 
} 
+0

मुझे लगता है कि अगर मैं 100 –

+0

सत्य टाइप करता हूं तो यह त्रुटि दिखाएगा। एक '' tmp.Contains (',') || जोड़ें tmp.Contains ('।') '' 'से बचने के लिए' 'EndsWith ("।")' 'से बचने के लिए। – Digifaktur

3

समस्या यह है कि आप मूल्य परिवर्तन में हर बार अपनी संपत्ति अपडेट कर रहे हैं। जब आप 12.0 करने के लिए 12.03 बदल यह इस

<TextBox Width="100" Margin="10" Text="{Binding DoubleField, UpdateSourceTrigger=PropertyChanged,Delay=500, ValidatesOnDataErrors=True}"> 

लेकिन delay तरह xaml में TextBox बदलकर delay उपलब्ध कराने को सूचित करें और देरी समय के बाद संपत्ति सेट हो जाएगा द्वारा 12.

आप परिवर्तन देख सकते हैं करने के लिए गोल है मिली सेक में। बेहतर उपयोग StringFormat इस

<TextBox Width="100" Margin="10" Text="{Binding DoubleField, UpdateSourceTrigger=PropertyChanged,StringFormat=N2, ValidatesOnDataErrors=True}"> 
5

एक पाठ बॉक्स के लिए नाव मूल्यों बंधन के व्यवहार की तरह 4.5 .NET 4 से बदल दिया गया है। .NET 4.5 के साथ डिफ़ॉल्ट रूप से 'UpdateSourceTrigger = PropertyChanged' के साथ विभाजक वर्ण (कॉमा या डॉट) दर्ज करना अब संभव नहीं है।

माइक्रोसॉफ्ट का कहना है, यह (है) का इरादा

आप अभी भी 'UpdateSourceTrigger = PropertyChanged' निम्न का उपयोग करने के जोड़कर, आप अपने .NET 4.5 आवेदन में नेट 4 व्यवहार के लिए मजबूर कर सकते हैं अपने App.xaml.cs के निर्माता के लिए कोड की पंक्ति:

public App() 
{ 
    System.Windows.FrameworkCompatibilityPreferences 
       .KeepTextBoxDisplaySynchronizedWithTextProperty = false; 
} 

(सेबस्टियन लक्स - here से शब्दशः कॉपी किया गया)

संबंधित मुद्दे